diff --git a/phase4-dbnalliance-client/src/main/java/com/helger/phase4/dbnalliance/Phase4DBNAllianceSender.java b/phase4-dbnalliance-client/src/main/java/com/helger/phase4/dbnalliance/Phase4DBNAllianceSender.java index f4b33ebc0..ff3662395 100644 --- a/phase4-dbnalliance-client/src/main/java/com/helger/phase4/dbnalliance/Phase4DBNAllianceSender.java +++ b/phase4-dbnalliance-client/src/main/java/com/helger/phase4/dbnalliance/Phase4DBNAllianceSender.java @@ -86,12 +86,12 @@ private Phase4DBNAllianceSender () {} @Nullable - private static XHE10XHEType _createXHE (@Nonnull final IParticipantIdentifier aSenderID, - @Nonnull final IParticipantIdentifier aReceiverID, - @Nonnull final IDocumentTypeIdentifier aDocTypeID, - @Nonnull final IProcessIdentifier aProcID, - @Nonnull final Element aPayloadElement, - final boolean bClonePayloadElement) + private static XHE10XHEType _createDBNAllianceXHE (@Nonnull final IParticipantIdentifier aSenderID, + @Nonnull final IParticipantIdentifier aReceiverID, + @Nonnull final IDocumentTypeIdentifier aDocTypeID, + @Nonnull final IProcessIdentifier aProcID, + @Nonnull final Element aPayloadElement, + final boolean bClonePayloadElement) throws Phase4DBNAllianceException { final DBNAllianceXHEData aData = new DBNAllianceXHEData (IF); aData.setFromParty (aSenderID.getScheme (), aSenderID.getValue ()); @@ -116,7 +116,7 @@ private static XHE10XHEType _createXHE (@Nonnull final IParticipantIdentifier aS // check with logging if (!aData.areAllFieldsSet (true)) - throw new IllegalArgumentException ("The DBNAlliance XHE data is incomplete. See logs for details."); + throw new Phase4DBNAllianceException ("The DBNAlliance XHE data is incomplete. See logs for details."); return DBNAllianceXHEDocumentWriter.createExchangeHeaderEnvelope (aData); } @@ -533,9 +533,28 @@ public DBNAllianceUserMessageBuilder () * The payload element to be used. They payload element MUST have a * namespace URI. May not be null. * @return this for chaining + * @deprecated in favour of {@link #payloadElement(Element)} */ @Nonnull + @Deprecated (forRemoval = true, since = "2.8.6") public DBNAllianceUserMessageBuilder payload (@Nonnull final Element aPayloadElement) + { + return payloadElement (aPayloadElement); + } + + /** + * Set the payload element to be used, if it is available as a parsed DOM + * element. Internally the DOM element will be cloned before sending it out. + * If this method is called, it overwrites any other explicitly set payload. + * + * @param aPayloadElement + * The payload element to be used. They payload element MUST have a + * namespace URI. May not be null. + * @return this for chaining + * @since 2.8.6 + */ + @Nonnull + public DBNAllianceUserMessageBuilder payloadElement (@Nonnull final Element aPayloadElement) { ValueEnforcer.notNull (aPayloadElement, "Payload"); ValueEnforcer.notEmpty (aPayloadElement.getNamespaceURI (), "Payload.NamespaceURI"); @@ -547,55 +566,58 @@ public DBNAllianceUserMessageBuilder payload (@Nonnull final Element aPayloadEle @OverridingMethodsMustInvokeSuper protected ESuccess finishFields () throws Phase4Exception { + // Perform SMP lookup + if (super.finishFields ().isFailure ()) + return ESuccess.FAILURE; + // Ensure a DOM element is present - final Element aPayloadElement; - final boolean bClonePayloadElement; if (m_aPayloadElement != null) { + // Ensure only one payload is present + if (m_aPayload != null) + throw new Phase4DBNAllianceException ("You cannot provide a payload element and a payload together - please pick one."); + // Already provided as a DOM element - aPayloadElement = m_aPayloadElement; - bClonePayloadElement = true; + final Element aPayloadElement = m_aPayloadElement; + + // Consistency check + if (CXHE10.NAMESPACE_URI_XHE.equals (aPayloadElement.getNamespaceURI ())) + throw new Phase4DBNAllianceException ("You cannot set an eXchange Header Envelope as the payload for the regular builder. The XHE is created automatically inside of this builder."); + + // Created SBDH + if (LOGGER.isDebugEnabled ()) + LOGGER.debug ("Start creating XHE for AS4 message"); + + final boolean bClonePayloadElement = true; + final XHE10XHEType aXHE = _createDBNAllianceXHE (m_aSenderID, + m_aReceiverID, + m_aDocTypeID, + m_aProcessID, + aPayloadElement, + bClonePayloadElement); + if (aXHE == null) + { + // A log message was already provided + return ESuccess.FAILURE; + } + + final byte [] aXHEBytes = new XHE10Marshaller ().getAsBytes (aXHE); + + // Now we have the main payload + payload (AS4OutgoingAttachment.builder () + .data (aXHEBytes) + .compressionGZIP () + .mimeTypeXML () + .charset (StandardCharsets.UTF_8)); } - else - throw new IllegalStateException ("Unexpected - element is not present"); - - // Consistency check - if (CXHE10.NAMESPACE_URI_XHE.equals (aPayloadElement.getNamespaceURI ())) - throw new Phase4DBNAllianceException ("You cannot set a Exchange Header Envelope as the payload for the regular builder. The XHE is created automatically inside of this builder."); - - // Optional payload validation - // _validatePayload (aPayloadElement, m_aVESRegistry, m_aVESID, - // m_aValidationResultHandler); - - // Perform SMP lookup - if (super.finishFields ().isFailure ()) - return ESuccess.FAILURE; - // Created SBDH - if (LOGGER.isDebugEnabled ()) - LOGGER.debug ("Start creating SBDH for AS4 message"); - - final XHE10XHEType aXHE = _createXHE (m_aSenderID, - m_aReceiverID, - m_aDocTypeID, - m_aProcessID, - aPayloadElement, - bClonePayloadElement); - if (aXHE == null) + // Make sure a payload is present + if (m_aPayload == null) { - // A log message was already provided + LOGGER.error ("No payload was provided to the DBNAlliance UserMessage builder"); return ESuccess.FAILURE; } - final byte [] aXHEBytes = new XHE10Marshaller ().getAsBytes (aXHE); - - // Now we have the main payload - payload (AS4OutgoingAttachment.builder () - .data (aXHEBytes) - .mimeTypeXML () - .compressionGZIP () - .charset (StandardCharsets.UTF_8)); - return ESuccess.SUCCESS; } } diff --git a/phase4-dbnalliance-client/src/test/java/com/helger/phase4/dbnalliance/MainPhase4DBNAllianceSenderExample.java b/phase4-dbnalliance-client/src/test/java/com/helger/phase4/dbnalliance/MainPhase4DBNAllianceSenderExample.java index 72d9619ca..eb525d1f7 100644 --- a/phase4-dbnalliance-client/src/test/java/com/helger/phase4/dbnalliance/MainPhase4DBNAllianceSenderExample.java +++ b/phase4-dbnalliance-client/src/test/java/com/helger/phase4/dbnalliance/MainPhase4DBNAllianceSenderExample.java @@ -16,13 +16,14 @@ */ package com.helger.phase4.dbnalliance; -import com.helger.peppolid.bdxr.smp2.participant.BDXR2ParticipantIdentifier; -import com.helger.peppolid.factory.SimpleIdentifierFactory; import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; +import com.helger.peppolid.bdxr.smp2.participant.BDXR2ParticipantIdentifier; +import com.helger.peppolid.factory.SimpleIdentifierFactory; import com.helger.phase4.dump.AS4DumpManager; import com.helger.phase4.dump.AS4IncomingDumperFileBased; import com.helger.phase4.dump.AS4OutgoingDumperFileBased; @@ -33,7 +34,6 @@ import com.helger.smpclient.url.DBNAURLProviderSMP; import com.helger.web.scope.mgr.WebScopeManager; import com.helger.xml.serialize.read.DOMReader; -import org.w3c.dom.Element; public class MainPhase4DBNAllianceSenderExample { @@ -52,24 +52,28 @@ public static void main (final String [] args) { // Read XML payload to send final Element aPayloadElement = DOMReader.readXMLDOM (new File ("src/test/resources/external/examples/base-example.xml")) - .getDocumentElement (); + .getDocumentElement (); if (aPayloadElement == null) throw new IllegalStateException ("Failed to read file to be send"); - // Start configuring here - final BDXR2ParticipantIdentifier aReceiver = Phase4DBNAllianceSender.IF.createParticipantIdentifier ("us:ein", "365060483"); - BDXR2ClientReadOnly aSMPClient = new BDXR2ClientReadOnly (DBNAURLProviderSMP.INSTANCE.getSMPURIOfParticipant (aReceiver, - EDBNASML.TEST.getZoneName())); + // Start configuring here + final BDXR2ParticipantIdentifier aReceiver = Phase4DBNAllianceSender.IF.createParticipantIdentifier ("us:ein", + "365060483"); + final BDXR2ClientReadOnly aSMPClient = new BDXR2ClientReadOnly (DBNAURLProviderSMP.INSTANCE.getSMPURIOfParticipant (aReceiver, + EDBNASML.TEST.getZoneName ())); aSMPClient.setVerifySignature (false); - + final EAS4UserMessageSendResult eResult; eResult = Phase4DBNAllianceSender.builder () - .documentTypeID (SimpleIdentifierFactory.INSTANCE.createDocumentTypeIdentifier ("bdx-docid-qns", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##DBNAlliance-1.0-data-Core")) - .processID (Phase4DBNAllianceSender.IF.createProcessIdentifier(null, "bdx:noprocess")) - .senderParticipantID (Phase4DBNAllianceSender.IF.createParticipantIdentifier ("us:ein", "365060483")) + .documentTypeID (SimpleIdentifierFactory.INSTANCE.createDocumentTypeIdentifier ("bdx-docid-qns", + "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##DBNAlliance-1.0-data-Core")) + .processID (Phase4DBNAllianceSender.IF.createProcessIdentifier (null, + "bdx:noprocess")) + .senderParticipantID (Phase4DBNAllianceSender.IF.createParticipantIdentifier ("us:ein", + "365060483")) .receiverParticipantID (aReceiver) - .fromPartyID("365060483") - .payload (aPayloadElement) + .fromPartyID ("365060483") + .payloadElement (aPayloadElement) .smpClient (aSMPClient) .sendMessageAndCheckForReceipt (); LOGGER.info ("DBNAlliance send result: " + eResult); diff --git a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java index b8570b539..0df2f217b 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java +++ b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4MessageBuilder.java @@ -853,10 +853,11 @@ protected ESuccess finishFields () throws Phase4Exception } /** - * Check if all required fields of the builder are set. + * Check if all mandatory fields are set. This method is called after + * {@link #finishFields()} and before {@link #customizeBeforeSending()} * - * @return true if all required fields are set, - * false if not. + * @return true if all mandatory fields are set, and sending can + * continue. */ @OverridingMethodsMustInvokeSuper public boolean isEveryRequiredFieldSet () @@ -912,7 +913,8 @@ public boolean isEveryRequiredFieldSet () /** * Internal method that is invoked after the required fields are checked but * before sending takes place. This is e.g. the perfect place to add custom - * message properties. This is called after {@link #isEveryRequiredFieldSet()} + * message properties. This method is called after + * {@link #isEveryRequiredFieldSet()} and before {@link #mainSendMessage()}. * * @throws Phase4Exception * if something goes wrong diff --git a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4UserMessageBuilderMIMEPayload.java b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4UserMessageBuilderMIMEPayload.java index a10a317e6..e45d4e26c 100644 --- a/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4UserMessageBuilderMIMEPayload.java +++ b/phase4-lib/src/main/java/com/helger/phase4/sender/AbstractAS4UserMessageBuilderMIMEPayload.java @@ -39,8 +39,8 @@ import com.helger.phase4.util.Phase4Exception; /** - * Abstract builder base class for a user messages that put the payload in a - * MIME part. + * Abstract builder base class for a user messages that puts also the main + * payload in a single MIME part and NOT in the SOAP body. * * @author Philip Helger * @param @@ -64,6 +64,8 @@ protected AbstractAS4UserMessageBuilderMIMEPayload () {} /** + * <<<<<<< HEAD + * * @return The currently set outgoing attachment payload. May be * null. * @since 2.5.0 @@ -75,7 +77,8 @@ public final AS4OutgoingAttachment payload () } /** - * Set the payload to be send out. + * Set the payload to be send out. The payload is translated into the first + * attachment to the user message. * * @param aBuilder * The payload builder to be used. May be null. @@ -182,7 +185,7 @@ protected final void mainSendMessage () throws Phase4Exception } } - // No payload - only one attachment + // No payload in SOAP - only one attachment aUserMsg.setPayload (null); // Add main attachment