diff --git a/README.md b/README.md index fabd9663..f674e374 100644 --- a/README.md +++ b/README.md @@ -266,8 +266,9 @@ They depend on several other libraries so I suggest you are going for the Maven * v9.1.1 - 2023-11-22 * Added the "peppol-directory-businesscard" to the known submodules in the BOM part of pom.xml * Updated to OpenPeppol eDEC Code Lists v8.7 - * Improved the Peppol Document Type Identifier value syntax checks - * Improved the Peppol Process Identifier value syntax checks + * Improved the Peppol Document Type Identifier value syntax checks - for `busdox-docid-qns` and for `peppol-doctype-wildcard` + * Improved the Peppol Process Identifier value syntax checks + * Identifier value checks can now be different per identifier scheme * v9.1.0 - 2023-11-09 * Added new submodule `peppol-directory-businesscard`. It is meant to replace the `phoss-directory-businesscard` one. * v9.0.8 - 2023-08-22 diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR1IdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR1IdentifierFactory.java index 2533578f..3a43100e 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR1IdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR1IdentifierFactory.java @@ -61,17 +61,20 @@ public boolean isDocumentTypeIdentifierSchemeValid (@Nullable final String sSche } @Override - public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sValue) + public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR1IdentifierHelper.isValidIdentifierValue (sValue); } @Nullable - public BDXR1DocumentTypeIdentifier createDocumentTypeIdentifier (@Nullable final String sScheme, @Nullable final String sValue) + public BDXR1DocumentTypeIdentifier createDocumentTypeIdentifier (@Nullable final String sScheme, + @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isDocumentTypeIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); - if (isDocumentTypeIdentifierSchemeValid (sRealScheme) && isDocumentTypeIdentifierValueValid (sRealValue)) + final String sRealValue = nullNotEmpty (isDocumentTypeIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); + if (isDocumentTypeIdentifierSchemeValid (sRealScheme) && + isDocumentTypeIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR1DocumentTypeIdentifier (sRealScheme, sRealValue); return null; } @@ -91,17 +94,19 @@ public boolean isParticipantIdentifierSchemeValid (@Nullable final String sSchem } @Override - public boolean isParticipantIdentifierValueValid (@Nullable final String sValue) + public boolean isParticipantIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR1IdentifierHelper.isValidIdentifierValue (sValue); } @Nullable - public BDXR1ParticipantIdentifier createParticipantIdentifier (@Nullable final String sScheme, @Nullable final String sValue) + public BDXR1ParticipantIdentifier createParticipantIdentifier (@Nullable final String sScheme, + @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isParticipantIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); - if (isParticipantIdentifierSchemeValid (sRealScheme) && isParticipantIdentifierValueValid (sRealValue)) + final String sRealValue = nullNotEmpty (isParticipantIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); + if (isParticipantIdentifierSchemeValid (sRealScheme) && isParticipantIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR1ParticipantIdentifier (sRealScheme, sRealValue); return null; } @@ -120,7 +125,7 @@ public boolean isProcessIdentifierCaseInsensitive (@Nullable final String sSchem } @Override - public boolean isProcessIdentifierValueValid (final String sValue) + public boolean isProcessIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR1IdentifierHelper.isValidIdentifierValue (sValue); } @@ -129,9 +134,10 @@ public boolean isProcessIdentifierValueValid (final String sValue) public BDXR1ProcessIdentifier createProcessIdentifier (@Nullable final String sScheme, @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isProcessIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); + final String sRealValue = nullNotEmpty (isProcessIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); - if (isProcessIdentifierSchemeValid (sRealScheme) && isProcessIdentifierValueValid (sRealValue)) + if (isProcessIdentifierSchemeValid (sRealScheme) && isProcessIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR1ProcessIdentifier (sRealScheme, sRealValue); return null; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR2IdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR2IdentifierFactory.java index 2cef820c..5ae1d050 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR2IdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/BDXR2IdentifierFactory.java @@ -61,17 +61,20 @@ public boolean isDocumentTypeIdentifierSchemeValid (@Nullable final String sSche } @Override - public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sValue) + public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR2IdentifierHelper.isValidIdentifierValue (sValue); } @Nullable - public BDXR2DocumentTypeIdentifier createDocumentTypeIdentifier (@Nullable final String sScheme, @Nullable final String sValue) + public BDXR2DocumentTypeIdentifier createDocumentTypeIdentifier (@Nullable final String sScheme, + @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isDocumentTypeIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); - if (isDocumentTypeIdentifierSchemeValid (sRealScheme) && isDocumentTypeIdentifierValueValid (sRealValue)) + final String sRealValue = nullNotEmpty (isDocumentTypeIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); + if (isDocumentTypeIdentifierSchemeValid (sRealScheme) && + isDocumentTypeIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR2DocumentTypeIdentifier (sRealScheme, sRealValue); return null; } @@ -91,17 +94,19 @@ public boolean isParticipantIdentifierSchemeValid (@Nullable final String sSchem } @Override - public boolean isParticipantIdentifierValueValid (@Nullable final String sValue) + public boolean isParticipantIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR2IdentifierHelper.isValidIdentifierValue (sValue); } @Nullable - public BDXR2ParticipantIdentifier createParticipantIdentifier (@Nullable final String sScheme, @Nullable final String sValue) + public BDXR2ParticipantIdentifier createParticipantIdentifier (@Nullable final String sScheme, + @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isParticipantIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); - if (isParticipantIdentifierSchemeValid (sRealScheme) && isParticipantIdentifierValueValid (sRealValue)) + final String sRealValue = nullNotEmpty (isParticipantIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); + if (isParticipantIdentifierSchemeValid (sRealScheme) && isParticipantIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR2ParticipantIdentifier (sRealScheme, sRealValue); return null; } @@ -120,7 +125,7 @@ public boolean isProcessIdentifierCaseInsensitive (@Nullable final String sSchem } @Override - public boolean isProcessIdentifierValueValid (final String sValue) + public boolean isProcessIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return BDXR2IdentifierHelper.isValidIdentifierValue (sValue); } @@ -129,9 +134,10 @@ public boolean isProcessIdentifierValueValid (final String sValue) public BDXR2ProcessIdentifier createProcessIdentifier (@Nullable final String sScheme, @Nullable final String sValue) { final String sRealScheme = nullNotEmpty (sScheme); - final String sRealValue = nullNotEmpty (isProcessIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) : sValue); + final String sRealValue = nullNotEmpty (isProcessIdentifierCaseInsensitive (sRealScheme) ? getUnifiedValue (sValue) + : sValue); - if (isProcessIdentifierSchemeValid (sRealScheme) && isProcessIdentifierValueValid (sRealValue)) + if (isProcessIdentifierSchemeValid (sRealScheme) && isProcessIdentifierValueValid (sRealScheme, sRealValue)) return new BDXR2ProcessIdentifier (sRealScheme, sRealValue); return null; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/IDocumentTypeIdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/IDocumentTypeIdentifierFactory.java index 2617ebbf..e8be0138 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/IDocumentTypeIdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/IDocumentTypeIdentifierFactory.java @@ -84,7 +84,26 @@ default boolean isDocumentTypeIdentifierSchemeValid (@Nullable final String sSch * @return true if the document type identifier value is valid, * false otherwise */ + @Deprecated (forRemoval = true, since = "9.1.1") default boolean isDocumentTypeIdentifierValueValid (@Nullable final String sValue) + { + return isDocumentTypeIdentifierValueValid (null, sValue); + } + + /** + * Check if the passed document type identifier value is valid for the + * provided scheme. + * + * @param sScheme + * The document type identifier scheme of the value to be checked. + * @param sValue + * The document type identifier value to be checked (without the + * scheme). May be null. + * @return true if the document type identifier value is valid + * for the provided scheme, false otherwise + * @since 9.1.1 + */ + default boolean isDocumentTypeIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return true; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/IParticipantIdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/IParticipantIdentifierFactory.java index 340f675e..889eab4b 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/IParticipantIdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/IParticipantIdentifierFactory.java @@ -84,7 +84,26 @@ default boolean isParticipantIdentifierSchemeValid (@Nullable final String sSche * @return true if the participant identifier value is valid, * false otherwise. */ + @Deprecated (forRemoval = true, since = "9.1.1") default boolean isParticipantIdentifierValueValid (@Nullable final String sValue) + { + return isParticipantIdentifierValueValid (null, sValue); + } + + /** + * Check if the passed participant identifier value is valid. + * + * @param sScheme + * The scheme of the participant identifier value to be checked. May be + * null. + * @param sValue + * The participant identifier value to be checked (without the scheme). + * May be null. + * @return true if the participant identifier value is valid, + * false otherwise. + * @since 9.1.1 + */ + default boolean isParticipantIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return true; } @@ -158,6 +177,7 @@ default IParticipantIdentifier parseParticipantIdentifier (@Nullable final Strin @Nullable default IParticipantIdentifier getClone (@Nullable final IParticipantIdentifier aParticipantID) { - return aParticipantID == null ? null : createParticipantIdentifier (aParticipantID.getScheme (), aParticipantID.getValue ()); + return aParticipantID == null ? null : createParticipantIdentifier (aParticipantID.getScheme (), + aParticipantID.getValue ()); } } diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/IProcessIdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/IProcessIdentifierFactory.java index 3d38680a..686e0e28 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/IProcessIdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/IProcessIdentifierFactory.java @@ -78,12 +78,31 @@ default boolean isProcessIdentifierSchemeValid (@Nullable final String sScheme) * Check if the passed process identifier value is valid. * * @param sValue - * The document type identifier value to be checked (without the - * scheme). May be null. - * @return true if the document type identifier value is valid, + * The process identifier value to be checked (without the scheme). May + * be null. + * @return true if the process identifier value is valid, * false otherwise */ + @Deprecated (forRemoval = true, since = "9.1.1") default boolean isProcessIdentifierValueValid (@Nullable final String sValue) + { + return isProcessIdentifierValueValid (null, sValue); + } + + /** + * Check if the passed process identifier value is valid. + * + * @param sScheme + * The process identifier scheme of the value to be checked. May be + * null. + * @param sValue + * The process identifier value to be checked (without the scheme). May + * be null. + * @return true if the process identifier value is valid, + * false otherwise + * @since 9.1.1 + */ + default boolean isProcessIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { return true; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/factory/PeppolIdentifierFactory.java b/peppol-id/src/main/java/com/helger/peppolid/factory/PeppolIdentifierFactory.java index 28008137..da019d6c 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/factory/PeppolIdentifierFactory.java +++ b/peppol-id/src/main/java/com/helger/peppolid/factory/PeppolIdentifierFactory.java @@ -65,34 +65,52 @@ public boolean isDocumentTypeIdentifierSchemeValid (@Nullable final String sSche return PeppolIdentifierHelper.isValidIdentifierScheme (sScheme); } - private static boolean _isForbiddenCustomizationIDChar (final char c) + private static boolean _isForbiddenCustomizationIDCharBusdoxDocidQns (final char c) { return c == '*' || c == 9 || c == 10 || c == 11 || c == 12 || c == 13 || c == ' ' || c == 133 || c == 160; } - public static boolean isValidCustomizationID (@Nullable final String s) + public static boolean isValidCustomizationIDBusdoxDocidQns (@Nullable final String s) { if (StringHelper.hasNoText (s)) return false; - // POLICY 17 (applies identical for busdox-docid-qns and - // peppol-doctype-wildcard) + // POLICY 17 (applies identical only to busdox-docid-qns) for (final char c : s.toCharArray ()) - if (_isForbiddenCustomizationIDChar (c)) + if (_isForbiddenCustomizationIDCharBusdoxDocidQns (c)) + return false; + + return true; + } + + private static boolean _isForbiddenCustomizationIDCharPeppolDoctypeWildcard (final char c) + { + // "*" is allowed + return c == 9 || c == 10 || c == 11 || c == 12 || c == 13 || c == ' ' || c == 133 || c == 160; + } + + public static boolean isValidCustomizationIDPeppolDoctypeWildcard (@Nullable final String s) + { + if (StringHelper.hasNoText (s)) + return false; + + // chapter 5.1.2 + for (final char c : s.toCharArray ()) + if (_isForbiddenCustomizationIDCharPeppolDoctypeWildcard (c)) return false; return true; } @Override - public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sValue) + public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { if (sValue == null) return false; final int nLength = sValue.length (); - // POLICY 1 + // POLICY 1 - general rules // at least 1 char if (nLength == 0) return false; @@ -107,11 +125,24 @@ public boolean isDocumentTypeIdentifierValueValid (@Nullable final String sValue try { final IPeppolDocumentTypeIdentifierParts aParts = PeppolDocumentTypeIdentifierParts.extractFromString (sValue); - final String sCustomizationID = aParts.getCustomizationID (); - // POLICY 17 - if (!isValidCustomizationID (sCustomizationID)) - return false; + if (sScheme != null) + switch (sScheme) + { + case PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS: + // POLICY 17 + if (!isValidCustomizationIDBusdoxDocidQns (aParts.getCustomizationID ())) + return false; + break; + case PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_PEPPOL_DOCTYPE_WILDCARD: + // Chapter 5.1.2 + if (!isValidCustomizationIDPeppolDoctypeWildcard (aParts.getCustomizationID ())) + return false; + break; + default: + // Ignore - no special Peppol rules + } + } catch (final IllegalArgumentException ex) { @@ -166,12 +197,6 @@ public boolean isParticipantIdentifierCaseInsensitive (@Nullable final String sS * note that the regular expression is applied case insensitive!
* This limitation is important, because the participant identifier scheme is * directly encoded into the SML DNS name record. - * - * @param sScheme - * The scheme to check. May be null. - * @return true if the passed scheme is a valid participant - * identifier scheme, false otherwise. - * @see PeppolIdentifierHelper#isValidIdentifierScheme(String) */ @Override public boolean isParticipantIdentifierSchemeValid (@Nullable final String sScheme) @@ -189,15 +214,9 @@ public boolean isParticipantIdentifierSchemeValid (@Nullable final String sSchem * {@link PeppolIdentifierHelper#MAX_PARTICIPANT_VALUE_LENGTH} characters. * Also it must be US ASCII encoded. This check method considers only the * value and not the identifier scheme! - * - * @param sValue - * The participant identifier value to be checked (without the scheme). - * May be null. - * @return true if the participant identifier value is valid, - * false otherwise. */ @Override - public boolean isParticipantIdentifierValueValid (@Nullable final String sValue) + public boolean isParticipantIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { if (sValue == null) return false; @@ -213,6 +232,11 @@ public boolean isParticipantIdentifierValueValid (@Nullable final String sValue) if (nLength > PeppolIdentifierHelper.MAX_PARTICIPANT_VALUE_LENGTH) return false; + // Check if the value is ISO-8859-1 encoded + if (!PeppolIdentifierHelper.areCharsetChecksDisabled ()) + if (!StandardCharsets.ISO_8859_1.newEncoder ().canEncode (sValue)) + return false; + // Check if the separator between identifier issuing agency and value is // present - can only be done if the default scheme is present // Also does not work in certain representations when the numeric scheme is @@ -221,11 +245,6 @@ public boolean isParticipantIdentifierValueValid (@Nullable final String sValue) if (sValue.indexOf (':') < 0) return false; - // Check if the value is ISO-8859-1 encoded - if (!PeppolIdentifierHelper.areCharsetChecksDisabled ()) - if (!StandardCharsets.ISO_8859_1.newEncoder ().canEncode (sValue)) - return false; - return true; } @@ -258,7 +277,7 @@ public boolean isProcessIdentifierSchemeValid (@Nullable final String sScheme) } @Override - public boolean isProcessIdentifierValueValid (@Nullable final String sValue) + public boolean isProcessIdentifierValueValid (@Nullable final String sScheme, @Nullable final String sValue) { final int nLength = StringHelper.getLength (sValue); diff --git a/peppol-id/src/main/java/com/helger/peppolid/peppol/doctype/PeppolDocumentTypeIdentifier.java b/peppol-id/src/main/java/com/helger/peppolid/peppol/doctype/PeppolDocumentTypeIdentifier.java index c837ba78..c7e0c0e9 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/peppol/doctype/PeppolDocumentTypeIdentifier.java +++ b/peppol-id/src/main/java/com/helger/peppolid/peppol/doctype/PeppolDocumentTypeIdentifier.java @@ -54,10 +54,14 @@ private static String _verifyScheme (@Nullable final String sScheme) } @Nonnull - private static String _verifyValue (@Nonnull final String sValue) + private static String _verifyValue (@Nullable final String sScheme, @Nonnull final String sValue) { - if (!PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (sValue)) - throw new IllegalArgumentException ("Peppol Document Type identifier value '" + sValue + "' is invalid!"); + if (!PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (sScheme, sValue)) + throw new IllegalArgumentException ("Peppol Document Type identifier value '" + + sValue + + "' is invalid for scheme '" + + sScheme + + "'!"); return sValue; } @@ -70,7 +74,7 @@ public PeppolDocumentTypeIdentifier (@Nonnull final IDocumentTypeIdentifier aIde @DevelopersNote ("Don't invoke manually. Always use the IdentifierFactory!") public PeppolDocumentTypeIdentifier (@Nullable final String sScheme, @Nonnull final String sValue) { - this (true, _verifyScheme (sScheme), _verifyValue (sValue)); + this (true, _verifyScheme (sScheme), _verifyValue (sScheme, sValue)); } /** @@ -84,7 +88,9 @@ public PeppolDocumentTypeIdentifier (@Nullable final String sScheme, @Nonnull fi * @param sValue * Identifier value. May not be null. */ - protected PeppolDocumentTypeIdentifier (final boolean bVerified, @Nonnull final String sScheme, @Nonnull final String sValue) + protected PeppolDocumentTypeIdentifier (final boolean bVerified, + @Nonnull final String sScheme, + @Nonnull final String sValue) { setScheme (sScheme); setValue (sValue); @@ -153,13 +159,15 @@ public int hashCode () * @return The document type identifier or null if any of the * parts is invalid. * @see PeppolIdentifierFactory#isDocumentTypeIdentifierSchemeValid(String) - * @see PeppolIdentifierFactory#isDocumentTypeIdentifierValueValid(String) + * @see PeppolIdentifierFactory#isDocumentTypeIdentifierValueValid(String, + * String) */ @Nullable - public static PeppolDocumentTypeIdentifier createIfValid (@Nullable final String sScheme, @Nullable final String sValue) + public static PeppolDocumentTypeIdentifier createIfValid (@Nullable final String sScheme, + @Nullable final String sValue) { if (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierSchemeValid (sScheme) && - PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (sValue)) + PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (sScheme, sValue)) return new PeppolDocumentTypeIdentifier (true, sScheme, sValue); return null; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/peppol/participant/PeppolParticipantIdentifier.java b/peppol-id/src/main/java/com/helger/peppolid/peppol/participant/PeppolParticipantIdentifier.java index 871205de..b6d3ba2e 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/peppol/participant/PeppolParticipantIdentifier.java +++ b/peppol-id/src/main/java/com/helger/peppolid/peppol/participant/PeppolParticipantIdentifier.java @@ -59,10 +59,14 @@ private static String _verifyScheme (@Nullable final String sScheme) } @Nonnull - private static String _verifyValue (@Nonnull final String sValue) + private static String _verifyValue (@Nullable final String sScheme, @Nonnull final String sValue) { - if (!PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (sValue)) - throw new IllegalArgumentException ("Peppol Participant identifier value '" + sValue + "' is invalid!"); + if (!PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (sScheme, sValue)) + throw new IllegalArgumentException ("Peppol Participant identifier value '" + + sValue + + "' is invalid for scheme '" + + sScheme + + "'!"); return sValue; } @@ -85,7 +89,7 @@ public PeppolParticipantIdentifier (@Nonnull final IParticipantIdentifier aIdent @DevelopersNote ("Don't invoke manually. Always use the IdentifierFactory!") public PeppolParticipantIdentifier (@Nullable final String sScheme, @Nonnull final String sValue) { - this (true, _verifyScheme (sScheme), _verifyValue (sValue)); + this (true, _verifyScheme (sScheme), _verifyValue (sScheme, sValue)); } /** @@ -99,7 +103,9 @@ public PeppolParticipantIdentifier (@Nullable final String sScheme, @Nonnull fin * @param sValue * Identifier value. May not be null. */ - protected PeppolParticipantIdentifier (final boolean bVerified, @Nonnull final String sScheme, @Nonnull final String sValue) + protected PeppolParticipantIdentifier (final boolean bVerified, + @Nonnull final String sScheme, + @Nonnull final String sValue) { setScheme (sScheme); setValue (sValue); @@ -208,10 +214,11 @@ public int hashCode () * @see PeppolIdentifierFactory#isParticipantIdentifierValueValid(String) */ @Nullable - public static PeppolParticipantIdentifier createIfValid (@Nullable final String sScheme, @Nullable final String sValue) + public static PeppolParticipantIdentifier createIfValid (@Nullable final String sScheme, + @Nullable final String sValue) { if (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierSchemeValid (sScheme) && - PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (sValue)) + PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (sScheme, sValue)) return new PeppolParticipantIdentifier (true, sScheme, sValue); return null; } diff --git a/peppol-id/src/main/java/com/helger/peppolid/peppol/process/PeppolProcessIdentifier.java b/peppol-id/src/main/java/com/helger/peppolid/peppol/process/PeppolProcessIdentifier.java index 68758a4d..3c1d13c9 100644 --- a/peppol-id/src/main/java/com/helger/peppolid/peppol/process/PeppolProcessIdentifier.java +++ b/peppol-id/src/main/java/com/helger/peppolid/peppol/process/PeppolProcessIdentifier.java @@ -55,10 +55,14 @@ private static String _verifyScheme (@Nullable final String sScheme) } @Nonnull - private static String _verifyValue (@Nonnull final String sValue) + private static String _verifyValue (@Nullable final String sScheme, @Nonnull final String sValue) { - if (!PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (sValue)) - throw new IllegalArgumentException ("Peppol Process identifier value '" + sValue + "' is invalid!"); + if (!PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (sScheme, sValue)) + throw new IllegalArgumentException ("Peppol Process identifier value '" + + sValue + + "' is invalid for scheme '" + + sScheme + + "!"); return sValue; } @@ -71,7 +75,7 @@ public PeppolProcessIdentifier (@Nonnull final IProcessIdentifier aIdentifier) @DevelopersNote ("Don't invoke manually. Always use the IdentifierFactory!") public PeppolProcessIdentifier (@Nonnull final String sScheme, @Nonnull final String sValue) { - this (true, _verifyScheme (sScheme), _verifyValue (sValue)); + this (true, _verifyScheme (sScheme), _verifyValue (sScheme, sValue)); } /** @@ -85,7 +89,9 @@ public PeppolProcessIdentifier (@Nonnull final String sScheme, @Nonnull final St * @param sValue * Identifier value. May not be null. */ - protected PeppolProcessIdentifier (final boolean bVerified, @Nonnull final String sScheme, @Nonnull final String sValue) + protected PeppolProcessIdentifier (final boolean bVerified, + @Nonnull final String sScheme, + @Nonnull final String sValue) { setScheme (sScheme); setValue (sValue); @@ -140,13 +146,13 @@ public int hashCode () * @return The process identifier or null if any of the parts is * invalid. * @see PeppolIdentifierFactory#isProcessIdentifierSchemeValid(String) - * @see PeppolIdentifierFactory#isProcessIdentifierValueValid(String) + * @see PeppolIdentifierFactory#isProcessIdentifierValueValid(String, String) */ @Nullable public static PeppolProcessIdentifier createIfValid (@Nullable final String sScheme, @Nullable final String sValue) { if (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierSchemeValid (sScheme) && - PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (sValue)) + PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (sScheme, sValue)) return new PeppolProcessIdentifier (true, sScheme, sValue); return null; } diff --git a/peppol-id/src/test/java/com/helger/peppolid/factory/PeppolIdentifierFactoryTest.java b/peppol-id/src/test/java/com/helger/peppolid/factory/PeppolIdentifierFactoryTest.java index 9e70ea26..0adea929 100644 --- a/peppol-id/src/test/java/com/helger/peppolid/factory/PeppolIdentifierFactoryTest.java +++ b/peppol-id/src/test/java/com/helger/peppolid/factory/PeppolIdentifierFactoryTest.java @@ -65,35 +65,54 @@ public void testIsValidParticipantIdentifierScheme () @Test public void testIsValidParticipantIdentifierValue () { - assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (null)); - assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("")); - - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9908:976098897")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9908:976098897 ")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("990:976098897")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("990976098897")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9909:976098896")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9908:976098896")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9956:DE:EPROC:BMIEVG:BeschA")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid ("9906:02419170044_01")); - - assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (VALUE_MAX_LENGTH)); - assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (VALUE_MAX_LENGTH_PLUS_1)); + assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + null)); + assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "")); + + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9908:976098897")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9908:976098897 ")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "990:976098897")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "990976098897")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9909:976098896")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9908:976098896")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9956:DE:EPROC:BMIEVG:BeschA")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + "9906:02419170044_01")); + + assertTrue (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + VALUE_MAX_LENGTH)); + assertFalse (PeppolIdentifierFactory.INSTANCE.isParticipantIdentifierValueValid (PeppolIdentifierHelper.PARTICIPANT_SCHEME_ISO6523_ACTORID_UPIS, + VALUE_MAX_LENGTH_PLUS_1)); } @Test public void testIsValidProcessIdentifierValue () { - assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (null)); - assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid ("")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + null)); + assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + "")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid ("proc1")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid ("proc2")); - assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid ("proc2 ")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + "proc1")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + "proc2")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + "proc2 ")); - assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (StringHelper.getRepeated ('a', + assertTrue (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + StringHelper.getRepeated ('a', PeppolIdentifierHelper.MAX_PROCESS_VALUE_LENGTH))); - assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (StringHelper.getRepeated ('a', + assertFalse (PeppolIdentifierFactory.INSTANCE.isProcessIdentifierValueValid (PeppolIdentifierHelper.PROCESS_SCHEME_CENBII_PROCID_UBL, + StringHelper.getRepeated ('a', PeppolIdentifierHelper.MAX_PROCESS_VALUE_LENGTH + 1))); } @@ -101,17 +120,34 @@ public void testIsValidProcessIdentifierValue () @Test public void testIsValidDocumentTypeIdentifierValue () { - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (null)); - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid ("")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + null)); + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + "")); - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid ("invoice")); - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid ("order ")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + "invoice")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_PEPPOL_DOCTYPE_WILDCARD, + "invoice")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid ("bla", "invoice")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (null, "invoice")); + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + "order ")); - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (StringHelper.getRepeated ('a', + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + StringHelper.getRepeated ('a', PeppolIdentifierHelper.MAX_DOCUMENT_TYPE_VALUE_LENGTH))); - assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (StringHelper.getRepeated ('a', + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + StringHelper.getRepeated ('a', PeppolIdentifierHelper.MAX_DOCUMENT_TYPE_VALUE_LENGTH + 1))); - assertTrue (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid ("urn:rootnamespace::localelement##customizationid::version")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + "urn:rootnamespace::localelement##customizationid::version")); + + // * only valid for peppol-doctype-wildcard + assertFalse (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_BUSDOX_DOCID_QNS, + "urn:rootnamespace::localelement##customizationid*::version")); + assertTrue (PeppolIdentifierFactory.INSTANCE.isDocumentTypeIdentifierValueValid (PeppolIdentifierHelper.DOCUMENT_TYPE_SCHEME_PEPPOL_DOCTYPE_WILDCARD, + "urn:rootnamespace::localelement##customizationid*::version")); } }