Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2005-2012 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.springframework.ws.soap.axiom;
 
 import java.io.File;
 
 
Axiom-specific implementation of the WebServiceMessageFactory interface. Creates AxiomSoapMessages.

To increase reading performance on the the SOAP request created by this message factory, you can set the setPayloadCaching(boolean) property to false (default is true). This this will read the contents of the body directly from the stream. However, when this setting is enabled, the payload can only be read once. This means that any endpoint mappings or interceptors which are based on the message payload (such as the org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping, the org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor, or the org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor) cannot be used. Instead, use an endpoint mapping that does not consume the payload (i.e. the org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping).

Additionally, this message factory can cache large attachments to disk by setting the setAttachmentCaching(boolean) property to true (default is false). Optionally, the location where attachments are stored can be defined via the attachmentCacheDir property (defaults to the system temp file path).

Mostly derived from org.apache.axis2.transport.http.HTTPTransportUtils and org.apache.axis2.transport.TransportUtils, which we cannot use since they are not part of the Axiom distribution.

Author(s):
Arjen Poutsma
Since:
1.0.0
See also:
AxiomSoapMessage
setPayloadCaching(boolean)
 
 
     private static final String CHARSET_PARAMETER = "charset";
 
     private static final String DEFAULT_CHARSET_ENCODING = "UTF-8";
 
     private static final String MULTI_PART_RELATED_CONTENT_TYPE = "multipart/related";
 
     private static final Log logger = LogFactory.getLog(AxiomSoapMessageFactory.class);
 
     private final XMLInputFactory inputFactory = createXmlInputFactory();
 
     private boolean payloadCaching = true;
 
     private boolean attachmentCaching = false;
 
     private File attachmentCacheDir;
 
     private int attachmentCacheThreshold = 4096;
    // use SOAP 1.1 by default
    private SOAPFactory soapFactory = new SOAP11Factory();
    private boolean langAttributeOnSoap11FaultString = true;


    
Indicates whether the SOAP Body payload should be cached or not. Default is true.

Setting this to false will increase performance, but also result in the fact that the message payload can only be read once.

    public void setPayloadCaching(boolean payloadCaching) {
        this. = payloadCaching;
    }

    
Indicates whether SOAP attachments should be cached or not. Default is false.

Setting this to true will cause Axiom to store larger attachments on disk, rather than in memory. This decreases memory consumption, but decreases performance.

    public void setAttachmentCaching(boolean attachmentCaching) {
        this. = attachmentCaching;
    }

    
Sets the directory where SOAP attachments will be stored. Only used when attachmentCaching is set to true.

The parameter should be an existing, writable directory. This property defaults to the temporary directory of the operating system (i.e. the value of the java.io.tmpdir system property).

    public void setAttachmentCacheDir(File attachmentCacheDir) {
        Assert.notNull(attachmentCacheDir"'attachmentCacheDir' must not be null");
        Assert.isTrue(attachmentCacheDir.isDirectory(), "'attachmentCacheDir' must be a directory");
        Assert.isTrue(attachmentCacheDir.canWrite(), "'attachmentCacheDir' must be writable");
        this. = attachmentCacheDir;
    }

    
Sets the threshold for attachments caching, in bytes. Attachments larger than this threshold will be cached in the attachment cache directory. Only used when setAttachmentCaching(boolean) is set to true.

Defaults to 4096 bytes (i.e. 4 kilobytes).

    public void setAttachmentCacheThreshold(int attachmentCacheThreshold) {
        Assert.isTrue(attachmentCacheThreshold > 0, "'attachmentCacheThreshold' must be larger than 0");
        this. = attachmentCacheThreshold;
    }
    public void setSoapVersion(SoapVersion version) {
        if (. == version) {
             = new SOAP11Factory();
        }
        else if (. == version) {
             = new SOAP12Factory();
        }
        else {
            throw new IllegalArgumentException(
                    "Invalid version [" + version + "]. " + "Expected the SOAP_11 or SOAP_12 constant");
        }
    }

    
Defines whether a xml:lang attribute should be set on SOAP 1.1 <faultstring> elements.

The default is true, to comply with WS-I, but this flag can be set to false to the older W3C SOAP 1.1 specification.

See also:
WS-I Basic Profile 1.1
    public void setLangAttributeOnSoap11FaultString(boolean langAttributeOnSoap11FaultString) {
        this. = langAttributeOnSoap11FaultString;
    }
    public void afterPropertiesSet() throws Exception {
        if (.isInfoEnabled()) {
            .info( ? "Enabled payload caching" : "Disabled payload caching");
        }
        if ( == null) {
            String tempDir = System.getProperty("java.io.tmpdir");
            setAttachmentCacheDir(new File(tempDir));
        }
    }
    }
    public AxiomSoapMessage createWebServiceMessage(InputStream inputStreamthrows IOException {
        Assert.isInstanceOf(TransportInputStream.classinputStream,
                "AxiomSoapMessageFactory requires a TransportInputStream");
        TransportInputStream transportInputStream = (TransportInputStreaminputStream;
        String contentType = getHeaderValue(transportInputStream.);
        if (!StringUtils.hasLength(contentType)) {
            if (.isDebugEnabled()) {
                .debug("TransportInputStream has no Content-Type header; defaulting to \"" +
                        ..getContentType() + "\"");
            }
            contentType = ..getContentType();
        }
        String soapAction = getHeaderValue(transportInputStream.);
        if (!StringUtils.hasLength(soapAction)) {
            soapAction = SoapUtils.extractActionFromContentType(contentType);
        }
        try {
            if (isMultiPartRelated(contentType)) {
                return createMultiPartAxiomSoapMessage(inputStreamcontentTypesoapAction);
            }
            else {
                return createAxiomSoapMessage(inputStreamcontentTypesoapAction);
            }
        }
        catch (XMLStreamException ex) {
            throw new AxiomSoapMessageCreationException("Could not parse request: " + ex.getMessage(), ex);
        }
        catch (OMException ex) {
            throw new AxiomSoapMessageCreationException("Could not create message: " + ex.getMessage(), ex);
        }
    }
    private String getHeaderValue(TransportInputStream transportInputStreamString headerthrows IOException {
        String contentType = null;
        Iterator<Stringiterator = transportInputStream.getHeaders(header);
        if (iterator.hasNext()) {
            contentType = iterator.next();
        }
        return contentType;
    }
    private boolean isMultiPartRelated(String contentType) {
        contentType = contentType.toLowerCase(.);
        return contentType.contains();
    }

    
Creates an AxiomSoapMessage without attachments.
    private AxiomSoapMessage createAxiomSoapMessage(InputStream inputStreamString contentTypeString soapAction)
            throws XMLStreamException {
        XMLStreamReader reader = .createXMLStreamReader(inputStreamgetCharSetEncoding(contentType));
        String envelopeNamespace = getSoapEnvelopeNamespace(contentType);
        StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(readerenvelopeNamespace);
        SOAPMessage soapMessage = builder.getSoapMessage();
        return new AxiomSoapMessage(soapMessagesoapAction);
    }

    
Creates an AxiomSoapMessage with attachments.
                                                             String contentType,
                                                             String soapActionthrows XMLStreamException {
        Attachments attachments =
                new Attachments(inputStreamcontentType.getAbsolutePath(),
                        Integer.toString());
                getCharSetEncoding(attachments.getSOAPPartContentType()));
        StAXSOAPModelBuilder builder;
        String envelopeNamespace = getSoapEnvelopeNamespace(contentType);
        if (..equals(attachments.getAttachmentSpecType()) ||
                ..equals(attachments.getAttachmentSpecType())) {
            builder = new StAXSOAPModelBuilder(readerenvelopeNamespace);
        }
        else if (..equals(attachments.getAttachmentSpecType())) {
            builder = new MTOMStAXSOAPModelBuilder(readerattachmentsenvelopeNamespace);
        }
        else {
            throw new AxiomSoapMessageCreationException(
                    "Unknown attachment type: [" + attachments.getAttachmentSpecType() + "]");
        }
        return new AxiomSoapMessage(builder.getSoapMessage(), attachmentssoapAction,
                );
    }
    private String getSoapEnvelopeNamespace(String contentType) {
        if (contentType.contains(.)) {
            return .;
        }
        else if (contentType.contains(.)) {
            return .;
        }
        else {
            throw new AxiomSoapMessageCreationException("Unknown content type '" + contentType + "'");
        }
    }

    
Returns the character set from the given content type. Mostly copied

Returns:
the character set encoding
    protected String getCharSetEncoding(String contentType) {
        int charSetIdx = contentType.indexOf();
        if (charSetIdx == -1) {
            return ;
        }
        int eqIdx = contentType.indexOf("="charSetIdx);
        int indexOfSemiColon = contentType.indexOf(";"eqIdx);
        String value;
        if (indexOfSemiColon > 0) {
            value = contentType.substring(eqIdx + 1, indexOfSemiColon);
        }
        else {
            value = contentType.substring(eqIdx + 1, contentType.length()).trim();
        }
        if (value.startsWith("\"")) {
            value = value.substring(1);
        }
        if (value.endsWith("\"")) {
            return value.substring(0, value.length() - 1);
        }
        if ("null".equalsIgnoreCase(value)) {
            return ;
        }
        else {
            return value.trim();
        }
    }

    
Create a XMLInputFactory that this resolver will use to create javax.xml.stream.XMLStreamReader objects.

Can be overridden in subclasses, adding further initialization of the factory. The resulting factory is cached, so this method will only be called once.

Returns:
the created factory
    protected XMLInputFactory createXmlInputFactory() {
        return XMLInputFactory.newInstance();
    }
    public String toString() {
        StringBuilder builder = new StringBuilder("AxiomSoapMessageFactory[");
        if ( instanceof SOAP11Factory) {
            builder.append("SOAP 1.1");
        }
        else if ( instanceof SOAP12Factory) {
            builder.append("SOAP 1.2");
        }
        builder.append(',');
        if () {
            builder.append("PayloadCaching enabled");
        }
        else {
            builder.append("PayloadCaching disabled");
        }
        builder.append(']');
        return builder.toString();
    }
New to GrepCode? Check out our FAQ X