diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java index 1657a91c..429eb3d9 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java @@ -218,7 +218,7 @@ public class Main { } catch (IOException e) { LOGGER.error(e.getMessage(), e); } - if (!selectedAnswer.equals("Y") && !selectedAnswer.equals("y")) { + if (!"Y".equalsIgnoreCase(selectedAnswer)) { System.err.println("Aborted by user"); System.exit(-1); } @@ -653,9 +653,9 @@ public class Main { if (zfProfile == null) { try { - if ((format.equals("zf") && (zfIntVersion == 1)) || (format.equals("ox"))) { + if ((("zf".equals(format)) && (zfIntVersion == 1)) || ("ox".equals(format))) { zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t"); - } else if ((format.equals("da"))) { + } else if (("da".equals(format))) { zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p"); } else { zfProfile = getStringFromUser( @@ -676,20 +676,20 @@ public class Main { ensureFileExists(xmlName); ensureFileNotExists(outName); - if ((format.equals("fx")) && (zfIntVersion > 1)) { + if ((("fx".equals(format))) && (zfIntVersion > 1)) { throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)"); } EStandard standard = EStandard.facturx; - if (format.equals("zf")) { + if ("zf".equals(format)) { standard = EStandard.zugferd; } - if (format.equals("da")) { + if ("da".equals(format)) { standard = EStandard.despatchadvice; zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1); - } else if (((format.equals("zf")) && (zfIntVersion == 1)) || (format.equals("ox"))) { - if (format.equals("ox")) { + } else if (((("zf".equals(format))) && (zfIntVersion == 1)) || ("ox".equals(format))) { + if ("ox".equals(format)) { standard = EStandard.orderx; } if (zfProfile.equals("b")) { diff --git a/library/src/main/java/org/mustangproject/Contact.java b/library/src/main/java/org/mustangproject/Contact.java index a5e8b3bf..a85e61c5 100644 --- a/library/src/main/java/org/mustangproject/Contact.java +++ b/library/src/main/java/org/mustangproject/Contact.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.util.Set; /*** * a named contact person in an organisation @@ -111,50 +112,52 @@ public class Contact implements IZUGFeRDExportableContact { for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { //nodes.item(i).getTextContent())) { Node currentItemNode = nodes.item(nodeIndex); - if (currentItemNode.getLocalName() != null) { + String localName = currentItemNode.getLocalName(); + if (localName != null) { - if (currentItemNode.getLocalName().equals("PersonName")/*CII*/||currentItemNode.getLocalName().equals("Name")/*UBL*/) { - if (currentItemNode.getFirstChild()!=null) { + Set nameElements = Set.of("PersonName"/*CII*/, "Name"/*UBL*/); + if (localName != null && nameElements.contains(localName) + && currentItemNode.getFirstChild()!=null) { setName(currentItemNode.getFirstChild().getNodeValue()); } - } - if (currentItemNode.getLocalName().equals("TelephoneUniversalCommunication")) { /*CII*/ + + if (localName.equals("TelephoneUniversalCommunication")) { /*CII*/ NodeList tel = currentItemNode.getChildNodes(); for (int telChildIndex = 0; telChildIndex < tel.getLength(); telChildIndex++) { - if (tel.item(telChildIndex).getLocalName() != null) { - if (tel.item(telChildIndex).getLocalName().equals("CompleteNumber")) { + String telLocalName = tel.item(telChildIndex).getLocalName(); + if (telLocalName != null && telLocalName.equals("CompleteNumber")) { setPhone(tel.item(telChildIndex).getTextContent()); } - } + } - } else if (currentItemNode.getLocalName().equals("Telephone")) { /* UBL */ + } else if (localName.equals("Telephone")) { /* UBL */ setPhone(currentItemNode.getTextContent()); } // CII: only for Extended profile - if (currentItemNode.getLocalName().equals("FaxUniversalCommunication")) { /* CII */ + if (localName.equals("FaxUniversalCommunication")) { /* CII */ NodeList fax = currentItemNode.getChildNodes(); for (int faxChildIndex = 0; faxChildIndex < fax.getLength(); faxChildIndex++) { - if (fax.item(faxChildIndex).getLocalName() != null) { - if (fax.item(faxChildIndex).getLocalName().equals("CompleteNumber")) { + String faxLocalName = fax.item(faxChildIndex).getLocalName(); + if (faxLocalName != null && faxLocalName.equals("CompleteNumber")) { setFax(fax.item(faxChildIndex).getTextContent()); } - } + } - } else if (currentItemNode.getLocalName().equals("Telefax")) { /* UBL */ + } else if (localName.equals("Telefax")) { /* UBL */ setFax(currentItemNode.getTextContent()); } - if (currentItemNode.getLocalName().equals("EmailURIUniversalCommunication")) { /* CII */ + if (localName.equals("EmailURIUniversalCommunication")) { /* CII */ NodeList email = currentItemNode.getChildNodes(); for (int emailChildIndex = 0; emailChildIndex < email.getLength(); emailChildIndex++) { - if (email.item(emailChildIndex).getLocalName() != null) { - if (email.item(emailChildIndex).getLocalName().equals("URIID")) { + String emailLocalName = email.item(emailChildIndex).getLocalName(); + if (emailLocalName != null && emailLocalName.equals("URIID")) { setEMail(email.item(emailChildIndex).getTextContent()); } - } + } - } else if (currentItemNode.getLocalName().equals("ElectronicMail")) { /* UBL */ + } else if (localName.equals("ElectronicMail")) { /* UBL */ setEMail(currentItemNode.getTextContent()); } } diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index 66491cf7..f25b4065 100644 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -2,7 +2,7 @@ package org.mustangproject; import java.util.ArrayList; import java.util.List; -import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -163,7 +163,9 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { NodeList taxSchemechilds = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes(); for (int taxSchemechildsIndex = 0; taxSchemechildsIndex < taxSchemechilds.getLength(); taxSchemechildsIndex++) { if (taxSchemechilds.item(taxSchemechildsIndex).getLocalName() != null) { - if (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("FC") || (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("NOVAT"))) { + Set taxSchemeTypes = Set.of("FC", "NOVAT"); + String textContent = taxSchemechilds.item(taxSchemechildsIndex).getTextContent(); + if (textContent != null && taxSchemeTypes.contains(textContent)) { setTaxID(CompanyId); } else { setVATID(CompanyId); diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java index 8368b466..6c262523 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java @@ -41,9 +41,9 @@ public class Profile { * @return the XMP name string of the profile */ public String getXMPName() { - if (name.equals("BASICWL")) { + if ("BASICWL".equals(name)) { return "BASIC WL"; - } else if (name.equals("EN16931")) { + } else if ("EN16931".equals(name)) { return "EN 16931"; } else { return name; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 6efb4b23..f990086a 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -33,9 +33,9 @@ import java.util.Arrays; import java.util.Base64; import java.util.Date; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import org.dom4j.Document; @@ -721,9 +721,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } } } - if (DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode()) - || DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode()) - ) { + if (trans.getDocumentCode() != null + && Set.of(DocumentCodeTypeConstants.CORRECTEDINVOICE, DocumentCodeTypeConstants.CREDITNOTE).contains(trans.getDocumentCode())) { hasDueDate = false; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java index 0909735f..6eb0fc08 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java @@ -225,7 +225,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte * @return the filename of the file to be embedded */ public String getFilenameForVersion(int ver, Profile profile) { - if (profile.getName().equals("XRECHNUNG")) { + if ("XRECHNUNG".equals(profile.getName())) { return "xrechnung.xml"; } if (isFacturX) { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 7136be78..ea4616fa 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -560,7 +560,7 @@ public class ZUGFeRDInvoiceImporter { } zpp.addNotes(includedNotes); String rootNode = extractString("local-name(/*)"); - if (rootNode.equals("Invoice") || rootNode.equals("CreditNote")) { + if (rootNode != null && Set.of("Invoice", "CreditNote").contains(rootNode)) { // UBL... // //*[local-name()="Invoice" or local-name()="CreditNote"] number = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"ID\"]").trim(); diff --git a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java index 0e35b714..05380d17 100644 --- a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.EnumSet; import java.util.HashMap; +import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -41,6 +42,7 @@ import org.verapdf.processor.TaskType; import org.verapdf.processor.plugins.PluginsCollectionConfig; import org.verapdf.processor.reports.ItemDetails; import org.w3c.dom.Document; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -194,9 +196,9 @@ public class PDFValidator extends Validator { boolean documentTypeValid = false; for (int i = 0; i < nodes.getLength(); i++) { - if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER") - || nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent() - .equals("ORDER_CHANGE")) { + Node item = nodes.item(i); + String textContent = item.getTextContent(); + if (textContent != null && Set.of("INVOICE", "ORDER", "ORDER_RESPONSE", "ORDER_CHANGE").contains(textContent)) { documentTypeValid = true; } } diff --git a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java index c258f114..d125cd7d 100644 --- a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java @@ -10,6 +10,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.text.ParseException; import java.util.Calendar; +import java.util.Set; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; @@ -103,7 +104,7 @@ public class XMLValidator extends Validator { * @return true if semantically identical */ public static boolean matchesURI(String uri1, String uri2) { - return (uri1.equals(uri2) || uri1.startsWith(uri2 + "#")); + return (uri1 != null && (uri2 != null && (uri1.equals(uri2) || uri1.startsWith(uri2 + "#")))); } @@ -217,35 +218,41 @@ public class XMLValidator extends Validator { // urn:cen.eu:en16931:2017 // urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic - if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) { + String rootLocalName = root.getLocalName(); + String contextProfile = context.getProfile(); + if ("SCRDMCCBDACIOMessageStructure".equalsIgnoreCase(rootLocalName)) { context.setGeneration("1"); isOrderX = true; - isBasic = context.getProfile().contains("basic"); - isEN16931 = context.getProfile().contains("comfort"); - isExtended = context.getProfile().contains("extended"); + isBasic = contextProfile.contains("basic"); + isEN16931 = contextProfile.contains("comfort"); + isExtended = contextProfile.contains("extended"); validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox); xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt"; - } else if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) { + } else if ("SCRDMCCBDACIOMessageStructure".equalsIgnoreCase(rootLocalName)) { context.setGeneration("1"); isOrderX = true; validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox); xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt"; - } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X + } else if ("CrossIndustryInvoice".equalsIgnoreCase(rootLocalName)) { // ZUGFeRD 2.0 or Factur-X context.setGeneration("2"); - isMiniumum = context.getProfile().contains("minimum"); - isBasic = context.getProfile().contains("basic"); - isBasicWithoutLines = context.getProfile().contains("basicwl"); + isMiniumum = contextProfile.contains("minimum"); + isBasic = contextProfile.contains("basic"); + isBasicWithoutLines = contextProfile.contains("basicwl"); if (isBasicWithoutLines) { isBasic = false;// basicwl also contains the string basic... } - isEN16931 = matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") - || matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017"); + isEN16931 = Set.of( + "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931", + "urn:cen.eu:en16931:2017" + ) + .stream() + .anyMatch(profile -> matchesURI(contextProfile, profile)); - isExtended = context.getProfile().contains("extended"); - isXRechnung = context.getProfile().contains("xrechnung"); + isExtended = contextProfile.contains("extended"); + isXRechnung = contextProfile.contains("xrechnung"); if ((isExtended) || (isXRechnung)) { isEN16931 = false;// the uri for extended is urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended and thus contains en16931... @@ -287,13 +294,13 @@ public class XMLValidator extends Validator { // saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s // tcdl2.0.tsdtf.sch iso_svrl.xsl - } else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote")) { + } else if ("Invoice".equalsIgnoreCase(rootLocalName) || rootLocalName.equalsIgnoreCase("CreditNote")) { context.setGeneration("2"); context.setFormat("UBL"); - isXRechnung = context.getProfile().contains("xrechnung"); + isXRechnung = contextProfile.contains("xrechnung"); // UBL LOGGER.debug("UBL"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + root.getLocalName() + "-2.1.xsd", 18, EPart.fx); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + rootLocalName + "-2.1.xsd", 18, EPart.fx); xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt"; mainSchematronSectionErrorTypeCode = 24; @@ -305,8 +312,10 @@ public class XMLValidator extends Validator { XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass * */ //validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx); - String xrVersion = context.getProfile().substring(context.getProfile().length() - 3).replace(".", ""); - if (!xrVersion.equals("12") && !xrVersion.equals("20") && !xrVersion.equals("21") && !xrVersion.equals("22") && !xrVersion.equals("23") && !xrVersion.equals("30")) { + String xrVersion = contextProfile.substring(contextProfile.length() - 3).replace(".", ""); + + Set supportedVersions = Set.of("12", "20", "21", "22", "23", "30"); + if (!supportedVersions.contains(xrVersion)) { throw new Exception("Unsupported XR version"); } LOGGER.debug("is XRechnung v{}", xrVersion); @@ -316,14 +325,16 @@ public class XMLValidator extends Validator { } - } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryDocument")) { // ZUGFeRD 1.0 + } else if ("CrossIndustryDocument".equalsIgnoreCase(rootLocalName)) { // ZUGFeRD 1.0 context.setGeneration("1"); // - if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); + Set validZF1Profiles = Set.of( + "urn:ferd:CrossIndustryDocument:invoice:1p0:basic", + "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort", + "urn:ferd:CrossIndustryDocument:invoice:1p0:extended" + ); + if (validZF1Profiles.stream().noneMatch(profile -> matchesURI(contextProfile, profile))) { + addUnsupportedProfileResultItem(); } validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_10/ZUGFeRD1p0.xsd", 18, EPart.fx); @@ -332,41 +343,41 @@ public class XMLValidator extends Validator { context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Unsupported root element") .setSection(3).setPart(EPart.fx)); } - if (context.getFormat().equals("CII")) { - - if (context.getGeneration().equals("2")) { - if ((!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"))) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile()) - .setSection(25).setPart(EPart.fx)); + if ("CII".equals(context.getFormat())) { + if ("2".equals(context.getGeneration())) { + Set validZF2Profiles = Set.of( + "urn:factur-x.eu:1p0:minimum", + "urn:zugferd.de:2p0:minimum", + "urn:factur-x.eu:1p0:basicwl", + "urn:zugferd.de:2p0:basicwl", + "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic", + "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic", + "urn:cen.eu:en16931:2017", + "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended", + "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended" + ); + if (validZF2Profiles.stream().noneMatch(profile -> matchesURI(contextProfile, profile))) { + addUnsupportedProfileResultItem(); } } else /** v1 */ { if (isOrderX) { //order-x 1.0 - if ((!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) { - //zf 1.0 - context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); - + if(Set.of( + "urn:order-x.eu:1p0:basic", + "urn:order-x.eu:1p0:comfort", + "urn:order-x.eu:1p0:extended" + ).stream().noneMatch(profile -> matchesURI(contextProfile, profile))) { + addUnsupportedProfileResultItem(); } - } else if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { - //zf 1.0 - context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); + } else if (Set.of( + "urn:ferd:CrossIndustryDocument:invoice:1p0:basic", + "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort", + "urn:ferd:CrossIndustryDocument:invoice:1p0:extended" + ).stream().noneMatch(profile -> matchesURI(contextProfile, profile))) { + //zf 1.0 + addUnsupportedProfileResultItem(); } } } @@ -377,7 +388,7 @@ public class XMLValidator extends Validator { } - if (context.getFormat().equals("CII") && (context.getGeneration().equals("2"))) { + if ("CII".equals(context.getFormat()) && ("2".equals(context.getGeneration()))) { if (isXRechnung) { //additionally validate against CEN, the CEN rules are part of the ZF Schematron anyway @@ -408,10 +419,30 @@ public class XMLValidator extends Validator { } final long endTime = Calendar.getInstance().getTimeInMillis(); - context.addCustomXML("" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid") - + "" + ((context.getProfile() != null) ? context.getProfile() : "invalid") + - "" + firedRules + "" + failedRules + "" + "" + (endTime - startXMLTime) + ""); + context.addCustomXML(getInfoXml(endTime, startXMLTime)); + } + private void addUnsupportedProfileResultItem() throws IrrecoverableValidationError { + context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile()) + .setSection(25).setPart(EPart.fx)); + } + + private String getInfoXml(long endTime, long startXMLTime) { + String generation = context.getGeneration() != null ? context.getGeneration() : "invalid"; + String profile = context.getProfile() != null ? context.getProfile() : "invalid"; + String validatorVersion = XMLValidator.class.getPackage().getImplementationVersion(); + long duration = endTime - startXMLTime; + + return String.format( + "" + + "%s" + + "%s" + + "" + + "%d%d" + + "%d" + + "", + generation, profile, validatorVersion, firedRules, failedRules, duration + ); } private void checkArithmetics(ValidationContext context) { @@ -514,7 +545,7 @@ public class XMLValidator extends Validator { if (defaultSeverity == ESeverity.notice) { severity = defaultSeverity; } else if (currentFailNode.getAttributes().getNamedItem("flag") != null - && currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) { + && "warning".equals(currentFailNode.getAttributes().getNamedItem("flag").getNodeValue())) { // the XR issues warnings with flag=warning severity = ESeverity.warning; } else {