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: package org.apache.axis2.jaxws.message.util.impl;
020:
021: import org.apache.axiom.om.OMElement;
022: import org.apache.axiom.om.OMNamespace;
023: import org.apache.axiom.om.OMException;
024: import org.apache.axiom.om.util.StAXUtils;
025: import org.apache.axiom.om.impl.builder.StAXOMBuilder;
026: import org.apache.axiom.om.impl.dom.ElementImpl;
027: import org.apache.axiom.soap.SOAP11Constants;
028: import org.apache.axiom.soap.SOAP12Constants;
029: import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
030: import org.apache.axis2.jaxws.ExceptionFactory;
031: import org.apache.axis2.jaxws.i18n.Messages;
032: import org.apache.axis2.jaxws.message.util.SAAJConverter;
033: import org.apache.axis2.jaxws.message.util.SOAPElementReader;
034: import org.apache.axis2.jaxws.utility.SAAJFactory;
035: import org.apache.axis2.util.XMLUtils;
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038: import org.w3c.dom.Node;
039:
040: import javax.xml.namespace.QName;
041: import javax.xml.soap.Detail;
042: import javax.xml.soap.MessageFactory;
043: import javax.xml.soap.Name;
044: import javax.xml.soap.SOAPBody;
045: import javax.xml.soap.SOAPElement;
046: import javax.xml.soap.SOAPEnvelope;
047: import javax.xml.soap.SOAPException;
048: import javax.xml.soap.SOAPFactory;
049: import javax.xml.soap.SOAPFault;
050: import javax.xml.soap.SOAPHeader;
051: import javax.xml.soap.SOAPMessage;
052: import javax.xml.soap.SOAPPart;
053: import javax.xml.stream.XMLStreamException;
054: import javax.xml.stream.XMLStreamReader;
055: import javax.xml.ws.WebServiceException;
056: import javax.xml.transform.TransformerFactory;
057: import javax.xml.transform.Transformer;
058: import javax.xml.transform.TransformerException;
059: import javax.xml.transform.TransformerConfigurationException;
060: import javax.xml.transform.dom.DOMSource;
061: import javax.xml.transform.stream.StreamSource;
062: import javax.xml.transform.stream.StreamResult;
063: import java.util.Iterator;
064: import java.io.ByteArrayOutputStream;
065: import java.io.ByteArrayInputStream;
066:
067: /** SAAJConverterImpl Provides an conversion methods between OM<->SAAJ */
068: public class SAAJConverterImpl implements SAAJConverter {
069:
070: private static final Log log = LogFactory
071: .getLog(SAAJConverterImpl.class);
072:
073: /** Constructed via SAAJConverterFactory */
074: SAAJConverterImpl() {
075: super ();
076: }
077:
078: /* (non-Javadoc)
079: * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toSAAJ(org.apache.axiom.soap.SOAPEnvelope)
080: */
081: public SOAPEnvelope toSAAJ(
082: org.apache.axiom.soap.SOAPEnvelope omEnvelope)
083: throws WebServiceException {
084: SOAPEnvelope soapEnvelope = null;
085: try {
086: // Build the default envelope
087: OMNamespace ns = omEnvelope.getNamespace();
088: MessageFactory mf = createMessageFactory(ns
089: .getNamespaceURI());
090: SOAPMessage sm = mf.createMessage();
091: SOAPPart sp = sm.getSOAPPart();
092: soapEnvelope = sp.getEnvelope();
093:
094: // The getSOAPEnvelope() call creates a default SOAPEnvelope with a SOAPHeader and SOAPBody.
095: // The SOAPHeader and SOAPBody are removed (they will be added back in if they are present in the
096: // OMEnvelope).
097: SOAPBody soapBody = soapEnvelope.getBody();
098: if (soapBody != null) {
099: soapBody.detachNode();
100: }
101: SOAPHeader soapHeader = soapEnvelope.getHeader();
102: if (soapHeader != null) {
103: soapHeader.detachNode();
104: }
105:
106: // We don't know if there is a real OM tree or just a backing XMLStreamReader.
107: // The best way to walk the data is to get the XMLStreamReader and use this
108: // to build the SOAPElements
109: XMLStreamReader reader = omEnvelope.getXMLStreamReader();
110:
111: NameCreator nc = new NameCreator(soapEnvelope);
112: buildSOAPTree(nc, soapEnvelope, null, reader, false);
113: } catch (WebServiceException e) {
114: throw e;
115: } catch (SOAPException e) {
116: throw ExceptionFactory.makeWebServiceException(e);
117: }
118: return soapEnvelope;
119: }
120:
121: /* (non-Javadoc)
122: * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toOM(javax.xml.soap.SOAPEnvelope)
123: */
124: public org.apache.axiom.soap.SOAPEnvelope toOM(
125: SOAPEnvelope saajEnvelope) throws WebServiceException {
126: if (log.isDebugEnabled()) {
127: log
128: .debug("Converting SAAJ SOAPEnvelope to an OM SOAPEnvelope");
129: }
130:
131: // Before we do the conversion, we have to fix the QNames for fault elements
132: _fixFaultElements(saajEnvelope);
133: // Get a XMLStreamReader backed by a SOAPElement tree
134: XMLStreamReader reader = new SOAPElementReader(saajEnvelope);
135: // Get a SOAP OM Builder. Passing null causes the version to be automatically triggered
136: StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader,
137: null);
138: // Create and return the OM Envelope
139: org.apache.axiom.soap.SOAPEnvelope omEnvelope = builder
140: .getSOAPEnvelope();
141:
142: // TODO The following statement expands the OM tree. This is
143: // a brute force workaround to get around an apparent bug in the om serialization
144: // (the pull stream parsing was not pulling the final tag).
145: // Four things need to occur:
146: // a) analyze fix the serialization/pull stream problem.
147: // b) add a method signature to allow the caller to request build or no build
148: // c) add a method signature to allow the caller to enable/disable caching
149: // d) possibly add an optimization to use OMSE for the body elements...to flatten the tree.
150: try {
151: omEnvelope.build();
152: } catch (OMException ex) {
153: try {
154: // Let's try to see if we can save the envelope as a string
155: // and then make it into axiom SOAPEnvelope
156: return toOM(toString(saajEnvelope));
157: } catch (TransformerException e) {
158: throw ExceptionFactory.makeWebServiceException(e);
159: }
160: }
161: return omEnvelope;
162: }
163:
164: private org.apache.axiom.soap.SOAPEnvelope toOM(String xml)
165: throws WebServiceException {
166: XMLStreamReader reader;
167: try {
168: reader = StAXUtils
169: .createXMLStreamReader(new ByteArrayInputStream(xml
170: .getBytes()));
171: } catch (XMLStreamException e) {
172: throw ExceptionFactory.makeWebServiceException(e);
173: }
174: // Get a SOAP OM Builder. Passing null causes the version to be automatically triggered
175: StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader,
176: null);
177: // Create and return the OM Envelope
178: return builder.getSOAPEnvelope();
179: }
180:
181: private String toString(SOAPEnvelope saajEnvelope)
182: throws TransformerException {
183: ByteArrayOutputStream baos = new ByteArrayOutputStream();
184: Transformer tf;
185: tf = TransformerFactory.newInstance().newTransformer();
186: tf.transform(new DOMSource(saajEnvelope.getOwnerDocument()),
187: new StreamResult(baos));
188: return new String(baos.toByteArray());
189: }
190:
191: /* (non-Javadoc)
192: * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toOM(javax.xml.soap.SOAPElement)
193: */
194: public OMElement toOM(SOAPElement soapElement)
195: throws WebServiceException {
196: if (log.isDebugEnabled()) {
197: log.debug("Converting SAAJ SOAPElement to an OMElement");
198: }
199:
200: // Get a XMLStreamReader backed by a SOAPElement tree
201: XMLStreamReader reader = new SOAPElementReader(soapElement);
202: // Get a OM Builder.
203: StAXOMBuilder builder = new StAXOMBuilder(reader);
204: // Create and return the Element
205: OMElement om = builder.getDocumentElement();
206: // TODO The following statement expands the OM tree. This is
207: // a brute force workaround to get around an apparent bug in the om serialization
208: // (the pull stream parsing was not pulling the final tag).
209: // Three things need to occur:
210: // a) analyze fix the serialization/pull stream problem.
211: // b) add a method signature to allow the caller to request build or no build
212: // c) add a method signature to allow the caller to enable/disable caching
213: om.build();
214: return om;
215: }
216:
217: /* (non-Javadoc)
218: * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toSAAJ(org.apache.axiom.om.OMElement, javax.xml.soap.SOAPElement)
219: */
220: public SOAPElement toSAAJ(OMElement omElement, SOAPElement parent)
221: throws WebServiceException {
222: if (log.isDebugEnabled()) {
223: log.debug("Converting OMElement to an SAAJ SOAPElement");
224: }
225:
226: XMLStreamReader reader = null;
227:
228: // If the OM element is not attached to a parser (builder), then the OM
229: // is built and you cannot ask for XMLStreamReaderWithoutCaching.
230: // This is probably a bug in OM. You should be able to ask the OM whether
231: // caching is supported.
232: if (omElement.getBuilder() == null) {
233: reader = omElement.getXMLStreamReader();
234: } else {
235: reader = omElement.getXMLStreamReaderWithoutCaching();
236: }
237: SOAPElement env = parent;
238: while (env != null && !(env instanceof SOAPEnvelope)) {
239: env = env.getParentElement();
240: }
241: if (env == null) {
242: throw ExceptionFactory.makeWebServiceException(Messages
243: .getMessage("SAAJConverterErr1"));
244: }
245: NameCreator nc = new NameCreator((SOAPEnvelope) env);
246: return buildSOAPTree(nc, null, parent, reader, false);
247: }
248:
249: /* (non-Javadoc)
250: * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toSAAJ(org.apache.axiom.om.OMElement, javax.xml.soap.SOAPElement, javax.xml.soap.SOAPFactory)
251: */
252: public SOAPElement toSAAJ(OMElement omElement, SOAPElement parent,
253: SOAPFactory sf) throws WebServiceException {
254: if (log.isDebugEnabled()) {
255: log.debug("Converting OMElement to an SAAJ SOAPElement");
256: }
257:
258: XMLStreamReader reader = null;
259:
260: // If the OM element is not attached to a parser (builder), then the OM
261: // is built and you cannot ask for XMLStreamReaderWithoutCaching.
262: // This is probably a bug in OM. You should be able to ask the OM whether
263: // caching is supported.
264: if (omElement.getBuilder() == null) {
265: reader = omElement.getXMLStreamReader();
266: } else {
267: reader = omElement.getXMLStreamReaderWithoutCaching();
268: }
269: NameCreator nc = new NameCreator(sf);
270: return buildSOAPTree(nc, null, parent, reader, false);
271: }
272:
273: /**
274: * Build SOAPTree Either the root or the parent is null. If the root is null, a new element is
275: * created under the parent using information from the reader If the parent is null, the existing
276: * root is updated with the information from the reader
277: *
278: * @param nc NameCreator
279: * @param root SOAPElement (the element that represents the data in the reader)
280: * @param parent (the parent of the element represented by the reader)
281: * @param reader XMLStreamReader. the first START_ELEMENT matches the root
282: * @param quitAtBody - true if quit reading after the body START_ELEMENT
283: */
284: protected SOAPElement buildSOAPTree(NameCreator nc,
285: SOAPElement root, SOAPElement parent,
286: XMLStreamReader reader, boolean quitAtBody)
287: throws WebServiceException {
288: try {
289: while (reader.hasNext()) {
290: int eventID = reader.next();
291: switch (eventID) {
292: case XMLStreamReader.START_ELEMENT: {
293:
294: // The first START_ELEMENT defines the prefix and attributes of the root
295: if (parent == null) {
296: updateTagData(nc, root, reader, false);
297: parent = root;
298: } else {
299: parent = createElementFromTag(nc, parent,
300: reader);
301: if (root == null) {
302: root = parent;
303: }
304: }
305: if (quitAtBody && parent instanceof SOAPBody) {
306: return root;
307: }
308: break;
309: }
310: case XMLStreamReader.ATTRIBUTE: {
311: String eventName = "ATTRIBUTE";
312: this ._unexpectedEvent(eventName);
313: }
314: case XMLStreamReader.NAMESPACE: {
315: String eventName = "NAMESPACE";
316: this ._unexpectedEvent(eventName);
317: }
318: case XMLStreamReader.END_ELEMENT: {
319: if (parent instanceof SOAPEnvelope) {
320: parent = null;
321: } else {
322: parent = parent.getParentElement();
323: }
324: break;
325: }
326: case XMLStreamReader.CHARACTERS: {
327: parent.addTextNode(reader.getText());
328: break;
329: }
330: case XMLStreamReader.CDATA: {
331: parent.addTextNode(reader.getText());
332: break;
333: }
334: case XMLStreamReader.COMMENT: {
335: // SOAP really doesn't have an adequate representation for comments.
336: // The defacto standard is to add the whole element as a text node.
337: parent.addTextNode("<!--" + reader.getText()
338: + "-->");
339: break;
340: }
341: case XMLStreamReader.SPACE: {
342: parent.addTextNode(reader.getText());
343: break;
344: }
345: case XMLStreamReader.START_DOCUMENT: {
346: // Ignore
347: break;
348: }
349: case XMLStreamReader.END_DOCUMENT: {
350: // Close reader and ignore
351: reader.close();
352: break;
353: }
354: case XMLStreamReader.PROCESSING_INSTRUCTION: {
355: // Ignore
356: break;
357: }
358: case XMLStreamReader.ENTITY_REFERENCE: {
359: // Ignore. this is unexpected in a web service message
360: break;
361: }
362: case XMLStreamReader.DTD: {
363: // Ignore. this is unexpected in a web service message
364: break;
365: }
366: default:
367: this ._unexpectedEvent("EventID "
368: + String.valueOf(eventID));
369: }
370: }
371: } catch (WebServiceException e) {
372: throw e;
373: } catch (XMLStreamException e) {
374: throw ExceptionFactory.makeWebServiceException(e);
375: } catch (SOAPException e) {
376: throw ExceptionFactory.makeWebServiceException(e);
377: }
378: return root;
379: }
380:
381: /**
382: * Create SOAPElement from the current tag data
383: *
384: * @param nc NameCreator
385: * @param parent SOAPElement for the new SOAPElement
386: * @param reader XMLStreamReader whose cursor is at the START_ELEMENT
387: * @return
388: */
389: protected SOAPElement createElementFromTag(NameCreator nc,
390: SOAPElement parent, XMLStreamReader reader)
391: throws SOAPException {
392: // Unfortunately, the SAAJ object is a product of both the
393: // QName of the element and the parent object. For example,
394: // All element children of a SOAPBody must be object's that are SOAPBodyElements.
395: // createElement creates the proper child element.
396: QName qName = reader.getName();
397: SOAPElement child = createElement(parent, qName);
398:
399: // Update the tag data on the child
400: updateTagData(nc, child, reader, true);
401: return child;
402: }
403:
404: /**
405: * Create child SOAPElement
406: *
407: * @param parent SOAPElement
408: * @param name Name
409: * @return
410: */
411: protected SOAPElement createElement(SOAPElement parent, QName qName)
412: throws SOAPException {
413: SOAPElement child;
414: if (parent instanceof SOAPEnvelope) {
415: if (qName.getNamespaceURI()
416: .equals(parent.getNamespaceURI())) {
417: if (qName.getLocalPart().equals("Body")) {
418: child = ((SOAPEnvelope) parent).addBody();
419: } else {
420: child = ((SOAPEnvelope) parent).addHeader();
421: }
422: } else {
423: child = parent.addChildElement(qName);
424: }
425: } else if (parent instanceof SOAPBody) {
426: if (qName.getNamespaceURI()
427: .equals(parent.getNamespaceURI())
428: && qName.getLocalPart().equals("Fault")) {
429: child = ((SOAPBody) parent).addFault();
430: } else {
431: child = ((SOAPBody) parent).addBodyElement(qName);
432: }
433: } else if (parent instanceof SOAPHeader) {
434: child = ((SOAPHeader) parent).addHeaderElement(qName);
435: } else if (parent instanceof SOAPFault) {
436: // This call assumes that the addChildElement implementation
437: // is smart enough to add "Detail" or "SOAPFaultElement" objects.
438: child = parent.addChildElement(qName);
439: } else if (parent instanceof Detail) {
440: child = ((Detail) parent).addDetailEntry(qName);
441: } else {
442: child = parent.addChildElement(qName);
443: }
444:
445: return child;
446: }
447:
448: /**
449: * update the tag data of the SOAPElement
450: *
451: * @param NameCreator nc
452: * @param element SOAPElement
453: * @param reader XMLStreamReader whose cursor is at START_ELEMENT
454: */
455: protected void updateTagData(NameCreator nc, SOAPElement element,
456: XMLStreamReader reader, boolean newElement)
457: throws SOAPException {
458: String prefix = reader.getPrefix();
459: prefix = (prefix == null) ? "" : prefix;
460:
461: // Make sure the prefix is correct
462: if (prefix.length() > 0 && !element.getPrefix().equals(prefix)) {
463: // Due to a bug in Axiom DOM or in the reader...not sure where yet,
464: // there may be a non-null prefix and no namespace
465: String ns = reader.getNamespaceURI();
466: if (ns != null && ns.length() != 0) {
467: element.setPrefix(prefix);
468: }
469:
470: }
471:
472: if (!newElement) {
473: // Add the namespace declarations from the reader for the missing namespaces
474: int size = reader.getNamespaceCount();
475: for (int i = 0; i < size; i++) {
476: String pre = reader.getNamespacePrefix(i);
477: String ns = reader.getNamespaceURI(i);
478: String existingNS = element.getNamespaceURI(pre);
479: if (!ns.equals(existingNS)) {
480: element.removeNamespaceDeclaration(pre); // Is it necessary to remove the existing prefix/ns
481: element.addNamespaceDeclaration(pre, ns);
482: }
483: }
484: } else {
485: // Add the namespace declarations from the reader
486: int size = reader.getNamespaceCount();
487: for (int i = 0; i < size; i++) {
488: element.addNamespaceDeclaration(reader
489: .getNamespacePrefix(i), reader
490: .getNamespaceURI(i));
491: }
492: }
493:
494: addAttributes(nc, element, reader);
495:
496: return;
497: }
498:
499: /**
500: * add attributes
501: *
502: * @param NameCreator nc
503: * @param element SOAPElement which is the target of the new attributes
504: * @param reader XMLStreamReader whose cursor is at START_ELEMENT
505: * @throws SOAPException
506: */
507: protected void addAttributes(NameCreator nc, SOAPElement element,
508: XMLStreamReader reader) throws SOAPException {
509:
510: // Add the attributes from the reader
511: int size = reader.getAttributeCount();
512: for (int i = 0; i < size; i++) {
513: QName qName = reader.getAttributeName(i);
514: String prefix = reader.getAttributePrefix(i);
515: String value = reader.getAttributeValue(i);
516: Name name = nc.createName(qName.getLocalPart(), prefix,
517: qName.getNamespaceURI());
518: element.addAttribute(name, value);
519: }
520: }
521:
522: private void _unexpectedEvent(String event)
523: throws WebServiceException {
524: // Review We need NLS for this message, but this code will probably
525: // be added to JAX-WS. So for now we there is no NLS.
526: // TODO NLS
527: throw ExceptionFactory.makeWebServiceException(Messages
528: .getMessage("SAAJConverterErr2", event));
529: }
530:
531: /*
532: * A utility method to fix the localnames of elements with an Axis2 SAAJ
533: * tree. The SAAJ impl relies on the Axiom SOAP APIs, which represent
534: * all faults as SOAP 1.2. This has to be corrected before we can convert
535: * to OM or the faults will not be handled correctly.
536: */
537: private void _fixFaultElements(SOAPEnvelope env) {
538: try {
539: // If we have a SOAP 1.2 envelope, then there's nothing to do.
540: if (env.getNamespaceURI().equals(
541: SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
542: return;
543: }
544:
545: SOAPBody body = env.getBody();
546: if (body != null && !body.hasFault()) {
547: if (log.isDebugEnabled()) {
548: log
549: .debug("No fault found. No conversion necessary.");
550: }
551: return;
552: } else if (body != null && body.hasFault()) {
553: if (log.isDebugEnabled()) {
554: log
555: .debug("A fault was found. Converting the fault child elements to SOAP 1.1 format");
556: }
557:
558: SOAPFault fault = body.getFault();
559:
560: Iterator itr = fault.getChildElements();
561: while (itr.hasNext()) {
562: SOAPElement se = (SOAPElement) itr.next();
563: if (se.getLocalName().equals(
564: SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME)) {
565: if (log.isDebugEnabled()) {
566: log.debug("Converting: faultcode");
567: }
568: // Axis2 SAAJ stores the acutal faultcode text under a SOAPFaultValue object, so we have to
569: // get that and add it as a text node under the original element.
570: Node value = se.getFirstChild();
571: if (value != null
572: && value instanceof org.apache.axis2.saaj.SOAPElementImpl) {
573: org.apache.axis2.saaj.SOAPElementImpl valueElement = (org.apache.axis2.saaj.SOAPElementImpl) value;
574: ElementImpl e = valueElement.getElement();
575: String content = e.getText();
576:
577: SOAPElement child = fault
578: .addChildElement(new QName(
579: se.getNamespaceURI(),
580: SOAP11Constants.SOAP_FAULT_CODE_LOCAL_NAME));
581: child.addTextNode(content);
582:
583: se.detachNode();
584: }
585: } else if (se
586: .getLocalName()
587: .equals(
588: SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME)) {
589: if (log.isDebugEnabled()) {
590: log.debug("Converting: detail");
591: }
592: se
593: .setElementQName(new QName(
594: se.getNamespaceURI(),
595: SOAP11Constants.SOAP_FAULT_DETAIL_LOCAL_NAME));
596: } else if (se
597: .getLocalName()
598: .equals(
599: SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME)) {
600: if (log.isDebugEnabled()) {
601: log.debug("Converting: faultstring");
602: }
603: se
604: .setElementQName(new QName(
605: se.getNamespaceURI(),
606: SOAP11Constants.SOAP_FAULT_STRING_LOCAL_NAME));
607: // Axis2 SAAJ stores the acutal faultstring text under a SOAPFaultValue object, so we have to
608: // get that and add it as a text node under the original element.
609: Node value = se.getFirstChild();
610: if (value != null
611: && value instanceof org.apache.axis2.saaj.SOAPElementImpl) {
612: org.apache.axis2.saaj.SOAPElementImpl valueElement = (org.apache.axis2.saaj.SOAPElementImpl) value;
613: ElementImpl e = valueElement.getElement();
614: String content = e.getText();
615:
616: SOAPElement child = fault
617: .addChildElement(new QName(
618: se.getNamespaceURI(),
619: SOAP11Constants.SOAP_FAULT_STRING_LOCAL_NAME));
620: child.addTextNode(content);
621:
622: se.detachNode();
623: }
624: }
625: }
626: }
627: } catch (SOAPException e) {
628: if (log.isDebugEnabled()) {
629: log
630: .debug("An error occured while converting fault elements: "
631: + e.getMessage());
632: }
633: throw ExceptionFactory.makeWebServiceException(e);
634: }
635: }
636:
637: /**
638: * A Name can be created from either a SOAPEnvelope or SOAPFactory. Either one or the other is
639: * available when the converter is called. NameCreator provides a level of abstraction which
640: * simplifies the code.
641: */
642: protected class NameCreator {
643: private SOAPEnvelope env = null;
644: private SOAPFactory sf = null;
645:
646: public NameCreator(SOAPEnvelope env) {
647: this .env = env;
648: }
649:
650: public NameCreator(SOAPFactory sf) {
651: this .sf = sf;
652: }
653:
654: /**
655: * Creates a Name
656: *
657: * @param localName
658: * @param prefix
659: * @param uri
660: * @return Name
661: */
662: public Name createName(String localName, String prefix,
663: String uri) throws SOAPException {
664: if (sf != null) {
665: return sf.createName(localName, prefix, uri);
666: } else {
667: return env.createName(localName, prefix, uri);
668: }
669: }
670:
671: }
672:
673: public MessageFactory createMessageFactory(String namespace)
674: throws SOAPException, WebServiceException {
675: return SAAJFactory.createMessageFactory(namespace);
676: }
677: }
|