Skip to content

Commit

Permalink
Improved docs
Browse files Browse the repository at this point in the history
  • Loading branch information
phax committed Dec 19, 2024
1 parent 98dac0c commit cbc7024
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 15 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ They depend on several other libraries so I suggest you are going for the Maven

# News and noteworthy

* v9.6.2 - work in progress
* Reworked the Peppol Document Type Identifier data model to handle non-XML syntax specific IDs as well
* v9.6.1 - 2024-12-16
* Added new class `PeppolNaptrURLProvider`
* Fixed the Peppol Directory URL of `EPeppolNetwork.PRODUCTION`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
public interface IPeppolDocumentTypeIdentifierParts extends IPeppolGenericDocumentTypeIdentifierParts
{
/**
* Separator between namespace URI and local name
* Separator between XML root element namespace URI and local name
*/
String NAMESPACE_SEPARATOR = "::";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
*/
package com.helger.peppolid.peppol.doctype;

import java.util.function.BiConsumer;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.Nonempty;
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.commons.string.StringHelper;
import com.helger.commons.string.ToStringGenerator;
import com.helger.commons.wrapper.Wrapper;
import com.helger.peppolid.IDocumentTypeIdentifier;

/**
Expand All @@ -39,6 +43,20 @@ public class PeppolDocumentTypeIdentifierParts extends PeppolGenericDocumentType
private final String m_sRootNS;
private final String m_sLocalName;

/**
* Convert the XML specific syntax elements back to a single syntax specific
* ID
*
* @param sRootNS
* The XML root element namespace URI. May neither be <code>null</code>
* nor empty.
* @param sLocalName
* The XML root element local name. May neither be <code>null</code>
* nor empty.
* @return The combination of <code>rootNS + :: + localName</code>
*/
@Nonnull
@Nonempty
public static String createSyntaxSpecificID (@Nonnull @Nonempty final String sRootNS,
@Nonnull @Nonempty final String sLocalName)
{
Expand Down Expand Up @@ -95,22 +113,37 @@ public String toString ()
.getToString ();
}

public static boolean isSyntaxSpecificIDLookingLikeXML (@Nullable final String sSyntaxSpecificID)
{
if (StringHelper.hasText (sSyntaxSpecificID))
{
final int nIndex = sSyntaxSpecificID.indexOf (NAMESPACE_SEPARATOR);
if (nIndex >= 0)
{
// It's contains the separator and it's not the start and not the end
return nIndex > 0 && nIndex < sSyntaxSpecificID.length () - NAMESPACE_SEPARATOR.length ();
}
}
return false;
}

/**
* Parse an OpenPeppol Document Type Identifier using the XML syntax.
* Split the provided syntax specific ID into the XML root element namespace
* URI and the XML root element local name.
*
* @param sDocTypeIDValue
* The document identifier value (without the scheme) to be split. May
* neither be <code>null</code> nor empty.
* @return The non-<code>null</code> Peppol identifier parts
* @throws IllegalArgumentException
* if the passed document identifier value does not match the
* specifications
* @param sSyntaxSpecificID
* The syntax specific ID to parse. May neither be <code>null</code>
* nor empty.
* @param aResultConsumer
* The consumer that takes root namespace URI and local name as a
* callback.
* @since 9.6.2
*/
@Nonnull
public static PeppolDocumentTypeIdentifierParts extractFromString (@Nonnull @Nonempty final String sDocTypeIDValue)
public static void extractXMLSyntaxSpecificID (@Nonnull @Nonempty final String sSyntaxSpecificID,
@Nonnull final BiConsumer <String, String> aResultConsumer)
{
final PeppolGenericDocumentTypeIdentifierParts aGenericParts = PeppolGenericDocumentTypeIdentifierParts.extractFromString (sDocTypeIDValue);
final String sSyntaxSpecificID = aGenericParts.getSyntaxSpecificID ();
ValueEnforcer.notEmpty (sSyntaxSpecificID, "SyntaxSpecificID");
ValueEnforcer.notNull (aResultConsumer, "ResultConsumer");

final ICommonsList <String> aFirst = StringHelper.getExploded (NAMESPACE_SEPARATOR, sSyntaxSpecificID, 2);
if (aFirst.size () < 2)
Expand All @@ -129,8 +162,34 @@ public static PeppolDocumentTypeIdentifierParts extractFromString (@Nonnull @Non
sSyntaxSpecificID +
"' contains an empty local name!");

return new PeppolDocumentTypeIdentifierParts (sRootNS,
sLocalName,
aResultConsumer.accept (sRootNS, sLocalName);
}

/**
* Parse an OpenPeppol Document Type Identifier using the XML syntax.
*
* @param sDocTypeIDValue
* The document identifier value (without the scheme) to be split. May
* neither be <code>null</code> nor empty.
* @return The non-<code>null</code> Peppol identifier parts
* @throws IllegalArgumentException
* if the passed document identifier value does not match the
* specifications
*/
@Nonnull
public static PeppolDocumentTypeIdentifierParts extractFromString (@Nonnull @Nonempty final String sDocTypeIDValue)
{
final PeppolGenericDocumentTypeIdentifierParts aGenericParts = PeppolGenericDocumentTypeIdentifierParts.extractFromString (sDocTypeIDValue);

final Wrapper <String> aRootNS = new Wrapper <> ();
final Wrapper <String> aLocalName = new Wrapper <> ();
extractXMLSyntaxSpecificID (aGenericParts.getSyntaxSpecificID (), (ns, ln) -> {
aRootNS.set (ns);
aLocalName.set (ln);
});

return new PeppolDocumentTypeIdentifierParts (aRootNS.get (),
aLocalName.get (),
aGenericParts.getCustomizationID (),
aGenericParts.getVersion ());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package com.helger.peppolid.peppol.doctype;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
Expand Down Expand Up @@ -181,4 +183,14 @@ public void testList () throws IOException
});
}
}

@Test
public void testIsSyntaxSpecificIDLookingLikeXML ()
{
assertTrue (PeppolDocumentTypeIdentifierParts.isSyntaxSpecificIDLookingLikeXML ("a::b"));
assertTrue (PeppolDocumentTypeIdentifierParts.isSyntaxSpecificIDLookingLikeXML ("root::local"));
assertFalse (PeppolDocumentTypeIdentifierParts.isSyntaxSpecificIDLookingLikeXML ("root:local"));
assertFalse (PeppolDocumentTypeIdentifierParts.isSyntaxSpecificIDLookingLikeXML ("::local"));
assertFalse (PeppolDocumentTypeIdentifierParts.isSyntaxSpecificIDLookingLikeXML ("root::"));
}
}

0 comments on commit cbc7024

Please sign in to comment.