Save This Page
Home » axis2-1.5-src » org.apache » axis2 » builder » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.axis2.builder;
   21   
   22   import org.apache.axiom.attachments.Attachments;
   23   import org.apache.axiom.attachments.lifecycle.LifecycleManager;
   24   import org.apache.axiom.attachments.lifecycle.impl.LifecycleManagerImpl;
   25   import org.apache.axiom.attachments.utils.IOUtils;
   26   import org.apache.axiom.om.OMAttribute;
   27   import org.apache.axiom.om.OMElement;
   28   import org.apache.axiom.om.OMException;
   29   import org.apache.axiom.om.OMNamespace;
   30   import org.apache.axiom.om.OMText;
   31   import org.apache.axiom.om.impl.MTOMConstants;
   32   import org.apache.axiom.om.impl.builder.StAXBuilder;
   33   import org.apache.axiom.om.impl.builder.StAXOMBuilder;
   34   import org.apache.axiom.om.impl.builder.XOPAwareStAXOMBuilder;
   35   import org.apache.axiom.om.util.StAXUtils;
   36   import org.apache.axiom.soap.SOAP11Constants;
   37   import org.apache.axiom.soap.SOAP12Constants;
   38   import org.apache.axiom.soap.SOAPBody;
   39   import org.apache.axiom.soap.SOAPConstants;
   40   import org.apache.axiom.soap.SOAPEnvelope;
   41   import org.apache.axiom.soap.SOAPFactory;
   42   import org.apache.axiom.soap.SOAPProcessingException;
   43   import org.apache.axiom.soap.impl.builder.MTOMStAXSOAPModelBuilder;
   44   import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
   45   import org.apache.axis2.AxisFault;
   46   import org.apache.axis2.Constants;
   47   import org.apache.axis2.context.MessageContext;
   48   import org.apache.axis2.deployment.DeploymentConstants;
   49   import org.apache.axis2.description.AxisMessage;
   50   import org.apache.axis2.description.AxisOperation;
   51   import org.apache.axis2.description.Parameter;
   52   import org.apache.axis2.engine.AxisConfiguration;
   53   import org.apache.axis2.java.security.AccessController;
   54   import org.apache.axis2.transport.http.HTTPConstants;
   55   import org.apache.axis2.util.JavaUtils;
   56   import org.apache.axis2.util.MultipleEntryHashMap;
   57   import org.apache.axis2.wsdl.WSDLConstants;
   58   import org.apache.commons.logging.Log;
   59   import org.apache.commons.logging.LogFactory;
   60   import org.apache.ws.commons.schema.XmlSchemaAll;
   61   import org.apache.ws.commons.schema.XmlSchemaComplexType;
   62   import org.apache.ws.commons.schema.XmlSchemaElement;
   63   import org.apache.ws.commons.schema.XmlSchemaGroupBase;
   64   import org.apache.ws.commons.schema.XmlSchemaParticle;
   65   import org.apache.ws.commons.schema.XmlSchemaSequence;
   66   import org.apache.ws.commons.schema.XmlSchemaType;
   67   
   68   import javax.activation.DataHandler;
   69   import javax.xml.namespace.QName;
   70   import javax.xml.parsers.FactoryConfigurationError;
   71   import javax.xml.stream.XMLStreamException;
   72   import javax.xml.stream.XMLStreamReader;
   73   import java.io.BufferedReader;
   74   import java.io.IOException;
   75   import java.io.InputStream;
   76   import java.io.InputStreamReader;
   77   import java.io.PushbackInputStream;
   78   import java.io.Reader;
   79   import java.io.UnsupportedEncodingException;
   80   import java.security.PrivilegedActionException;
   81   import java.security.PrivilegedExceptionAction;
   82   import java.util.Iterator;
   83   import java.util.Map;
   84   
   85   public class BuilderUtil {
   86       private static final Log log = LogFactory.getLog(BuilderUtil.class);
   87   
   88       public static final int BOM_SIZE = 4;
   89   
   90       public static SOAPEnvelope buildsoapMessage(MessageContext messageContext,
   91                                                   MultipleEntryHashMap requestParameterMap,
   92                                                   SOAPFactory soapFactory) throws AxisFault {
   93   
   94           SOAPEnvelope soapEnvelope = soapFactory.getDefaultEnvelope();
   95           SOAPBody body = soapEnvelope.getBody();
   96           XmlSchemaElement xmlSchemaElement;
   97           AxisOperation axisOperation = messageContext.getAxisOperation();
   98           if (axisOperation != null) {
   99               AxisMessage axisMessage =
  100                       axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
  101               xmlSchemaElement = axisMessage.getSchemaElement();
  102   
  103               if (xmlSchemaElement == null) {
  104                   OMElement bodyFirstChild =
  105                           soapFactory
  106                                   .createOMElement(messageContext.getAxisOperation().getName(), body);
  107   
  108                   // if there is no schema its piece of cake !! add these to the soap body in any order you like.
  109                   // Note : if there are parameters in the path of the URL, there is no way this can add them
  110                   // to the message.
  111                   createSOAPMessageWithoutSchema(soapFactory, bodyFirstChild, requestParameterMap);
  112               } else {
  113   
  114                   // first get the target namespace from the schema and the wrapping element.
  115                   // create an OMElement out of those information. We are going to extract parameters from
  116                   // url, create OMElements and add them as children to this wrapping element.
  117                   String targetNamespace = xmlSchemaElement.getQName().getNamespaceURI();
  118                   QName bodyFirstChildQName;
  119                   if (targetNamespace != null && !"".equals(targetNamespace)) {
  120                       bodyFirstChildQName = new QName(targetNamespace, xmlSchemaElement.getName());
  121                   } else {
  122                       bodyFirstChildQName = new QName(xmlSchemaElement.getName());
  123                   }
  124                   OMElement bodyFirstChild = soapFactory.createOMElement(bodyFirstChildQName, body);
  125   
  126                   // Schema should adhere to the IRI style in this. So assume IRI style and dive in to
  127                   // schema
  128                   XmlSchemaType schemaType = xmlSchemaElement.getSchemaType();
  129                   if (schemaType instanceof XmlSchemaComplexType) {
  130                       XmlSchemaComplexType complexType = ((XmlSchemaComplexType)schemaType);
  131                       XmlSchemaParticle particle = complexType.getParticle();
  132                       if (particle instanceof XmlSchemaSequence || particle instanceof XmlSchemaAll) {
  133                           XmlSchemaGroupBase xmlSchemaGroupBase = (XmlSchemaGroupBase)particle;
  134                           Iterator iterator = xmlSchemaGroupBase.getItems().getIterator();
  135   
  136                           // now we need to know some information from the binding operation.
  137   
  138                           while (iterator.hasNext()) {
  139                               XmlSchemaElement innerElement = (XmlSchemaElement)iterator.next();
  140                               QName qName = innerElement.getQName();
  141                               if (qName == null && innerElement.getSchemaTypeName()
  142                                       .equals(org.apache.ws.commons.schema.constants.Constants.XSD_ANYTYPE)) {
  143                                   createSOAPMessageWithoutSchema(soapFactory, bodyFirstChild,
  144                                                                  requestParameterMap);
  145                                   break;
  146                               }
  147                               long minOccurs = innerElement.getMinOccurs();
  148                               boolean nillable = innerElement.isNillable();
  149                               String name =
  150                                       qName != null ? qName.getLocalPart() : innerElement.getName();
  151                               Object value;
  152                               OMNamespace ns = (qName == null ||
  153                                                 qName.getNamespaceURI() == null
  154                                                 || qName.getNamespaceURI().length() == 0) ?
  155                                       null : soapFactory.createOMNamespace(
  156                                       qName.getNamespaceURI(), null);
  157   
  158                               // FIXME changed
  159                               while ((value = requestParameterMap.get(name)) != null) {
  160                                   addRequestParameter(soapFactory,
  161                                                       bodyFirstChild, ns, name, value);
  162                                   minOccurs--;
  163                               }
  164                               if (minOccurs > 0) {
  165                                   if (nillable) {
  166   
  167                                       OMNamespace xsi = soapFactory.createOMNamespace(
  168                                               Constants.URI_DEFAULT_SCHEMA_XSI,
  169                                               Constants.NS_PREFIX_SCHEMA_XSI);
  170                                       OMAttribute omAttribute =
  171                                               soapFactory.createOMAttribute("nil", xsi, "true");
  172                                       soapFactory.createOMElement(name, ns,
  173                                                                   bodyFirstChild)
  174                                               .addAttribute(omAttribute);
  175   
  176                                   } else {
  177                                       throw new AxisFault("Required element " + qName +
  178                                                           " defined in the schema can not be" +
  179                                                           " found in the request");
  180                                   }
  181                               }
  182                           }
  183                       }
  184                   }
  185               }
  186           }
  187           return soapEnvelope;
  188       }
  189   
  190       private static void createSOAPMessageWithoutSchema(SOAPFactory soapFactory,
  191                                                          OMElement bodyFirstChild,
  192                                                          MultipleEntryHashMap requestParameterMap) {
  193   
  194           // first add the parameters in the URL
  195           if (requestParameterMap != null) {
  196               Iterator requestParamMapIter = requestParameterMap.keySet().iterator();
  197               while (requestParamMapIter.hasNext()) {
  198                   String key = (String)requestParamMapIter.next();
  199                   Object value = requestParameterMap.get(key);
  200                   if (value != null) {
  201                       addRequestParameter(soapFactory, bodyFirstChild, null, key,
  202                                           value);
  203                   }
  204   
  205               }
  206           }
  207       }
  208   
  209       private static void addRequestParameter(SOAPFactory soapFactory,
  210                                               OMElement bodyFirstChild,
  211                                               OMNamespace ns,
  212                                               String key,
  213                                               Object parameter) {
  214           if (parameter instanceof DataHandler) {
  215               DataHandler dataHandler = (DataHandler)parameter;
  216               OMText dataText = bodyFirstChild.getOMFactory().createOMText(
  217                       dataHandler, true);
  218               soapFactory.createOMElement(key, ns, bodyFirstChild).addChild(
  219                       dataText);
  220           } else {
  221               String textValue = parameter.toString();
  222               soapFactory.createOMElement(key, ns, bodyFirstChild).setText(
  223                       textValue);
  224           }
  225       }
  226   
  227       public static StAXBuilder getPOXBuilder(InputStream inStream, String charSetEnc)
  228               throws XMLStreamException {
  229           StAXBuilder builder;
  230           XMLStreamReader xmlreader =
  231                   StAXUtils.createXMLStreamReader(inStream, charSetEnc);
  232           builder = new StAXOMBuilder(xmlreader);
  233           return builder;
  234       }
  235   
  236       /**
  237        * Use the BOM Mark to identify the encoding to be used. Fall back to default encoding
  238        * specified
  239        *
  240        * @param is              the InputStream of a message
  241        * @param charSetEncoding default character set encoding
  242        * @return a Reader with the correct encoding already set
  243        * @throws java.io.IOException
  244        */
  245       public static Reader getReader(final InputStream is, final String charSetEncoding)
  246               throws IOException {
  247           final PushbackInputStream is2 = getPushbackInputStream(is);
  248           final String encoding = getCharSetEncoding(is2, charSetEncoding);
  249           InputStreamReader inputStreamReader;
  250           try {
  251               inputStreamReader = (InputStreamReader)AccessController.doPrivileged(
  252                       new PrivilegedExceptionAction() {
  253                           public Object run() throws UnsupportedEncodingException {
  254                               return new InputStreamReader(is2, encoding);
  255                           }
  256                       }
  257               );
  258           } catch (PrivilegedActionException e) {
  259               throw (UnsupportedEncodingException)e.getException();
  260           }
  261           return new BufferedReader(inputStreamReader);
  262       }
  263   
  264       /**
  265        * Convenience method to get a PushbackInputStream so that we can read the BOM
  266        *
  267        * @param is a regular InputStream
  268        * @return a PushbackInputStream wrapping the passed one
  269        */
  270       public static PushbackInputStream getPushbackInputStream(InputStream is) {
  271           return new PushbackInputStream(is, BOM_SIZE);
  272       }
  273   
  274       /**
  275        * Use the BOM Mark to identify the encoding to be used. Fall back to default encoding
  276        * specified
  277        *
  278        * @param is2             PushBackInputStream (it must be a pushback input stream so that we can
  279        *                        unread the BOM)
  280        * @param defaultEncoding default encoding style if no BOM
  281        * @return the selected character set encoding
  282        * @throws java.io.IOException
  283        */
  284       public static String getCharSetEncoding(PushbackInputStream is2, String defaultEncoding)
  285               throws IOException {
  286           String encoding;
  287           byte bom[] = new byte[BOM_SIZE];
  288           int n, unread;
  289   
  290           n = is2.read(bom, 0, bom.length);
  291   
  292           if ((bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB) && (bom[2] == (byte)0xBF)) {
  293               encoding = "UTF-8";
  294               if (log.isDebugEnabled()) {
  295                   log.debug("char set encoding set from BOM =" + encoding);
  296               }
  297               unread = n - 3;
  298           } else if ((bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF)) {
  299               encoding = "UTF-16BE";
  300               if (log.isDebugEnabled()) {
  301                   log.debug("char set encoding set from BOM =" + encoding);
  302               }
  303               unread = n - 2;
  304           } else if ((bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE)) {
  305               encoding = "UTF-16LE";
  306               if (log.isDebugEnabled()) {
  307                   log.debug("char set encoding set from BOM =" + encoding);
  308               }
  309               unread = n - 2;
  310           } else if ((bom[0] == (byte)0x00) && (bom[1] == (byte)0x00) && (bom[2] == (byte)0xFE)
  311                      && (bom[3] == (byte)0xFF)) {
  312               encoding = "UTF-32BE";
  313               if (log.isDebugEnabled()) {
  314                   log.debug("char set encoding set from BOM =" + encoding);
  315               }
  316               unread = n - 4;
  317           } else if ((bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) && (bom[2] == (byte)0x00)
  318                      && (bom[3] == (byte)0x00)) {
  319               encoding = "UTF-32LE";
  320               if (log.isDebugEnabled()) {
  321                   log.debug("char set encoding set from BOM =" + encoding);
  322               }
  323               unread = n - 4;
  324           } else {
  325   
  326               // Unicode BOM mark not found, unread all bytes
  327               encoding = defaultEncoding;
  328               if (log.isDebugEnabled()) {
  329                   log.debug("char set encoding set from default =" + encoding);
  330               }
  331               unread = n;
  332           }
  333   
  334           if (unread > 0) {
  335               is2.unread(bom, (n - unread), unread);
  336           }
  337           return encoding;
  338       }
  339   
  340   
  341       public static String getEnvelopeNamespace(String contentType) {
  342           String soapNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
  343           if (contentType != null) {
  344               if (contentType.indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1) {
  345                   // it is SOAP 1.2
  346                   soapNS = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
  347               } else if (contentType.indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1) {
  348                   // SOAP 1.1
  349                   soapNS = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
  350               }
  351           }
  352           return soapNS;
  353       }
  354   
  355       /**
  356        * Extracts and returns the character set encoding from the Content-type header
  357        * <p/>
  358        * Example: "Content-Type: text/xml; charset=utf-8" would return "utf-8"
  359        *
  360        * @param contentType a content-type (from HTTP or MIME, for instance)
  361        * @return the character set encoding if found, or MessageContext.DEFAULT_CHAR_SET_ENCODING
  362        */
  363       public static String getCharSetEncoding(String contentType) {
  364           if (log.isDebugEnabled()) {
  365               log.debug("Input contentType (" + contentType + ")");
  366           }
  367           if (contentType == null) {
  368               // Using the default UTF-8
  369               if (log.isDebugEnabled()) {
  370                   log.debug("CharSetEncoding defaulted (" + MessageContext.DEFAULT_CHAR_SET_ENCODING +
  371                             ")");
  372               }
  373               return MessageContext.DEFAULT_CHAR_SET_ENCODING;
  374           }
  375   
  376           int index = contentType.indexOf(HTTPConstants.CHAR_SET_ENCODING);
  377   
  378           if (index == -1) {    // Charset encoding not found in the content-type header
  379               // Using the default UTF-8
  380               if (log.isDebugEnabled()) {
  381                   log.debug("CharSetEncoding defaulted (" + MessageContext.DEFAULT_CHAR_SET_ENCODING +
  382                             ")");
  383               }
  384               return MessageContext.DEFAULT_CHAR_SET_ENCODING;
  385           }
  386   
  387           // If there are spaces around the '=' sign
  388           int indexOfEq = contentType.indexOf("=", index);
  389   
  390           // There can be situations where "charset" is not the last parameter of the Content-Type header
  391           int indexOfSemiColon = contentType.indexOf(";", indexOfEq);
  392           String value;
  393   
  394           if (indexOfSemiColon > 0) {
  395               value = (contentType.substring(indexOfEq + 1, indexOfSemiColon));
  396           } else {
  397               value = (contentType.substring(indexOfEq + 1, contentType.length())).trim();
  398           }
  399   
  400           // There might be "" around the value - if so remove them
  401           if (value.indexOf('\"') != -1) {
  402               value = value.replaceAll("\"", "");
  403           }
  404           value = value.trim();
  405           if (log.isDebugEnabled()) {
  406               log.debug("CharSetEncoding from content-type (" + value + ")");
  407           }
  408           return value;
  409       }
  410   
  411       public static StAXBuilder getAttachmentsBuilder(MessageContext msgContext,
  412                                                       InputStream inStream, String contentTypeString,
  413                                                       boolean isSOAP)
  414               throws OMException, XMLStreamException, FactoryConfigurationError {
  415           StAXBuilder builder = null;
  416           XMLStreamReader streamReader;
  417   
  418           Attachments attachments = createAttachmentsMap(msgContext, inStream, contentTypeString);
  419           String charSetEncoding = getCharSetEncoding(attachments.getSOAPPartContentType());
  420   
  421           if ((charSetEncoding == null)
  422               || "null".equalsIgnoreCase(charSetEncoding)) {
  423               charSetEncoding = MessageContext.UTF_8;
  424           }
  425           msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
  426                                  charSetEncoding);
  427   
  428           try {
  429               PushbackInputStream pis = getPushbackInputStream(attachments.getSOAPPartInputStream());
  430               String actualCharSetEncoding = getCharSetEncoding(pis, charSetEncoding);
  431   
  432               streamReader = StAXUtils.createXMLStreamReader(pis, actualCharSetEncoding);
  433           } catch (IOException e) {
  434               throw new XMLStreamException(e);
  435           }
  436   
  437           //  Put a reference to Attachments Map in to the message context For
  438           // backword compatibility with Axis2 1.0 
  439           msgContext.setProperty(MTOMConstants.ATTACHMENTS, attachments);
  440   
  441           // Setting the Attachments map to new SwA API
  442           msgContext.setAttachmentMap(attachments);
  443   
  444           String soapEnvelopeNamespaceURI = getEnvelopeNamespace(contentTypeString);
  445   
  446           if (isSOAP) {
  447               if (attachments.getAttachmentSpecType().equals(
  448                       MTOMConstants.MTOM_TYPE)) {
  449                   //Creates the MTOM specific MTOMStAXSOAPModelBuilder
  450                   builder = new MTOMStAXSOAPModelBuilder(streamReader,
  451                                                          attachments, soapEnvelopeNamespaceURI);
  452                   msgContext.setDoingMTOM(true);
  453               } else if (attachments.getAttachmentSpecType().equals(
  454                       MTOMConstants.SWA_TYPE)) {
  455                   builder = new StAXSOAPModelBuilder(streamReader,
  456                                                      soapEnvelopeNamespaceURI);
  457               } else if (attachments.getAttachmentSpecType().equals(
  458                       MTOMConstants.SWA_TYPE_12)) {
  459                   builder = new StAXSOAPModelBuilder(streamReader,
  460                                                      soapEnvelopeNamespaceURI);
  461               }
  462   
  463           }
  464           // To handle REST XOP case
  465           else {
  466               if (attachments.getAttachmentSpecType().equals(MTOMConstants.MTOM_TYPE)) {
  467                   builder = new XOPAwareStAXOMBuilder(streamReader, attachments);
  468   
  469               } else if (attachments.getAttachmentSpecType().equals(MTOMConstants.SWA_TYPE)) {
  470                   builder = new StAXOMBuilder(streamReader);
  471               } else if (attachments.getAttachmentSpecType().equals(MTOMConstants.SWA_TYPE_12)) {
  472                   builder = new StAXOMBuilder(streamReader);
  473               }
  474           }
  475   
  476           return builder;
  477       }
  478   
  479       protected static Attachments createAttachmentsMap(MessageContext msgContext,
  480                                                         InputStream inStream,
  481                                                         String contentTypeString) {
  482           boolean fileCacheForAttachments = isAttachmentsCacheEnabled(msgContext);
  483   
  484           String attachmentRepoDir = null;
  485           String attachmentSizeThreshold = null;
  486   
  487           if (fileCacheForAttachments) {
  488               Object attachmentRepoDirProperty = msgContext
  489                       .getProperty(Constants.Configuration.ATTACHMENT_TEMP_DIR);
  490   
  491               if (attachmentRepoDirProperty != null) {
  492                   attachmentRepoDir = (String)attachmentRepoDirProperty;
  493               } else {
  494                   Parameter attachmentRepoDirParameter = msgContext
  495                           .getParameter(Constants.Configuration.ATTACHMENT_TEMP_DIR);
  496                   attachmentRepoDir =
  497                           (attachmentRepoDirParameter != null) ? (String)attachmentRepoDirParameter
  498                                   .getValue()
  499                                   : null;
  500               }
  501   
  502               Object attachmentSizeThresholdProperty = msgContext
  503                       .getProperty(Constants.Configuration.FILE_SIZE_THRESHOLD);
  504               if (attachmentSizeThresholdProperty != null
  505                   && attachmentSizeThresholdProperty instanceof String) {
  506                   attachmentSizeThreshold = (String)attachmentSizeThresholdProperty;
  507               } else {
  508                   Parameter attachmentSizeThresholdParameter = msgContext
  509                           .getParameter(Constants.Configuration.FILE_SIZE_THRESHOLD);
  510                   attachmentSizeThreshold = attachmentSizeThresholdParameter
  511                           .getValue().toString();
  512               }
  513           }
  514   
  515           // Get the content-length if it is available
  516           int contentLength = 0;
  517           Map headers = (Map)msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
  518           if (headers != null) {
  519               String contentLengthValue = (String)headers.get(HTTPConstants.HEADER_CONTENT_LENGTH);
  520               if (contentLengthValue != null) {
  521                   try {
  522                       contentLength = new Integer(contentLengthValue);
  523                   } catch (NumberFormatException e) {
  524                       if (log.isDebugEnabled()) {
  525                           log.debug(
  526                                   "Content-Length is not a valid number.  Will assume it is not set:" +
  527                                   e);
  528                       }
  529                   }
  530               }
  531           }
  532           if (log.isDebugEnabled()) {
  533               if (contentLength > 0) {
  534                   log.debug("Creating an Attachments map.  The content-length is" + contentLength);
  535               } else {
  536                   log.debug("Creating an Attachments map.");
  537               }
  538           }
  539           return createAttachments(msgContext,
  540                                    inStream,
  541                                    contentTypeString,
  542                                    fileCacheForAttachments,
  543                                    attachmentRepoDir,
  544                                    attachmentSizeThreshold,
  545                                    contentLength);
  546       }
  547   
  548       public static boolean isAttachmentsCacheEnabled(MessageContext msgContext) {
  549           Object cacheAttachmentProperty = msgContext
  550                   .getProperty(Constants.Configuration.CACHE_ATTACHMENTS);
  551           String cacheAttachmentString;
  552           boolean fileCacheForAttachments;
  553   
  554           if (cacheAttachmentProperty != null && cacheAttachmentProperty instanceof String) {
  555               cacheAttachmentString = (String)cacheAttachmentProperty;
  556           } else {
  557               Parameter parameter_cache_attachment =
  558                       msgContext.getParameter(Constants.Configuration.CACHE_ATTACHMENTS);
  559               cacheAttachmentString = (parameter_cache_attachment != null) ?
  560                       (String)parameter_cache_attachment.getValue() : null;
  561           }
  562           fileCacheForAttachments = (Constants.VALUE_TRUE.equals(cacheAttachmentString));
  563           return fileCacheForAttachments;
  564       }
  565   
  566       public static Attachments createAttachments(MessageContext msgContext,
  567                                                   InputStream inStream,
  568                                                   String contentTypeString,
  569                                                   boolean fileCacheForAttachments,
  570                                                   String attachmentRepoDir,
  571                                                   String attachmentSizeThreshold,
  572                                                   int contentLength) {
  573           LifecycleManager manager = null;
  574           try {
  575               AxisConfiguration configuration = msgContext.getRootContext().getAxisConfiguration();
  576               manager = (LifecycleManager)configuration
  577                       .getParameterValue(DeploymentConstants.ATTACHMENTS_LIFECYCLE_MANAGER);
  578               if (manager == null) {
  579                   manager = new LifecycleManagerImpl();
  580                   configuration.addParameter(DeploymentConstants.ATTACHMENTS_LIFECYCLE_MANAGER,
  581                                              manager);
  582               }
  583           } catch (Exception e) {
  584               if (log.isDebugEnabled()) {
  585                   log.debug("Exception getting Attachments LifecycleManager", e);
  586               }
  587           }
  588           return new Attachments(manager,
  589                                  inStream,
  590                                  contentTypeString,
  591                                  fileCacheForAttachments,
  592                                  attachmentRepoDir,
  593                                  attachmentSizeThreshold,
  594                                  contentLength);
  595       }
  596   
  597       /**
  598        * Utility method to get a StAXBuilder
  599        *
  600        * @param in an InputStream
  601        * @return a StAXSOAPModelBuilder for the given InputStream
  602        * @throws XMLStreamException
  603        * @deprecated If some one really need this method, please shout.
  604        */
  605       public static StAXBuilder getBuilder(Reader in) throws XMLStreamException {
  606           XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(in);
  607           return new StAXSOAPModelBuilder(xmlreader, null);
  608       }
  609   
  610       /**
  611        * Creates an OMBuilder for a plain XML message. Default character set encording is used.
  612        *
  613        * @param inStream InputStream for a XML message
  614        * @return Handler to a OMBuilder implementation instance
  615        * @throws XMLStreamException
  616        */
  617       public static StAXBuilder getBuilder(InputStream inStream) throws XMLStreamException {
  618           XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(inStream);
  619           return new StAXOMBuilder(xmlReader);
  620       }
  621   
  622       /**
  623        * Creates an OMBuilder for a plain XML message.
  624        *
  625        * @param inStream   InputStream for a XML message
  626        * @param charSetEnc Character set encoding to be used
  627        * @return Handler to a OMBuilder implementation instance
  628        * @throws XMLStreamException
  629        */
  630       public static StAXBuilder getBuilder(InputStream inStream, String charSetEnc)
  631               throws XMLStreamException {
  632           XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(inStream, charSetEnc);
  633           try {
  634               return new StAXSOAPModelBuilder(xmlReader);
  635           } catch (OMException e) {
  636               log.info("OMException in getSOAPBuilder", e);
  637               try {
  638                   log.info("Remaining input stream :[" +
  639                            new String(IOUtils.getStreamAsByteArray(inStream), charSetEnc) + "]");
  640               } catch (IOException e1) {
  641                   // Nothing here?
  642               }
  643               throw e;
  644           }
  645       }
  646   
  647       /**
  648        * Creates an OMBuilder for a SOAP message. Default character set encording is used.
  649        *
  650        * @param inStream InputStream for a SOAP message
  651        * @return Handler to a OMBuilder implementation instance
  652        * @throws XMLStreamException
  653        */
  654       public static StAXBuilder getSOAPBuilder(InputStream inStream) throws XMLStreamException {
  655           XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(inStream);
  656           try {
  657               return new StAXSOAPModelBuilder(xmlReader);
  658           } catch (OMException e) {
  659               log.info("OMException in getSOAPBuilder", e);
  660               try {
  661                   log.info("Remaining input stream :[" +
  662                            new String(IOUtils.getStreamAsByteArray(inStream)) + "]");
  663               } catch (IOException e1) {
  664                   // Nothing here?
  665               }
  666               throw e;
  667           }
  668       }
  669   
  670       /**
  671        * Creates an OMBuilder for a SOAP message.
  672        *
  673        * @param inStream   InputStream for a SOAP message
  674        * @param charSetEnc Character set encoding to be used
  675        * @return Handler to a OMBuilder implementation instance
  676        * @throws XMLStreamException
  677        */
  678       public static StAXBuilder getSOAPBuilder(InputStream inStream, String charSetEnc)
  679               throws XMLStreamException {
  680           XMLStreamReader xmlReader = StAXUtils.createXMLStreamReader(inStream, charSetEnc);
  681           try {
  682               return new StAXSOAPModelBuilder(xmlReader);
  683           } catch (OMException e) {
  684               log.info("OMException in getSOAPBuilder", e);
  685               try {
  686                   log.info("Remaining input stream :[" +
  687                            new String(IOUtils.getStreamAsByteArray(inStream), charSetEnc) + "]");
  688               } catch (IOException e1) {
  689                   // Nothing here?
  690               }
  691               throw e;
  692           }
  693       }
  694   
  695       public static StAXBuilder getBuilder(SOAPFactory soapFactory, InputStream in, String charSetEnc)
  696               throws XMLStreamException {
  697           StAXBuilder builder;
  698           XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(in, charSetEnc);
  699           builder = new StAXOMBuilder(soapFactory, xmlreader);
  700           return builder;
  701       }
  702   
  703       /**
  704        * Initial work for a builder selector which selects the builder for a given message format
  705        * based on the the content type of the recieved message. content-type to builder mapping can be
  706        * specified through the Axis2.xml.
  707        *
  708        * @param type       content-type
  709        * @param msgContext the active MessageContext
  710        * @return the builder registered against the given content-type
  711        * @throws AxisFault
  712        */
  713       public static Builder getBuilderFromSelector(String type, MessageContext msgContext)
  714               throws AxisFault {
  715       	boolean useFallbackBuilder = false;
  716           AxisConfiguration configuration =
  717                   msgContext.getConfigurationContext().getAxisConfiguration();
  718           Parameter useFallbackParameter = configuration.getParameter(Constants.Configuration.USE_DEFAULT_FALLBACK_BUILDER);
  719           if (useFallbackParameter !=null){
  720           	useFallbackBuilder = JavaUtils.isTrueExplicitly(useFallbackParameter.getValue(),useFallbackBuilder);
  721           }
  722           Builder builder = configuration.getMessageBuilder(type,useFallbackBuilder);
  723           if (builder != null) {
  724               // Check whether the request has a Accept header if so use that as the response
  725               // message type.
  726               // If thats not present,
  727               // Setting the received content-type as the messageType to make
  728               // sure that we respond using the received message serialization format.
  729   
  730               Object contentNegotiation = configuration
  731                       .getParameterValue(Constants.Configuration.ENABLE_HTTP_CONTENT_NEGOTIATION);
  732               if (JavaUtils.isTrueExplicitly(contentNegotiation)) {
  733                   Map transportHeaders =
  734                           (Map)msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
  735                   if (transportHeaders != null) {
  736                       String acceptHeader = (String)transportHeaders.get(HTTPConstants.HEADER_ACCEPT);
  737                       if (acceptHeader != null) {
  738                           int index = acceptHeader.indexOf(";");
  739                           if (index > 0) {
  740                               acceptHeader = acceptHeader.substring(0, index);
  741                           }
  742                           String[] strings = acceptHeader.split(",");
  743                           for (String string : strings) {
  744                               String accept = string.trim();
  745                               // We dont want dynamic content negotoatin to work on text.xml as its
  746                               // ambiguos as to whether the user requests SOAP 1.1 or POX response
  747                               if (!HTTPConstants.MEDIA_TYPE_TEXT_XML.equals(accept) &&
  748                                   configuration.getMessageFormatter(accept) != null) {
  749                                   type = string;
  750                                   break;
  751                               }
  752                           }
  753                       }
  754                   }
  755               }
  756   
  757               msgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, type);
  758           }
  759           return builder;
  760       }
  761   
  762       public static void validateSOAPVersion(String soapNamespaceURIFromTransport,
  763                                              SOAPEnvelope envelope) {
  764           if (soapNamespaceURIFromTransport != null) {
  765               OMNamespace envelopeNamespace = envelope.getNamespace();
  766               String namespaceName = envelopeNamespace.getNamespaceURI();
  767               if (!(soapNamespaceURIFromTransport.equals(namespaceName))) {
  768                   throw new SOAPProcessingException(
  769                           "Transport level information does not match with SOAP" +
  770                           " Message namespace URI", envelopeNamespace.getPrefix() + ":" +
  771                                                     SOAPConstants.FAULT_CODE_VERSION_MISMATCH);
  772               }
  773           }
  774       }
  775   
  776       public static void validateCharSetEncoding(String charsetEncodingFromTransport,
  777                                                  String charsetEncodingFromXML,
  778                                                  String soapNamespaceURI) throws AxisFault {
  779           if ((charsetEncodingFromXML != null)
  780               && !"".equals(charsetEncodingFromXML)
  781               && (charsetEncodingFromTransport != null)
  782               && !charsetEncodingFromXML.equalsIgnoreCase(charsetEncodingFromTransport)
  783               && !compatibleEncodings(charsetEncodingFromXML, charsetEncodingFromTransport)) {
  784               String faultCode;
  785   
  786               if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
  787                   faultCode = SOAP12Constants.FAULT_CODE_SENDER;
  788               } else {
  789                   faultCode = SOAP11Constants.FAULT_CODE_SENDER;
  790               }
  791   
  792               throw new AxisFault("Character Set Encoding from "
  793                                   + "transport information [" + charsetEncodingFromTransport +
  794                                   "] does not match with "
  795                                   + "character set encoding in the received SOAP message [" +
  796                                   charsetEncodingFromXML + "]", faultCode);
  797           }
  798       }
  799   
  800       /**
  801        * check if the pair is [UTF-16,UTF-16LE] [UTF-32, UTF-32LE],[UTF-16,UTF-16BE] [UTF-32,
  802        * UTF-32BE] etc.
  803        *
  804        * @param enc1 encoding style
  805        * @param enc2 encoding style
  806        * @return true if the encoding styles are compatible, or false otherwise
  807        */
  808       private static boolean compatibleEncodings(String enc1, String enc2) {
  809           enc1 = enc1.toLowerCase();
  810           enc2 = enc2.toLowerCase();
  811           if (enc1.endsWith("be") || enc1.endsWith("le")) {
  812               enc1 = enc1.substring(0, enc1.length() - 2);
  813           }
  814           if (enc2.endsWith("be") || enc2.endsWith("le")) {
  815               enc2 = enc2.substring(0, enc2.length() - 2);
  816           }
  817           return enc1.equals(enc2);
  818       }
  819   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » builder » [javadoc | source]