Merge pull request #252 from weclapp-dev/master

Add a document type and additional fields
This commit is contained in:
Jochen Staerk
2021-10-21 14:14:37 +02:00
committed by GitHub
11 changed files with 217 additions and 151 deletions

View File

@@ -46,13 +46,18 @@ public class Invoice implements IExportableTransaction {
protected Date detailedDeliveryDateStart = null; protected Date detailedDeliveryDateStart = null;
protected Date detailedDeliveryPeriodEnd = null; protected Date detailedDeliveryPeriodEnd = null;
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<IZUGFeRDAllowanceCharge>(), protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>(),
Charges = new ArrayList<IZUGFeRDAllowanceCharge>(), LogisticsServiceCharges = new ArrayList<IZUGFeRDAllowanceCharge>(); Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>();
protected IZUGFeRDPaymentTerms paymentTerms = null; protected IZUGFeRDPaymentTerms paymentTerms = null;
private Date invoiceReferencedIssueDate;
private String specifiedProcuringProjectID = null;
private String specifiedProcuringProjectName = null;
public Invoice() { public Invoice() {
ZFItems = new ArrayList<IZUGFeRDExportableItem>(); ZFItems = new ArrayList<>();
setCurrency("EUR"); setCurrency("EUR");
} }
@@ -246,6 +251,16 @@ public class Invoice implements IExportableTransaction {
return invoiceReferencedDocumentID; return invoiceReferencedDocumentID;
} }
@Override
public Date getInvoiceReferencedIssueDate() {
return invoiceReferencedIssueDate;
}
public Invoice setInvoiceReferencedIssueDate(Date issueDate) {
this.invoiceReferencedIssueDate = issueDate;
return this;
}
@Override @Override
public String getBuyerOrderReferencedDocumentIssueDateTime() { public String getBuyerOrderReferencedDocumentIssueDateTime() {
return buyerOrderReferencedDocumentIssueDateTime; return buyerOrderReferencedDocumentIssueDateTime;
@@ -637,4 +652,23 @@ public class Invoice implements IExportableTransaction {
return this; return this;
} }
@Override
public String getSpecifiedProcuringProjectID() {
return specifiedProcuringProjectID;
}
public Invoice setSpecifiedProcuringProjectID(String specifiedProcuringProjectID) {
this.specifiedProcuringProjectID = specifiedProcuringProjectID;
return this;
}
@Override
public String getSpecifiedProcuringProjectName() {
return specifiedProcuringProjectName;
}
public Invoice setSpecifiedProcuringProjectName(String specifiedProcuringProjectName) {
this.specifiedProcuringProjectName = specifiedProcuringProjectName;
return this;
}
} }

View File

@@ -416,7 +416,7 @@ public interface IExportableTransaction {
} }
/** /**
* get the ID of the prceding invoice, which is e.g. to be corrected if this is a correction * get the ID of the preceding invoice, which is e.g. to be corrected if this is a correction
* *
* @return the ID of the document * @return the ID of the document
*/ */
@@ -424,6 +424,7 @@ public interface IExportableTransaction {
return null; return null;
} }
default Date getInvoiceReferencedIssueDate(){return null;}
/** /**
* get the issue timestamp of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement * get the issue timestamp of the BuyerOrderReferencedDocument, which sits in the ApplicableSupplyChainTradeAgreement
* *
@@ -488,4 +489,12 @@ public interface IExportableTransaction {
default String[] getNotes() { default String[] getNotes() {
return null; return null;
} }
default String getSpecifiedProcuringProjectName(){
return null;
}
default String getSpecifiedProcuringProjectID(){
return null;
}
} }

View File

@@ -20,6 +20,7 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON;
import java.io.IOException; import java.io.IOException;
@@ -46,7 +47,6 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
protected byte[] zugferdData; protected byte[] zugferdData;
private String paymentTermsDescription; private String paymentTermsDescription;
SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
protected Profile profile = Profiles.getByName("COMFORT", 1); protected Profile profile = Profiles.getByName("COMFORT", 1);
@@ -169,8 +169,8 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
+ " <ram:ID>" + XMLTools.encodeXML(trans.getNumber()) + "</ram:ID>\n" + " <ram:ID>" + XMLTools.encodeXML(trans.getNumber()) + "</ram:ID>\n"
+ " <ram:Name>RECHNUNG</ram:Name>\n" + " <ram:Name>RECHNUNG</ram:Name>\n"
+ " <ram:TypeCode>" + typecode + "</ram:TypeCode>\n" + " <ram:TypeCode>" + typecode + "</ram:TypeCode>\n"
+ " <ram:IssueDateTime><udt:DateTimeString format=\"102\">" + " <ram:IssueDateTime>"
+ zugferdDateFormat.format(trans.getIssueDate()) + "</udt:DateTimeString></ram:IssueDateTime>\n" // date + DATE.udtFormat(trans.getIssueDate()) + "</ram:IssueDateTime>\n" // date
// format // format
// was // was
// 20130605 // 20130605
@@ -225,8 +225,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
+ " <ram:OccurrenceDateTime>"; + " <ram:OccurrenceDateTime>";
if (trans.getDeliveryDate() != null) { if (trans.getDeliveryDate() != null) {
xml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getDeliveryDate()) xml += DATE.udtFormat(trans.getDeliveryDate());
+ "</udt:DateTimeString>";
} else { } else {
throw new IllegalStateException("No delivery date provided"); throw new IllegalStateException("No delivery date provided");
} }
@@ -292,9 +291,9 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
} }
if (hasDueDate && (trans.getDueDate() != null)) { if (hasDueDate && (trans.getDueDate() != null)) {
xml = xml + " <ram:DueDateDateTime><udt:DateTimeString format=\"102\">" // $NON-NLS-2$ xml = xml + " <ram:DueDateDateTime>" // $NON-NLS-2$
+ zugferdDateFormat.format(trans.getDueDate()) + DATE.udtFormat(trans.getDueDate())
+ "</udt:DateTimeString></ram:DueDateDateTime>\n";// 20130704 + "</ram:DueDateDateTime>\n";// 20130704
} }
xml = xml + " </ram:SpecifiedTradePaymentTerms>\n"; xml = xml + " </ram:SpecifiedTradePaymentTerms>\n";
@@ -440,8 +439,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>"; paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>";
if (dueDate != null) { if (dueDate != null) {
paymentTermsXml += "<ram:DueDateDateTime>"; paymentTermsXml += "<ram:DueDateDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" paymentTermsXml += DATE.udtFormat(dueDate) ;
+ zugferdDateFormat.format(dueDate.getDate()) + "</udt:DateTimeString>";
paymentTermsXml += "</ram:DueDateDateTime>"; paymentTermsXml += "</ram:DueDateDateTime>";
} }
@@ -456,7 +454,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
if (discountTerms.getBaseDate() != null) { if (discountTerms.getBaseDate() != null) {
final Date baseDate = discountTerms.getBaseDate(); final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>"; paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>"; paymentTermsXml += DATE.udtFormat(baseDate) ;
paymentTermsXml += "</ram:BasisDateTime>"; paymentTermsXml += "</ram:BasisDateTime>";
paymentTermsXml += "<ram:BasisPeriodMeasure unitCode=\"" + discountTerms.getBasePeriodUnitCode() + "\">" paymentTermsXml += "<ram:BasisPeriodMeasure unitCode=\"" + discountTerms.getBasePeriodUnitCode() + "\">"

View File

@@ -20,6 +20,7 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE; import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE;
import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON;
@@ -44,8 +45,6 @@ import org.mustangproject.XMLTools;
public class ZUGFeRD2PullProvider implements IXMLProvider { public class ZUGFeRD2PullProvider implements IXMLProvider {
//// MAIN CLASS
protected SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
protected byte[] zugferdData; protected byte[] zugferdData;
protected IExportableTransaction trans; protected IExportableTransaction trans;
protected TransactionCalculator calc; protected TransactionCalculator calc;
@@ -278,7 +277,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
// xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100
// ../Schema/ZUGFeRD1p0.xsd\"" // ../Schema/ZUGFeRD1p0.xsd\""
+ " xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\"" + " xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\""
+ " xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\">\n" + " xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\""
+ " xmlns:qdt=\"urn:un:unece:uncefact:data:standard:QualifiedDataType:100\">\n"
+ " <rsm:ExchangedDocumentContext>\n" + " <rsm:ExchangedDocumentContext>\n"
// + " // + "
// <ram:TestIndicator><udt:Indicator>"+testBooleanStr+"</udt:Indicator></ram:TestIndicator>\n" // <ram:TestIndicator><udt:Indicator>"+testBooleanStr+"</udt:Indicator></ram:TestIndicator>\n"
@@ -292,8 +292,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
// + " <ram:Name>RECHNUNG</ram:Name>\n" // + " <ram:Name>RECHNUNG</ram:Name>\n"
// + " <ram:TypeCode>380</ram:TypeCode>\n" // + " <ram:TypeCode>380</ram:TypeCode>\n"
+ " <ram:TypeCode>" + typecode + "</ram:TypeCode>\n" + " <ram:TypeCode>" + typecode + "</ram:TypeCode>\n"
+ " <ram:IssueDateTime><udt:DateTimeString format=\"102\">" + " <ram:IssueDateTime>"
+ zugferdDateFormat.format(trans.getIssueDate()) + "</udt:DateTimeString></ram:IssueDateTime>\n" // date + DATE.udtFormat(trans.getIssueDate()) + "</ram:IssueDateTime>\n" // date
+ notes + notes
+ subjectNote + subjectNote
+ rebateAgreement + rebateAgreement
@@ -405,10 +405,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) {
xml = xml + "<ram:BillingSpecifiedPeriod>"; xml = xml + "<ram:BillingSpecifiedPeriod>";
if (currentItem.getDetailedDeliveryPeriodFrom() != null) { if (currentItem.getDetailedDeliveryPeriodFrom() != null) {
xml = xml + "<ram:StartDateTime><udt:DateTimeString format='102'>" + zugferdDateFormat.format(currentItem.getDetailedDeliveryPeriodFrom()) + "</udt:DateTimeString></ram:StartDateTime>"; xml = xml + "<ram:StartDateTime>" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + "</ram:StartDateTime>";
} }
if (currentItem.getDetailedDeliveryPeriodTo() != null) { if (currentItem.getDetailedDeliveryPeriodTo() != null) {
xml = xml + "<ram:EndDateTime><udt:DateTimeString format='102'>" + zugferdDateFormat.format(currentItem.getDetailedDeliveryPeriodTo()) + "</udt:DateTimeString></ram:EndDateTime>"; xml = xml + "<ram:EndDateTime>" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + "</ram:EndDateTime>";
} }
xml = xml + "</ram:BillingSpecifiedPeriod>"; xml = xml + "</ram:BillingSpecifiedPeriod>";
@@ -475,6 +475,15 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
} }
if (trans.getSpecifiedProcuringProjectID() != null) {
xml = xml + " <ram:SpecifiedProcuringProject>\n"
+ " <ram:ID>"
+ XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + "</ram:ID>\n";
if(trans.getSpecifiedProcuringProjectName()!= null) {
xml += " <ram:Name >" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + "</ram:Name>\n";
}
xml += " </ram:SpecifiedProcuringProject>\n";
}
xml = xml + " </ram:ApplicableHeaderTradeAgreement>\n" xml = xml + " </ram:ApplicableHeaderTradeAgreement>\n"
+ " <ram:ApplicableHeaderTradeDelivery>\n"; + " <ram:ApplicableHeaderTradeDelivery>\n";
if (this.trans.getDeliveryAddress() != null) { if (this.trans.getDeliveryAddress() != null) {
@@ -487,8 +496,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ " <ram:OccurrenceDateTime>"; + " <ram:OccurrenceDateTime>";
if (trans.getDeliveryDate() != null) { if (trans.getDeliveryDate() != null) {
xml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getDeliveryDate()) xml += DATE.udtFormat(trans.getDeliveryDate());
+ "</udt:DateTimeString>";
} else { } else {
throw new IllegalStateException("No delivery date provided"); throw new IllegalStateException("No delivery date provided");
} }
@@ -546,10 +554,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) { if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) {
xml = xml + "<ram:BillingSpecifiedPeriod>"; xml = xml + "<ram:BillingSpecifiedPeriod>";
if (trans.getDetailedDeliveryPeriodFrom() != null) { if (trans.getDetailedDeliveryPeriodFrom() != null) {
xml = xml + "<ram:StartDateTime><udt:DateTimeString format='102'>" + zugferdDateFormat.format(trans.getDetailedDeliveryPeriodFrom()) + "</udt:DateTimeString></ram:StartDateTime>"; xml = xml + "<ram:StartDateTime>" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + "</ram:StartDateTime>";
} }
if (trans.getDetailedDeliveryPeriodTo() != null) { if (trans.getDetailedDeliveryPeriodTo() != null) {
xml = xml + "<ram:EndDateTime><udt:DateTimeString format='102'>" + zugferdDateFormat.format(trans.getDetailedDeliveryPeriodTo()) + "</udt:DateTimeString></ram:EndDateTime>"; xml = xml + "<ram:EndDateTime>" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + "</ram:EndDateTime>";
} }
xml = xml + "</ram:BillingSpecifiedPeriod>"; xml = xml + "</ram:BillingSpecifiedPeriod>";
@@ -616,9 +624,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} }
if (hasDueDate && (trans.getDueDate() != null)) { if (hasDueDate && (trans.getDueDate() != null)) {
xml = xml + " <ram:DueDateDateTime><udt:DateTimeString format=\"102\">" // $NON-NLS-2$ xml = xml + " <ram:DueDateDateTime>" // $NON-NLS-2$
+ zugferdDateFormat.format(trans.getDueDate()) + DATE.udtFormat(trans.getDueDate())
+ "</udt:DateTimeString></ram:DueDateDateTime>\n";// 20130704 + "</ram:DueDateDateTime>\n";// 20130704
} }
xml = xml + " </ram:SpecifiedTradePaymentTerms>\n"; xml = xml + " </ram:SpecifiedTradePaymentTerms>\n";
@@ -649,8 +657,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if (trans.getInvoiceReferencedDocumentID() != null) { if (trans.getInvoiceReferencedDocumentID() != null) {
xml = xml + " <ram:InvoiceReferencedDocument>\n" xml = xml + " <ram:InvoiceReferencedDocument>\n"
+ " <ram:IssuerAssignedID>" + " <ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + "</ram:IssuerAssignedID>\n" + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + "</ram:IssuerAssignedID>\n";
+ " </ram:InvoiceReferencedDocument>\n"; if(trans.getInvoiceReferencedIssueDate()!= null){
xml += "<ram:FormattedIssueDateTime>"
+ DATE.qdtFormat(trans.getInvoiceReferencedIssueDate())
+ "</ram:FormattedIssueDateTime>\n";
}
xml += " </ram:InvoiceReferencedDocument>\n";
} }
xml = xml + " </ram:ApplicableHeaderTradeSettlement>\n"; xml = xml + " </ram:ApplicableHeaderTradeSettlement>\n";
@@ -698,8 +711,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>"; paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>";
if (dueDate != null) { if (dueDate != null) {
paymentTermsXml += "<ram:DueDateDateTime>"; paymentTermsXml += "<ram:DueDateDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" paymentTermsXml += DATE.udtFormat(dueDate) ;
+ zugferdDateFormat.format(dueDate) + "</udt:DateTimeString>";
paymentTermsXml += "</ram:DueDateDateTime>"; paymentTermsXml += "</ram:DueDateDateTime>";
} }
@@ -714,7 +726,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if (discountTerms.getBaseDate() != null) { if (discountTerms.getBaseDate() != null) {
final Date baseDate = discountTerms.getBaseDate(); final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>"; paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(baseDate) + "</udt:DateTimeString>"; paymentTermsXml += DATE.udtFormat(baseDate);
paymentTermsXml += "</ram:BasisDateTime>"; paymentTermsXml += "</ram:BasisDateTime>";
paymentTermsXml += "<ram:BasisPeriodMeasure unitCode=\"" + discountTerms.getBasePeriodUnitCode() + "\">" paymentTermsXml += "<ram:BasisPeriodMeasure unitCode=\"" + discountTerms.getBasePeriodUnitCode() + "\">"

View File

@@ -1,6 +1,7 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date;
import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants; import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants;
@@ -12,6 +13,8 @@ public enum ZUGFeRDDateFormat {
private String dateTimeType; private String dateTimeType;
private SimpleDateFormat formatter; private SimpleDateFormat formatter;
private static final String QDT_FORMAT = "<qdt:DateTimeString format=\"%s\">%s</qdt:DateTimeString>";
private static final String UDT_FORMAT = "<udt:DateTimeString format=\"%s\">%s</udt:DateTimeString>";
private ZUGFeRDDateFormat(String dateTimeType, SimpleDateFormat formatter) { private ZUGFeRDDateFormat(String dateTimeType, SimpleDateFormat formatter) {
this.dateTimeType = dateTimeType; this.dateTimeType = dateTimeType;
@@ -25,4 +28,14 @@ public enum ZUGFeRDDateFormat {
public SimpleDateFormat getFormatter() { public SimpleDateFormat getFormatter() {
return formatter; return formatter;
} }
public String simpleFormat(Date date){
return getFormatter().format(date);
}
public String qdtFormat(Date date){
return String.format(QDT_FORMAT, getDateTimeType(), getFormatter().format(date));
}
public String udtFormat(Date date){
return String.format(UDT_FORMAT, getDateTimeType(), getFormatter().format(date));
}
} }

View File

@@ -23,4 +23,5 @@ public class DocumentCodeTypeConstants {
public static final String CREDITNOTE = "381"; public static final String CREDITNOTE = "381";
public static final String DEBITNOTE = "84"; public static final String DEBITNOTE = "84";
public static final String CORRECTEDINVOICE = "384"; public static final String CORRECTEDINVOICE = "384";
public static final String PARTIAL_BILLING = "326";
} }

View File

@@ -21,32 +21,32 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.CII.CIIToUBL;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.CII.CIIToUBL;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class UBLTest extends ResourceCase { public class UBLTest extends ResourceCase {
public void testUBLBasic() { public void testUBLBasic() {
// the writing part // the writing part
CIIToUBL c2u = new CIIToUBL(); final CIIToUBL c2u = new CIIToUBL();
String sourceFilename = "factur-x.xml"; final String sourceFilename = "factur-x.xml";
File input = getResourceAsFile(sourceFilename); final File input = getResourceAsFile(sourceFilename);
File expectedFile = getResourceAsFile("ubl-conv-ubl-output-factur-x.xml"); final File expectedFile = getResourceAsFile("ubl-conv-ubl-output-factur-x.xml");
String expected = null; String expected = null;
String result = null; String result = null;
try { try {
File tempFile = File.createTempFile("ZUGFeRD-UBL-", "-test"); final File tempFile = File.createTempFile("ZUGFeRD-UBL-", "-test");
c2u.convert(input, tempFile); c2u.convert(input, tempFile);
expected = ResourceUtilities.readFile(StandardCharsets.UTF_8, expectedFile.getAbsolutePath()); expected = ResourceUtilities.readFile(StandardCharsets.UTF_8, expectedFile.getAbsolutePath());
result = ResourceUtilities.readFile(StandardCharsets.UTF_8, tempFile.getAbsolutePath()); result = ResourceUtilities.readFile(StandardCharsets.UTF_8, tempFile.getAbsolutePath()).replaceAll("\r\n", "\n");
} catch (IOException e) { } catch (final IOException e) {
fail("Exception should not happen: "+e.getMessage()); fail("Exception should not happen: "+e.getMessage());
} }

View File

@@ -1,6 +1,5 @@
package org.mustangproject.validator; package org.mustangproject.validator;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -8,7 +7,6 @@ import java.io.PrintWriter;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
@@ -16,14 +14,9 @@ import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpression;
@@ -75,46 +68,47 @@ public class PDFValidator extends Validator {
return Arrays.asList(arr).contains(targetValue); return Arrays.asList(arr).contains(targetValue);
} }
@Override
public void validate() throws IrrecoverableValidationError { public void validate() throws IrrecoverableValidationError {
zfXML = null; zfXML = null;
File file = new File(pdfFilename); final File file = new File(pdfFilename);
// file existence must have been checked before // file existence must have been checked before
BigFileSearcher searcher = new BigFileSearcher(); final BigFileSearcher searcher = new BigFileSearcher();
byte[] pdfSignature = { '%', 'P', 'D', 'F' }; final byte[] pdfSignature = { '%', 'P', 'D', 'F' };
if (searcher.indexOf(file, pdfSignature) != 0) { if (searcher.indexOf(file, pdfSignature) != 0) {
context.addResultItem( context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "Not a PDF file "+pdfFilename).setSection(20).setPart(EPart.pdf)); new ValidationResultItem(ESeverity.fatal, "Not a PDF file "+pdfFilename).setSection(20).setPart(EPart.pdf));
} }
long startPDFTime = Calendar.getInstance().getTimeInMillis(); final long startPDFTime = Calendar.getInstance().getTimeInMillis();
// Step 1 Validate PDF // Step 1 Validate PDF
VeraGreenfieldFoundryProvider.initialise(); VeraGreenfieldFoundryProvider.initialise();
// Default validator config // Default validator config
ValidatorConfig validatorConfig = ValidatorFactory.defaultConfig(); final ValidatorConfig validatorConfig = ValidatorFactory.defaultConfig();
// Default features config // Default features config
FeatureExtractorConfig featureConfig = FeatureFactory.defaultConfig(); final FeatureExtractorConfig featureConfig = FeatureFactory.defaultConfig();
// Default plugins config // Default plugins config
PluginsCollectionConfig pluginsConfig = PluginsCollectionConfig.defaultConfig(); final PluginsCollectionConfig pluginsConfig = PluginsCollectionConfig.defaultConfig();
// Default fixer config // Default fixer config
MetadataFixerConfig fixerConfig = FixerFactory.defaultConfig(); final MetadataFixerConfig fixerConfig = FixerFactory.defaultConfig();
// Tasks configuring // Tasks configuring
EnumSet tasks = EnumSet.noneOf(TaskType.class); final EnumSet tasks = EnumSet.noneOf(TaskType.class);
tasks.add(TaskType.VALIDATE); tasks.add(TaskType.VALIDATE);
// tasks.add(TaskType.EXTRACT_FEATURES); // tasks.add(TaskType.EXTRACT_FEATURES);
// tasks.add(TaskType.FIX_METADATA); // tasks.add(TaskType.FIX_METADATA);
// Creating processor config // Creating processor config
ProcessorConfig processorConfig = ProcessorFactory.fromValues(validatorConfig, featureConfig, pluginsConfig, final ProcessorConfig processorConfig = ProcessorFactory.fromValues(validatorConfig, featureConfig, pluginsConfig,
fixerConfig, tasks); fixerConfig, tasks);
// Creating processor and output stream. // Creating processor and output stream.
ByteArrayOutputStream reportStream = new ByteArrayOutputStream(); final ByteArrayOutputStream reportStream = new ByteArrayOutputStream();
try (BatchProcessor processor = ProcessorFactory.fileBatchProcessor(processorConfig)) { try (BatchProcessor processor = ProcessorFactory.fileBatchProcessor(processorConfig)) {
// Generating list of files for processing // Generating list of files for processing
List<File> files = new ArrayList<>(); final List<File> files = new ArrayList<>();
files.add(new File(pdfFilename)); files.add(new File(pdfFilename));
// starting the processor // starting the processor
processor.process(files, ProcessorFactory.getHandler(FormatOption.MRR, true, reportStream, 100, processor.process(files, ProcessorFactory.getHandler(FormatOption.MRR, true, reportStream, 100,
@@ -122,25 +116,25 @@ public class PDFValidator extends Validator {
pdfReport = reportStream.toString("utf-8").replaceAll("<\\?xml version=\"1\\.0\" encoding=\"utf-8\"\\?>", pdfReport = reportStream.toString("utf-8").replaceAll("<\\?xml version=\"1\\.0\" encoding=\"utf-8\"\\?>",
""); "");
} catch (VeraPDFException e) { } catch (final VeraPDFException e) {
ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(6) final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(6)
.setPart(EPart.pdf); .setPart(EPart.pdf);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw); final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw); e.printStackTrace(pw);
vri.setStacktrace(sw.toString()); vri.setStacktrace(sw.toString());
context.addResultItem(vri); context.addResultItem(vri);
} catch (IOException excep) { } catch (final IOException excep) {
context.addResultItem(new ValidationResultItem(ESeverity.exception, excep.getMessage()).setSection(7) context.addResultItem(new ValidationResultItem(ESeverity.exception, excep.getMessage()).setSection(7)
.setPart(EPart.pdf).setStacktrace(excep.getStackTrace().toString())); .setPart(EPart.pdf).setStacktrace(excep.getStackTrace().toString()));
} }
// step 2 validate XMP // step 2 validate XMP
ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfFilename); final ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfFilename);
String xmp = zi.getXMP(); final String xmp = zi.getXMP();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document docXMP; final Document docXMP;
if (xmp.length() == 0) { if (xmp.length() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found") context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found")
@@ -153,15 +147,15 @@ public class PDFValidator extends Validator {
* <zf:Version>1.0</zf:Version> * <zf:Version>1.0</zf:Version>
*/ */
try { try {
DocumentBuilder builder = factory.newDocumentBuilder(); final DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xmp)); final InputSource is = new InputSource(new StringReader(xmp));
docXMP = builder.parse(is); docXMP = builder.parse(is);
XPathFactory xpathFactory = XPathFactory.newInstance(); final XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression // Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression
XPath xpath = xpathFactory.newXPath(); final XPath xpath = xpathFactory.newXPath();
// xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]"); // xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]");
// evaluate expression result on XML document ndList = (NodeList) // evaluate expression result on XML document ndList = (NodeList)
@@ -179,7 +173,7 @@ public class PDFValidator extends Validator {
boolean conformanceLevelValid=false; boolean conformanceLevelValid=false;
for (int i = 0; i < nodes.getLength(); i++) { for (int i = 0; i < nodes.getLength(); i++) {
String[] valueArray = { "BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG" }; final String[] valueArray = { "BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG" };
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
conformanceLevelValid=true; conformanceLevelValid=true;
} }
@@ -220,7 +214,7 @@ public class PDFValidator extends Validator {
} }
boolean documentFilenameValid=false; boolean documentFilenameValid=false;
for (int i = 0; i < nodes.getLength(); i++) { for (int i = 0; i < nodes.getLength(); i++) {
String[] valueArray = { "factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml" , "order-x.xml" }; final String[] valueArray = { "factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml" , "order-x.xml" };
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
documentFilenameValid=true; documentFilenameValid=true;
} }
@@ -246,7 +240,7 @@ public class PDFValidator extends Validator {
boolean versionValid=false; boolean versionValid=false;
for (int i = 0; i < nodes.getLength(); i++) { for (int i = 0; i < nodes.getLength(); i++) {
String[] valueArray = { "1.0", "2p0", "1.2", "2.0" }; //1.2 and 2.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1 final String[] valueArray = { "1.0", "2p0", "1.2", "2.0" }; //1.2 and 2.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
versionValid=true; versionValid=true;
} // e.g. 1.0 } // e.g. 1.0
@@ -258,26 +252,26 @@ public class PDFValidator extends Validator {
} }
} catch (SAXException e) { } catch (final SAXException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} catch (IOException e) { } catch (final IOException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} catch (ParserConfigurationException e) { } catch (final ParserConfigurationException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} catch (XPathExpressionException e) { } catch (final XPathExpressionException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} }
zfXML = zi.getUTF8(); zfXML = zi.getUTF8();
// step 3 find signatures // step 3 find signatures
try { try {
byte[] symtraxSignature = "Symtrax".getBytes("UTF-8"); final byte[] symtraxSignature = "Symtrax".getBytes("UTF-8");
byte[] mustangSignature = "via mustangproject".getBytes("UTF-8"); final byte[] mustangSignature = "via mustangproject".getBytes("UTF-8");
byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes("UTF-8"); final byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes("UTF-8");
byte[] intarsysSignature = "intarsys ".getBytes("UTF-8"); final byte[] intarsysSignature = "intarsys ".getBytes("UTF-8");
byte[] konikSignature = "Konik".getBytes("UTF-8"); final byte[] konikSignature = "Konik".getBytes("UTF-8");
byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes("UTF-8"); final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes("UTF-8");
byte[] ghostscriptSignature = "%%Invocation:".getBytes("UTF-8"); final byte[] ghostscriptSignature = "%%Invocation:".getBytes("UTF-8");
if (searcher.indexOf(file, symtraxSignature) != -1) { if (searcher.indexOf(file, symtraxSignature) != -1) {
Signature = "Symtrax"; Signature = "Symtrax";
@@ -297,13 +291,13 @@ public class PDFValidator extends Validator {
context.setSignature(Signature); context.setSignature(Signature);
} catch (UnsupportedEncodingException e) { } catch (final UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} }
// step 4:validate additional data // step 4:validate additional data
HashMap<String, byte[]> additionalData=zi.getAdditionalData(); final HashMap<String, byte[]> additionalData=zi.getAdditionalData();
for (String filename : additionalData.keySet()) { for (final String filename : additionalData.keySet()) {
// validating xml in byte[] additionalData.get(filename) // validating xml in byte[] additionalData.get(filename)
LOGGER.info("validating additionalData " + filename); LOGGER.info("validating additionalData " + filename);
validateSchema(additionalData.get(filename), "ad/basic/additional_data_base_schema.xsd", 2, EPart.pdf); validateSchema(additionalData.get(filename), "ad/basic/additional_data_base_schema.xsd", 2, EPart.pdf);
@@ -312,7 +306,7 @@ public class PDFValidator extends Validator {
//end //end
long endTime = Calendar.getInstance().getTimeInMillis(); final long endTime = Calendar.getInstance().getTimeInMillis();
if (!pdfReport.contains("validationReports compliant=\"1\"")) { if (!pdfReport.contains("validationReports compliant=\"1\"")) {
context.setInvalid(); context.setInvalid();
} }
@@ -323,7 +317,7 @@ public class PDFValidator extends Validator {
} }
context.addCustomXML(pdfReport + "<info><signature>" context.addCustomXML(pdfReport + "<info><signature>"
+ ((context.getSignature() != null) ? context.getSignature() : "unknown") + ((context.getSignature() != null) ? context.getSignature() : "unknown")
+ "</signature><duration unit='ms'>" + (endTime - startPDFTime) + "</duration></info>"); + "</signature><duration unit=\"ms\">" + (endTime - startPDFTime) + "</duration></info>");
} }

View File

@@ -18,7 +18,7 @@ public class ValidationContext {
public ValidationContext(Logger log) { public ValidationContext(Logger log) {
logger = log; logger = log;
results = new Vector<ValidationResultItem>(); results = new Vector<>();
} }
public void addResultItem(ValidationResultItem vr) throws IrrecoverableValidationError { public void addResultItem(ValidationResultItem vr) throws IrrecoverableValidationError {
@@ -110,14 +110,14 @@ public class ValidationContext {
res += "<messages>"; res += "<messages>";
} }
for (ValidationResultItem validationResultItem : results) { for (final ValidationResultItem validationResultItem : results) {
// xml and pdf are handled in their respective sections // xml and pdf are handled in their respective sections
res += validationResultItem.getXMLOnce() + "\n"; res += validationResultItem.getXMLOnce() + "\n";
} }
if (results.size() > 0) { if (results.size() > 0) {
res += "</messages>"; res += "</messages>";
} }
res += "<summary status='" + (isValid ? "valid" : "invalid") + "'/>"; res += "<summary status=\"" + (isValid ? "valid" : "invalid") + "\"/>";
return res; return res;
} }
@@ -126,9 +126,9 @@ public class ValidationContext {
* @return the unique error types as comma separated string * @return the unique error types as comma separated string
*/ */
public String getCSVResult() { public String getCSVResult() {
ArrayList<String> errorcodes = new ArrayList<String>(); final ArrayList<String> errorcodes = new ArrayList<>();
for (ValidationResultItem validationResultItem : results) { for (final ValidationResultItem validationResultItem : results) {
String errorCodeStr=Integer.toString(validationResultItem.getSection()); final String errorCodeStr=Integer.toString(validationResultItem.getSection());
errorcodes.add(errorCodeStr); errorcodes.add(errorCodeStr);
} }
return String.join(",", errorcodes); return String.join(",", errorcodes);

View File

@@ -1,6 +1,9 @@
package org.mustangproject.validator; package org.mustangproject.validator;
import java.io.*; import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -22,13 +25,14 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.helger.schematron.ISchematronResource;
import com.helger.schematron.svrl.SVRLHelper;
import com.helger.schematron.svrl.jaxb.FailedAssert; import com.helger.schematron.svrl.jaxb.FailedAssert;
import com.helger.schematron.svrl.jaxb.FiredRule; import com.helger.schematron.svrl.jaxb.FiredRule;
import com.helger.schematron.svrl.jaxb.SchematronOutputType; import com.helger.schematron.svrl.jaxb.SchematronOutputType;
import com.helger.schematron.ISchematronResource;
import com.helger.schematron.xslt.SchematronResourceXSLT; import com.helger.schematron.xslt.SchematronResourceXSLT;
import com.helger.schematron.svrl.SVRLHelper;
import org.xml.sax.InputSource;
public class XMLValidator extends Validator { public class XMLValidator extends Validator {
@@ -54,18 +58,19 @@ public class XMLValidator extends Validator {
* @param name the absolute filename of an xml file to validate * @param name the absolute filename of an xml file to validate
* @throws IrrecoverableValidationError * @throws IrrecoverableValidationError
*/ */
@Override
public void setFilename(String name) throws IrrecoverableValidationError { // from XML Filename public void setFilename(String name) throws IrrecoverableValidationError { // from XML Filename
filename = name; filename = name;
// file existence must have been checked before // file existence must have been checked before
try { try {
zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(name))), StandardCharsets.UTF_8); zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(name))), StandardCharsets.UTF_8);
} catch (IOException e) { } catch (final IOException e) {
ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9) final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9)
.setPart(EPart.fx); .setPart(EPart.fx);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw); final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw); e.printStackTrace(pw);
vri.setStacktrace(sw.toString()); vri.setStacktrace(sw.toString());
context.addResultItem(vri); context.addResultItem(vri);
@@ -105,13 +110,13 @@ public class XMLValidator extends Validator {
*/ */
@Override @Override
public void validate() throws IrrecoverableValidationError { public void validate() throws IrrecoverableValidationError {
long startXMLTime = Calendar.getInstance().getTimeInMillis(); final long startXMLTime = Calendar.getInstance().getTimeInMillis();
firedRules = 0; firedRules = 0;
failedRules = 0; failedRules = 0;
if (zfXML.isEmpty()) { if (zfXML.isEmpty()) {
ValidationResultItem res = new ValidationResultItem(ESeverity.exception, final ValidationResultItem res = new ValidationResultItem(ESeverity.exception,
"XML data not found in " + filename "XML data not found in " + filename
+ ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?") + ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?")
.setSection(3); .setSection(3);
@@ -136,33 +141,33 @@ public class XMLValidator extends Validator {
* *
*/ */
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use dbf.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use
// document.getElementsByTagNameNS("*",... // document.getElementsByTagNameNS("*",...
DocumentBuilder db = dbf.newDocumentBuilder(); final DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(zfXML)); final InputSource is = new InputSource(new StringReader(zfXML));
Document doc = db.parse(is); final Document doc = db.parse(is);
Element root = doc.getDocumentElement(); final Element root = doc.getDocumentElement();
NodeList ndList; final NodeList ndList;
// rootNode = document.getDocumentElement(); // rootNode = document.getDocumentElement();
// ApplicableSupplyChainTradeSettlement // ApplicableSupplyChainTradeSettlement
// Create XPathFactory object // Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance(); final XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object // Create XPath object
XPath xpath = xpathFactory.newXPath(); final XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile( final XPathExpression expr = xpath.compile(
"//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"]/text()"); "//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"]/text()");
// evaluate expression result on XML document // evaluate expression result on XML document
ndList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); ndList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) {
Node booking = ndList.item(bookingIndex); final Node booking = ndList.item(bookingIndex);
// if there is a attribute in the tag number:value // if there is a attribute in the tag number:value
// urn:ferd:CrossIndustryDocument:invoice:1p0:extended // urn:ferd:CrossIndustryDocument:invoice:1p0:extended
// setForeignReference(booking.getTextContent()); // setForeignReference(booking.getTextContent());
@@ -324,24 +329,24 @@ public class XMLValidator extends Validator {
} }
} catch (IrrecoverableValidationError er) { } catch (final IrrecoverableValidationError er) {
throw er; throw er;
} catch (Exception e) { } catch (final Exception e) {
ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(22) final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(22)
.setPart(EPart.fx); .setPart(EPart.fx);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw); final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw); e.printStackTrace(pw);
vri.setStacktrace(sw.toString()); vri.setStacktrace(sw.toString());
context.addResultItem(vri); context.addResultItem(vri);
} }
} }
long endTime = Calendar.getInstance().getTimeInMillis(); final long endTime = Calendar.getInstance().getTimeInMillis();
context.addCustomXML("<info><version>" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid") context.addCustomXML("<info><version>" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid")
+ "</version><profile>" + ((context.getProfile() != null) ? context.getProfile() : "invalid") + + "</version><profile>" + ((context.getProfile() != null) ? context.getProfile() : "invalid") +
"</profile><validator version=\"" + XMLValidator.class.getPackage().getImplementationVersion() + "\"></validator><rules><fired>" + firedRules + "</fired><failed>" + failedRules + "</failed></rules>" + "<duration unit='ms'>" + (endTime - startXMLTime) + "</duration></info>"); "</profile><validator version=\"" + XMLValidator.class.getPackage().getImplementationVersion() + "\"></validator><rules><fired>" + firedRules + "</fired><failed>" + failedRules + "</failed></rules>" + "<duration unit=\"ms\">" + (endTime - startXMLTime) + "</duration></info>");
} }
@@ -377,20 +382,20 @@ public class XMLValidator extends Validator {
throw new IllegalArgumentException(xsltFilename + " is invalid Schematron!"); throw new IllegalArgumentException(xsltFilename + " is invalid Schematron!");
} }
SchematronOutputType sout; final SchematronOutputType sout;
try { try {
sout = aResSCH sout = aResSCH
.applySchematronValidationToSVRL(new StreamSource(new StringReader(xml))); .applySchematronValidationToSVRL(new StreamSource(new StringReader(xml)));
} catch (Exception e) { } catch (final Exception e) {
throw new IrrecoverableValidationError(e.getMessage()); throw new IrrecoverableValidationError(e.getMessage());
} }
List<Object> failedAsserts = sout.getActivePatternAndFiredRuleAndFailedAssert(); final List<Object> failedAsserts = sout.getActivePatternAndFiredRuleAndFailedAssert();
if (failedAsserts.size() > 0) { if (failedAsserts.size() > 0) {
for (Object object : failedAsserts) { for (final Object object : failedAsserts) {
if (object instanceof FailedAssert) { if (object instanceof FailedAssert) {
FailedAssert failedAssert = (FailedAssert) object; final FailedAssert failedAssert = (FailedAssert) object;
LOGGER.info("FailedAssert ", failedAssert); LOGGER.info("FailedAssert ", failedAssert);
context.addResultItem(new ValidationResultItem(severity, SVRLHelper.getAsString(failedAssert.getText())) context.addResultItem(new ValidationResultItem(severity, SVRLHelper.getAsString(failedAssert.getText()))

View File

@@ -9,8 +9,8 @@ public class PDFValidatorTest extends ResourceCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log
public void testPDFValidation() { public void testPDFValidation() {
ValidationContext vc = new ValidationContext(null); final ValidationContext vc = new ValidationContext(null);
PDFValidator pv = new PDFValidator(vc); final PDFValidator pv = new PDFValidator(vc);
try { try {
@@ -25,10 +25,10 @@ public class PDFValidatorTest extends ResourceCase {
pv.setFilename(tempFile.getAbsolutePath()); pv.setFilename(tempFile.getAbsolutePath());
pv.validate(); pv.validate();
String actual = pv.getXMLResult(); String actual = pv.getXMLResult();
assertEquals(true, actual.contains("summary status='valid")); assertEquals(true, actual.contains("summary status=\"valid"));
assertEquals(false, actual.contains("summary status='invalid")); assertEquals(false, actual.contains("summary status=\"invalid"));
XMLValidator xv = new XMLValidator(vc); final XMLValidator xv = new XMLValidator(vc);
xv.setStringContent(pv.getRawXML()); xv.setStringContent(pv.getRawXML());
xv.validate(); xv.validate();
actual = vc.getXMLResult(); actual = vc.getXMLResult();
@@ -58,16 +58,16 @@ public class PDFValidatorTest extends ResourceCase {
actual.contains("validationReports compliant=\"1\" nonCompliant=\"0\" failedJobs=\"0\">")); actual.contains("validationReports compliant=\"1\" nonCompliant=\"0\" failedJobs=\"0\">"));
assertEquals(false, actual.contains("<error")); assertEquals(false, actual.contains("<error"));
} catch (IrrecoverableValidationError e) { } catch (final IrrecoverableValidationError e) {
// ignore, will be in XML output anyway // ignore, will be in XML output anyway
} }
} }
public void testPDFXMLValidation() { public void testPDFXMLValidation() {
ValidationContext vc = new ValidationContext(null); final ValidationContext vc = new ValidationContext(null);
try { try {
PDFValidator pv = new PDFValidator(vc); final PDFValidator pv = new PDFValidator(vc);
File tempFile = getResourceAsFile("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");// need a more File tempFile = getResourceAsFile("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");// need a more
// invalid file here // invalid file here
@@ -99,7 +99,7 @@ public class PDFValidatorTest extends ResourceCase {
xmlvres = xv.getXMLResult(); xmlvres = xv.getXMLResult();
assertEquals(true, pdfvres.contains("valid") && !pdfvres.contains("invalid")); assertEquals(true, pdfvres.contains("valid") && !pdfvres.contains("invalid"));
assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid")); assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid"));
} catch (IrrecoverableValidationError e) { } catch (final IrrecoverableValidationError e) {
// ignore, will be in XML output anyway // ignore, will be in XML output anyway
} }
@@ -107,8 +107,8 @@ public class PDFValidatorTest extends ResourceCase {
public void testXMPValidation() { public void testXMPValidation() {
ValidationContext vc = new ValidationContext(null); final ValidationContext vc = new ValidationContext(null);
PDFValidator pv = new PDFValidator(vc); final PDFValidator pv = new PDFValidator(vc);
try { try {
File tempFile = getResourceAsFile("invalidXMP.pdf"); File tempFile = getResourceAsFile("invalidXMP.pdf");
@@ -130,7 +130,7 @@ public class PDFValidatorTest extends ResourceCase {
assertEquals(false, actual.contains("<error"));// issue 18: "ConformanceLevel not found" should not be assertEquals(false, actual.contains("<error"));// issue 18: "ConformanceLevel not found" should not be
// reported since it's actually there // reported since it's actually there
} catch (IrrecoverableValidationError e) { } catch (final IrrecoverableValidationError e) {
// ignore, will be in XML output anyway // ignore, will be in XML output anyway
} }