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