Search in sources :

Example 6 with IMimeType

use of com.helger.commons.mime.IMimeType in project ph-web by phax.

the class MockHttpServletResponse method setContentType.

public void setContentType(@Nullable final String sContentType) {
    m_sContentType = sContentType;
    if (sContentType != null) {
        try {
            final IMimeType aContentType = MimeTypeParser.parseMimeType(sContentType);
            final String sEncoding = MimeTypeHelper.getCharsetNameFromMimeType(aContentType);
            if (sEncoding != null)
                setCharacterEncoding(sEncoding);
        } catch (final MimeTypeParserException ex) {
            LOGGER.warn("Passed content type '" + sContentType + "' cannot be parsed as a MIME type");
        }
    }
}
Also used : IMimeType(com.helger.commons.mime.IMimeType) MimeTypeParserException(com.helger.commons.mime.MimeTypeParserException)

Example 7 with IMimeType

use of com.helger.commons.mime.IMimeType in project phase4 by phax.

the class AS4IncomingHandler method parseAS4Message.

public static void parseAS4Message(@Nonnull final IAS4IncomingAttachmentFactory aIAF, @Nonnull @WillNotClose final AS4ResourceHelper aResHelper, @Nonnull final IAS4IncomingMessageMetadata aMessageMetadata, @Nonnull @WillClose final InputStream aPayloadIS, @Nonnull final HttpHeaderMap aHttpHeaders, @Nonnull final IAS4ParsedMessageCallback aCallback, @Nullable final IAS4IncomingDumper aIncomingDumper) throws Phase4Exception, IOException, MessagingException, WSSecurityException {
    // Determine content type
    final String sContentType = aHttpHeaders.getFirstHeaderValue(CHttpHeader.CONTENT_TYPE);
    if (StringHelper.hasNoText(sContentType))
        throw new Phase4Exception("Content-Type header is missing");
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Received Content-Type string: '" + sContentType + "'");
    final IMimeType aContentType = MimeTypeParser.safeParseMimeType(sContentType);
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Received Content-Type object: " + aContentType);
    if (aContentType == null)
        throw new Phase4Exception("Failed to parse Content-Type '" + sContentType + "'");
    final IMimeType aPlainContentType = aContentType.getCopyWithoutParameters();
    // Fallback to global dumper if none is provided
    final IAS4IncomingDumper aRealIncomingDumper = aIncomingDumper != null ? aIncomingDumper : AS4DumpManager.getIncomingDumper();
    Document aSoapDocument = null;
    ESoapVersion eSoapVersion = null;
    final ICommonsList<WSS4JAttachment> aIncomingAttachments = new CommonsArrayList<>();
    final Wrapper<OutputStream> aDumpOSHolder = new Wrapper<>();
    if (aPlainContentType.equals(AS4RequestHandler.MT_MULTIPART_RELATED)) {
        // MIME message
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Received MIME message");
        final String sBoundary = aContentType.getParameterValueWithName("boundary");
        if (StringHelper.hasNoText(sBoundary))
            throw new Phase4Exception("Content-Type '" + sContentType + "' misses 'boundary' parameter");
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("MIME Boundary: '" + sBoundary + "'");
        // Ensure the stream gets closed correctly
        try (final InputStream aRequestIS = AS4DumpManager.getIncomingDumpAwareInputStream(aRealIncomingDumper, aPayloadIS, aMessageMetadata, aHttpHeaders, aDumpOSHolder)) {
            // PARSING MIME Message via MultipartStream
            final MultipartStream aMulti = new MultipartStream(aRequestIS, sBoundary.getBytes(StandardCharsets.ISO_8859_1), (MultipartProgressNotifier) null);
            int nIndex = 0;
            while (true) {
                final boolean bHasNextPart = nIndex == 0 ? aMulti.skipPreamble() : aMulti.readBoundary();
                if (!bHasNextPart)
                    break;
                if (LOGGER.isDebugEnabled())
                    LOGGER.debug("Found MIME part #" + nIndex);
                try (final MultipartItemInputStream aBodyPartIS = aMulti.createInputStream()) {
                    // Read headers AND content
                    final MimeBodyPart aBodyPart = new MimeBodyPart(aBodyPartIS);
                    if (nIndex == 0) {
                        // First MIME part -> SOAP document
                        if (LOGGER.isDebugEnabled())
                            LOGGER.debug("Parsing first MIME part as SOAP document");
                        // Read SOAP document
                        aSoapDocument = DOMReader.readXMLDOM(aBodyPart.getInputStream());
                        IMimeType aPlainPartMT = MimeTypeParser.safeParseMimeType(aBodyPart.getContentType());
                        if (aPlainPartMT != null)
                            aPlainPartMT = aPlainPartMT.getCopyWithoutParameters();
                        // Determine SOAP version from MIME part content type
                        eSoapVersion = ESoapVersion.getFromMimeTypeOrNull(aPlainPartMT);
                        if (eSoapVersion != null && LOGGER.isDebugEnabled())
                            LOGGER.debug("Determined SOAP version " + eSoapVersion + " from Content-Type");
                        if (eSoapVersion == null && aSoapDocument != null) {
                            // Determine SOAP version from the read document
                            eSoapVersion = ESoapVersion.getFromNamespaceURIOrNull(XMLHelper.getNamespaceURI(aSoapDocument));
                            if (eSoapVersion != null && LOGGER.isDebugEnabled())
                                LOGGER.debug("Determined SOAP version " + eSoapVersion + " from XML root element namespace URI");
                        }
                    } else {
                        // MIME Attachment (index is gt 0)
                        if (LOGGER.isDebugEnabled())
                            LOGGER.debug("Parsing MIME part #" + nIndex + " as attachment");
                        final WSS4JAttachment aAttachment = aIAF.createAttachment(aBodyPart, aResHelper);
                        aIncomingAttachments.add(aAttachment);
                    }
                }
                nIndex++;
            }
        }
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Read MIME message with " + aIncomingAttachments.size() + " attachment(s)");
    } else {
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Received plain message");
        // Expect plain SOAP - read whole request to DOM
        // Note: this may require a huge amount of memory for large requests
        aSoapDocument = DOMReader.readXMLDOM(AS4DumpManager.getIncomingDumpAwareInputStream(aRealIncomingDumper, aPayloadIS, aMessageMetadata, aHttpHeaders, aDumpOSHolder));
        if (LOGGER.isDebugEnabled())
            if (aSoapDocument != null)
                LOGGER.debug("Successfully parsed payload as XML");
            else
                LOGGER.debug("Failed to parse payload as XML");
        if (aSoapDocument != null) {
            // Determine SOAP version from the read document
            eSoapVersion = ESoapVersion.getFromNamespaceURIOrNull(XMLHelper.getNamespaceURI(aSoapDocument));
            if (eSoapVersion != null && LOGGER.isDebugEnabled())
                LOGGER.debug("Determined SOAP version " + eSoapVersion + " from XML root element namespace URI");
        }
        if (eSoapVersion == null) {
            // Determine SOAP version from content type
            eSoapVersion = ESoapVersion.getFromMimeTypeOrNull(aPlainContentType);
            if (eSoapVersion != null && LOGGER.isDebugEnabled())
                LOGGER.debug("Determined SOAP version " + eSoapVersion + " from Content-Type");
        }
    }
    try {
        if (aSoapDocument == null) {
            // We don't have a SOAP document
            throw new Phase4Exception(eSoapVersion == null ? "Failed to parse incoming message!" : "Failed to parse incoming SOAP " + eSoapVersion.getVersion() + " document!");
        }
        if (eSoapVersion == null) {
            // We're missing a SOAP version
            throw new Phase4Exception("Failed to determine SOAP version of XML document!");
        }
        aCallback.handle(aHttpHeaders, aSoapDocument, eSoapVersion, aIncomingAttachments);
    } finally {
        // Here, the incoming dump is finally ready closed and usable
        if (aRealIncomingDumper != null && aDumpOSHolder.isSet())
            try {
                aRealIncomingDumper.onEndRequest(aMessageMetadata);
            } catch (final Exception ex) {
                LOGGER.error("IncomingDumper.onEndRequest failed. Dumper=" + aRealIncomingDumper + "; MessageMetadata=" + aMessageMetadata, ex);
            }
    }
}
Also used : Wrapper(com.helger.commons.wrapper.Wrapper) IAS4IncomingDumper(com.helger.phase4.dump.IAS4IncomingDumper) MultipartItemInputStream(com.helger.web.multipart.MultipartStream.MultipartItemInputStream) NonBlockingByteArrayInputStream(com.helger.commons.io.stream.NonBlockingByteArrayInputStream) HasInputStream(com.helger.commons.io.stream.HasInputStream) IHasInputStream(com.helger.commons.io.IHasInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) Document(org.w3c.dom.Document) AS4DecompressException(com.helger.phase4.attachment.AS4DecompressException) MessagingException(javax.mail.MessagingException) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Phase4Exception(com.helger.phase4.util.Phase4Exception) IOException(java.io.IOException) Phase4Exception(com.helger.phase4.util.Phase4Exception) IMimeType(com.helger.commons.mime.IMimeType) MultipartItemInputStream(com.helger.web.multipart.MultipartStream.MultipartItemInputStream) ESoapVersion(com.helger.phase4.soap.ESoapVersion) MimeBodyPart(javax.mail.internet.MimeBodyPart) MultipartStream(com.helger.web.multipart.MultipartStream) CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList) WSS4JAttachment(com.helger.phase4.attachment.WSS4JAttachment)

Example 8 with IMimeType

use of com.helger.commons.mime.IMimeType in project ph-web by phax.

the class UnifiedResponse method applyToResponse.

public final void applyToResponse(@Nonnull final HttpServletResponse aHttpResponse) throws IOException {
    ValueEnforcer.notNull(aHttpResponse, "HttpResponse");
    // Apply all collected headers
    for (final Map.Entry<String, ICommonsList<String>> aEntry : m_aResponseHeaderMap) {
        final String sHeaderName = aEntry.getKey();
        int nIndex = 0;
        for (final String sHeaderValue : aEntry.getValue()) {
            // Ensure single line values
            final String sUnifiedHeaderValue = m_bHttpHeaderValuesUnified ? HttpHeaderMap.getUnifiedValue(sHeaderValue, m_bHttpHeaderValuesQuoteIfNecessary) : sHeaderValue;
            if (nIndex == 0)
                aHttpResponse.setHeader(sHeaderName, sUnifiedHeaderValue);
            else
                aHttpResponse.addHeader(sHeaderName, sUnifiedHeaderValue);
            ++nIndex;
        }
    }
    final boolean bIsRedirect = isRedirectDefined();
    final boolean bHasStatusCode = isStatusCodeDefined();
    if (bIsRedirect) {
        if (bHasStatusCode)
            logWarn("Ignoring provided status code because a redirect is specified!");
        if (!m_bAllowContentOnRedirect) {
            if (m_aCacheControl != null)
                logInfo("Ignoring provided Cache-Control because a redirect is specified!");
            if (m_sContentDispositionFilename != null)
                logWarn("Ignoring provided Content-Dispostion filename because a redirect is specified!");
            if (m_aMimeType != null)
                logWarn("Ignoring provided MimeType because a redirect is specified!");
            if (m_aCharset != null)
                logWarn("Ignoring provided charset because a redirect is specified!");
            if (hasContent())
                logWarn("Ignoring provided content because a redirect is specified!");
        }
        // Note: After using this method, the response should be
        // considered to be committed and should not be written to.
        String sRealTargetURL;
        if (ServletSettings.isEncodeURLs()) {
            try {
                sRealTargetURL = aHttpResponse.encodeRedirectURL(m_sRedirectTargetUrl);
            } catch (final IllegalArgumentException ex) {
                // Happens e.g. if "http://server/../" is requested
                LOGGER.warn("Failed to encode redirect target URL '" + m_sRedirectTargetUrl + "': " + ex.getMessage());
                sRealTargetURL = m_sRedirectTargetUrl;
            }
        } else
            sRealTargetURL = m_sRedirectTargetUrl;
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Response is a redirect to '" + sRealTargetURL + "' using mode " + m_eRedirectMode);
        switch(m_eRedirectMode) {
            case DEFAULT:
                aHttpResponse.sendRedirect(sRealTargetURL);
                break;
            case POST_REDIRECT_GET:
                if (m_eHttpVersion.is10()) {
                    // For HTTP 1.0 send 302
                    aHttpResponse.setStatus(HttpServletResponse.SC_FOUND);
                } else {
                    // For HTTP 1.1 send 303
                    aHttpResponse.setStatus(HttpServletResponse.SC_SEE_OTHER);
                }
                // Set the location header
                aHttpResponse.addHeader(CHttpHeader.LOCATION, sRealTargetURL);
                break;
            default:
                throw new IllegalStateException("Unimplemented redirect mode " + m_eRedirectMode + "!");
        }
        if (!m_bAllowContentOnRedirect)
            return;
    }
    if (bHasStatusCode) {
        if (bIsRedirect)
            logWarn("Overriding provided redirect because a status code is specified!");
        if (!m_bAllowContentOnStatusCode) {
            if (m_aCacheControl != null)
                logInfo("Ignoring provided Cache-Control because a status code is specified!");
            if (m_sContentDispositionFilename != null)
                logWarn("Ignoring provided Content-Dispostion filename because a status code is specified!");
            if (m_aMimeType != null)
                logWarn("Ignoring provided MimeType because a status code is specified!");
            if (m_aCharset != null)
                logWarn("Ignoring provided charset because a status code is specified!");
            if (hasContent())
                logWarn("Ignoring provided content because a status code is specified!");
        }
        if (m_nStatusCode == HttpServletResponse.SC_UNAUTHORIZED && !m_aResponseHeaderMap.containsHeaders(CHttpHeader.WWW_AUTHENTICATE))
            logWarn("Status code UNAUTHORIZED (401) is returned, but no " + CHttpHeader.WWW_AUTHENTICATE + " HTTP response header is set!");
        // Content may be present so, sendError is not an option here!
        if (m_nStatusCode >= HttpServletResponse.SC_BAD_REQUEST && m_aContentArray == null) {
            // It's an error
            // Note: After using this method, the response should be considered
            // to be committed and should not be written to.
            aHttpResponse.sendError(m_nStatusCode);
        } else {
            // It's a status message "only"
            // Note: The container clears the buffer and sets the Location
            // header, preserving cookies and other headers.
            aHttpResponse.setStatus(m_nStatusCode);
        }
        if (!m_bAllowContentOnStatusCode)
            return;
        if (!hasContent()) {
            // continue - would produce some warnings
            return;
        }
    }
    // Verify only if is a response with content
    _verifyCachingIntegrity();
    if (m_aCacheControl != null) {
        final String sCacheControlValue = m_aCacheControl.getAsHTTPHeaderValue();
        if (StringHelper.hasText(sCacheControlValue))
            aHttpResponse.setHeader(CHttpHeader.CACHE_CONTROL, sCacheControlValue);
        else
            logWarn("An empty Cache-Control was provided!");
    }
    if (m_sContentDispositionFilename != null) {
        final StringBuilder aSB = new StringBuilder();
        if (m_aRequestBrowserInfo != null && m_aRequestBrowserInfo.getBrowserType() == EBrowserType.IE && m_aRequestBrowserInfo.getVersion().getMajor() <= 8) {
            // Special case for IE <= 8
            final Charset aCharsetToUse = m_aCharset != null ? m_aCharset : StandardCharsets.UTF_8;
            aSB.append(m_eContentDispositionType.getID()).append("; filename=").append(URLHelper.urlEncode(m_sContentDispositionFilename, aCharsetToUse));
        } else {
            // Filename needs to be surrounded with double quotes (single quotes
            // don't work).
            aSB.append(m_eContentDispositionType.getID()).append("; filename=\"").append(m_sContentDispositionFilename).append('"');
            // Check if we need an UTF-8 filename
            // http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http/6745788#6745788
            final String sRFC5987Filename = RFC5987Encoder.getRFC5987EncodedUTF8(m_sContentDispositionFilename);
            if (!sRFC5987Filename.equals(m_sContentDispositionFilename))
                aSB.append("; filename*=UTF-8''").append(sRFC5987Filename);
        }
        aHttpResponse.setHeader(CHttpHeader.CONTENT_DISPOSITION, aSB.toString());
        if (m_aMimeType == null) {
            logWarn("Content-Disposition is specified but no MimeType is set. Using the default download MimeType.");
            aHttpResponse.setContentType(CMimeType.APPLICATION_FORCE_DOWNLOAD.getAsString());
        }
    }
    // Mime type
    if (m_aMimeType != null) {
        final String sMimeType = m_aMimeType.getAsString();
        // Check with request accept mime types
        final QValue aQuality = m_aAcceptMimeTypeList.getQValueOfMimeType(m_aMimeType);
        if (aQuality.isMinimumQuality()) {
            final ICommonsOrderedMap<IMimeType, QValue> aBetterValues = m_aAcceptMimeTypeList.getAllQValuesGreaterThan(aQuality.getQuality());
            logError("MimeType '" + sMimeType + "' is not at all supported by the request. Allowed values are: " + _getAsStringMimeTypes(aBetterValues));
        } else if (aQuality.isLowValue()) {
            // only in the debug version
            if (GlobalDebug.isDebugMode()) {
                // Inform if the quality of the request is <= 50%!
                final ICommonsOrderedMap<IMimeType, QValue> aBetterValues = m_aAcceptMimeTypeList.getAllQValuesGreaterThan(aQuality.getQuality());
                if (!aBetterValues.isEmpty())
                    logWarn("MimeType '" + sMimeType + "' is not best supported by the request (" + aQuality + "). Better MimeTypes are: " + _getAsStringMimeTypes(aBetterValues));
            }
        }
        aHttpResponse.setContentType(sMimeType);
    } else {
        logWarn("No MimeType present");
    }
    // Charset
    if (m_aCharset != null) {
        final String sCharset = m_aCharset.name();
        if (m_aMimeType == null)
            logWarn("If no MimeType present, the client cannot get notified about the character encoding '" + sCharset + "'");
        // Check with request charset
        final QValue aQuality = m_aAcceptCharsetList.getQValueOfCharset(sCharset);
        if (aQuality.isMinimumQuality()) {
            final ICommonsOrderedMap<String, QValue> aBetterValues = m_aAcceptCharsetList.getAllQValuesGreaterThan(aQuality.getQuality());
            logError("Character encoding '" + sCharset + "' is not at all supported by the request. Allowed values are: " + _getAsStringText(aBetterValues));
        } else if (aQuality.isLowValue()) {
            // Inform if the quality of the request is <= 50%!
            final ICommonsOrderedMap<String, QValue> aBetterValues = m_aAcceptCharsetList.getAllQValuesGreaterThan(aQuality.getQuality());
            if (!aBetterValues.isEmpty())
                logWarn("Character encoding '" + sCharset + "' is not best supported by the request (" + aQuality + "). Better charsets are: " + _getAsStringText(aBetterValues));
        }
        aHttpResponse.setCharacterEncoding(sCharset);
    } else if (m_aMimeType == null) {
        logWarn("Also no character encoding present");
    } else
        switch(m_aMimeType.getContentType()) {
            case TEXT:
            case MULTIPART:
                logWarn("A character encoding for MimeType '" + m_aMimeType.getAsString() + "' is appreciated.");
                break;
            default:
                // Do we need character encoding here as well???
                break;
        }
    // Add all cookies
    if (m_aCookies != null)
        for (final Cookie aCookie : m_aCookies.values()) aHttpResponse.addCookie(aCookie);
    // Write the body to the response
    _applyContent(aHttpResponse, bHasStatusCode);
}
Also used : Cookie(javax.servlet.http.Cookie) ICommonsList(com.helger.commons.collection.impl.ICommonsList) QValue(com.helger.http.QValue) Charset(java.nio.charset.Charset) ICommonsOrderedMap(com.helger.commons.collection.impl.ICommonsOrderedMap) IMimeType(com.helger.commons.mime.IMimeType) HttpHeaderMap(com.helger.commons.http.HttpHeaderMap) Map(java.util.Map) ICommonsOrderedMap(com.helger.commons.collection.impl.ICommonsOrderedMap) ICommonsMap(com.helger.commons.collection.impl.ICommonsMap) CommonsLinkedHashMap(com.helger.commons.collection.impl.CommonsLinkedHashMap)

Example 9 with IMimeType

use of com.helger.commons.mime.IMimeType in project phase4 by phax.

the class PModePayloadProfileJsonConverter method convertToNative.

@Nonnull
public static PModePayloadProfile convertToNative(final IJsonObject aElement) {
    final String sName = aElement.getAsString(NAME);
    final String sMimeType = aElement.getAsString(MIME_TYPE);
    final IMimeType aMimeType;
    try {
        aMimeType = MimeTypeParser.parseMimeType(sMimeType);
    } catch (final MimeTypeParserException ex) {
        throw new IllegalArgumentException("Failed to parse MIME Type '" + sMimeType + "'", ex);
    }
    final String sXSDFilename = aElement.getAsString(XSD_FILENAME);
    final Integer aMaxSizeKB = aElement.getAsIntObj(MAX_SIZE_KB);
    final EMandatory eMandatory = EMandatory.valueOf(aElement.getAsBoolean(MANDATORY, PModePayloadProfile.DEFAULT_MANDATORY));
    return new PModePayloadProfile(sName, aMimeType, sXSDFilename, aMaxSizeKB, eMandatory);
}
Also used : IMimeType(com.helger.commons.mime.IMimeType) EMandatory(com.helger.commons.state.EMandatory) MimeTypeParserException(com.helger.commons.mime.MimeTypeParserException) Nonnull(javax.annotation.Nonnull)

Example 10 with IMimeType

use of com.helger.commons.mime.IMimeType in project phase4 by phax.

the class PModePayloadProfileMicroTypeConverter method convertToNative.

@Nonnull
public PModePayloadProfile convertToNative(final IMicroElement aElement) {
    final String sName = aElement.getAttributeValue(ATTR_NAME);
    final String sMimeType = aElement.getAttributeValue(ATTR_MIME_TYPE);
    final IMimeType aMimeType;
    try {
        aMimeType = MimeTypeParser.parseMimeType(sMimeType);
    } catch (final MimeTypeParserException ex) {
        throw new IllegalArgumentException("Failed to parse MIME Type '" + sMimeType + "'", ex);
    }
    final String sXSDFilename = aElement.getAttributeValue(ATTR_XSD_FILENAME);
    final Integer aMaxSizeKB = aElement.getAttributeValueWithConversion(ATTR_MAX_SIZE_KB, Integer.class);
    final EMandatory eMandatory = EMandatory.valueOf(aElement.getAttributeValueAsBool(ATTR_MANDATORY, PModePayloadProfile.DEFAULT_MANDATORY));
    return new PModePayloadProfile(sName, aMimeType, sXSDFilename, aMaxSizeKB, eMandatory);
}
Also used : IMimeType(com.helger.commons.mime.IMimeType) EMandatory(com.helger.commons.state.EMandatory) MimeTypeParserException(com.helger.commons.mime.MimeTypeParserException) Nonnull(javax.annotation.Nonnull)

Aggregations

IMimeType (com.helger.commons.mime.IMimeType)11 Nonnull (javax.annotation.Nonnull)5 MimeTypeParserException (com.helger.commons.mime.MimeTypeParserException)3 Charset (java.nio.charset.Charset)3 ICommonsList (com.helger.commons.collection.impl.ICommonsList)2 HttpHeaderMap (com.helger.commons.http.HttpHeaderMap)2 IHasInputStream (com.helger.commons.io.IHasInputStream)2 NonBlockingByteArrayInputStream (com.helger.commons.io.stream.NonBlockingByteArrayInputStream)2 EMandatory (com.helger.commons.state.EMandatory)2 Phase4Exception (com.helger.phase4.util.Phase4Exception)2 IOException (java.io.IOException)2 Nullable (javax.annotation.Nullable)2 MessagingException (javax.mail.MessagingException)2 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)2 CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)1 CommonsLinkedHashMap (com.helger.commons.collection.impl.CommonsLinkedHashMap)1 ICommonsMap (com.helger.commons.collection.impl.ICommonsMap)1 ICommonsOrderedMap (com.helger.commons.collection.impl.ICommonsOrderedMap)1 HasInputStream (com.helger.commons.io.stream.HasInputStream)1 Wrapper (com.helger.commons.wrapper.Wrapper)1