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.addressing;
020:
021: import org.apache.axiom.om.OMAttribute;
022: import org.apache.axiom.om.OMElement;
023: import org.apache.axiom.om.OMFactory;
024: import org.apache.axiom.om.OMNamespace;
025: import org.apache.axiom.om.OMNode;
026: import org.apache.axiom.om.impl.builder.StAXOMBuilder;
027: import org.apache.axiom.om.util.AttributeHelper;
028: import org.apache.axiom.om.util.ElementHelper;
029: import org.apache.axiom.soap.SOAPFactory;
030: import org.apache.axis2.AxisFault;
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033:
034: import javax.xml.namespace.QName;
035: import javax.xml.stream.XMLStreamException;
036: import java.io.ByteArrayInputStream;
037: import java.util.ArrayList;
038: import java.util.IdentityHashMap;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.Map;
042:
043: /**
044: * The methods in this class are used to process {@link EndpointReference} objects
045: * according to the rules of the 2005/08 (Final) and 2004/08 (submission) WS-Addressing
046: * specifications.
047: */
048: public class EndpointReferenceHelper {
049:
050: private static final Log log = LogFactory
051: .getLog(EndpointReferenceHelper.class);
052:
053: private final static Map finalQNames = new IdentityHashMap();
054: private final static Map submissionQNames = new IdentityHashMap();
055:
056: /**
057: * Populates an endpoint reference based on the <code>OMElement</code> and
058: * WS-Addressing namespace that is passed in. If the string passed in is not
059: * recognized as a valid WS-Addressing namespace then this method behaves as
060: * if http://www.w3.org/2005/08/addressing has been passed in.
061: *
062: * @param epr an endpoint reference instance to hold the info.
063: * @param eprOMElement an element of endpoint reference type
064: * @param addressingNamespace the namespace of the WS-Addressing spec to comply with.
065: * @throws AxisFault if unable to locate an address element
066: * @see #fromOM(OMElement)
067: */
068: public static void fromOM(EndpointReference epr,
069: OMElement eprOMElement, String addressingNamespace)
070: throws AxisFault {
071: boolean isFinalAddressingNamespace = false;
072: Map map = null;
073:
074: //First pass, identify the addressing namespace.
075: if (AddressingConstants.Submission.WSA_NAMESPACE
076: .equals(addressingNamespace)) {
077: OMElement address = eprOMElement
078: .getFirstChildWithName((QName) submissionQNames
079: .get(AddressingConstants.EPR_ADDRESS));
080:
081: if (address != null) {
082: map = submissionQNames;
083: isFinalAddressingNamespace = false;
084:
085: if (log.isDebugEnabled()) {
086: log
087: .debug("fromOM: Found address element for namespace, "
088: + AddressingConstants.Submission.WSA_NAMESPACE);
089: }
090: } else {
091: throw new AxisFault(
092: "Unable to locate an address element for the endpoint reference type.");
093: }
094: } else {
095: OMElement address = eprOMElement
096: .getFirstChildWithName((QName) finalQNames
097: .get(AddressingConstants.EPR_ADDRESS));
098:
099: if (address != null) {
100: map = finalQNames;
101: isFinalAddressingNamespace = true;
102:
103: if (log.isDebugEnabled()) {
104: log
105: .debug("fromOM: Found address element for namespace, "
106: + AddressingConstants.Final.WSA_NAMESPACE);
107: }
108: } else {
109: throw new AxisFault(
110: "Unable to locate an address element for the endpoint reference type.");
111: }
112: }
113:
114: //Second pass, identify the properties.
115: fromOM(epr, eprOMElement, map, isFinalAddressingNamespace);
116: }
117:
118: /**
119: * Populates an endpoint reference based on the <code>String</code> that is
120: * passed in. If the http://schemas.xmlsoap.org/ws/2004/08/addressing namespace
121: * is in effect then any reference properties will be saved as reference parameters.
122: * Regardless of the addressing namespace in effect, any elements present in the
123: * <code>String</code> that are not recognised are saved as extensibility elements.
124: *
125: * @param eprString string from the element of endpoint reference type
126: * @throws AxisFault if unable to locate an address element
127: */
128: public static EndpointReference fromOM(String eprString)
129: throws AxisFault {
130: try {
131: return fromOM(new StAXOMBuilder(new ByteArrayInputStream(
132: eprString.getBytes())).getDocumentElement());
133: } catch (XMLStreamException e) {
134: throw AxisFault.makeFault(e);
135: }
136: }
137:
138: /**
139: * Populates an endpoint reference based on the <code>OMElement</code> that is
140: * passed in. If the http://schemas.xmlsoap.org/ws/2004/08/addressing namespace
141: * is in effect then any reference properties will be saved as reference parameters.
142: * Regardless of the addressing namespace in effect, any elements present in the
143: * <code>OMElement</code> that are not recognised are saved as extensibility elements.
144: *
145: * @param eprOMElement an element of endpoint reference type
146: * @throws AxisFault if unable to locate an address element
147: */
148: public static EndpointReference fromOM(OMElement eprOMElement)
149: throws AxisFault {
150: EndpointReference epr = new EndpointReference("");
151: boolean isFinalAddressingNamespace = false;
152: Map map = null;
153:
154: //First pass, identify the addressing namespace.
155: OMElement address = eprOMElement
156: .getFirstChildWithName((QName) finalQNames
157: .get(AddressingConstants.EPR_ADDRESS));
158:
159: if (address != null) {
160: map = finalQNames;
161: isFinalAddressingNamespace = true;
162:
163: if (log.isDebugEnabled()) {
164: log
165: .debug("fromOM: Found address element for namespace, "
166: + AddressingConstants.Final.WSA_NAMESPACE);
167: }
168: } else {
169: address = eprOMElement
170: .getFirstChildWithName((QName) submissionQNames
171: .get(AddressingConstants.EPR_ADDRESS));
172:
173: if (address != null) {
174: map = submissionQNames;
175: isFinalAddressingNamespace = false;
176:
177: if (log.isDebugEnabled()) {
178: log
179: .debug("fromOM: Found address element for namespace, "
180: + AddressingConstants.Submission.WSA_NAMESPACE);
181: }
182: } else {
183: throw new AxisFault(
184: "Unable to locate an address element for the endpoint reference type.");
185: }
186: }
187:
188: //Second pass, identify the properties.
189: fromOM(epr, eprOMElement, map, isFinalAddressingNamespace);
190:
191: return epr;
192: }
193:
194: /**
195: * Creates an <code>OMElement</code> based on the properties of the endpoint
196: * reference. The output may differ based on the addressing namespace that is
197: * in effect when this method is called. If the http://www.w3.org/2005/08/addressing
198: * namespace is in effect, and a metadata property has been defined for the
199: * endpoint reference, then there will be a metadata element to contain the
200: * property in the output. If the http://schemas.xmlsoap.org/ws/2004/08/addressing
201: * namespace is in effect, however, then no metadata element will be included
202: * in the output, even if a metadata property element has been defined.
203: *
204: * @param factory
205: * @param epr
206: * @param qname
207: * @param addressingNamespace
208: * @return
209: * @throws AxisFault
210: */
211: public static OMElement toOM(OMFactory factory,
212: EndpointReference epr, QName qname,
213: String addressingNamespace) throws AxisFault {
214: OMElement eprElement = null;
215:
216: if (log.isDebugEnabled()) {
217: log.debug("toOM: Factory, " + factory);
218: log.debug("toOM: Endpoint reference, " + epr);
219: log.debug("toOM: Element qname, " + qname);
220: log.debug("toOM: Addressing namespace, "
221: + addressingNamespace);
222: }
223:
224: if (addressingNamespace == null) {
225: throw new AxisFault("Addressing namespace cannot be null.");
226: }
227:
228: if (qname.getPrefix() != null) {
229: OMNamespace wrapNs = factory.createOMNamespace(qname
230: .getNamespaceURI(), qname.getPrefix());
231: if (factory instanceof SOAPFactory) {
232: eprElement = ((SOAPFactory) factory)
233: .createSOAPHeaderBlock(qname.getLocalPart(),
234: wrapNs);
235: } else {
236: eprElement = factory.createOMElement(qname
237: .getLocalPart(), wrapNs);
238: }
239:
240: OMNamespace wsaNS = factory.createOMNamespace(
241: addressingNamespace,
242: AddressingConstants.WSA_DEFAULT_PREFIX);
243: OMElement addressE = factory.createOMElement(
244: AddressingConstants.EPR_ADDRESS, wsaNS, eprElement);
245: String address = epr.getAddress();
246: addressE.setText(address);
247:
248: ArrayList addressAttributes = epr.getAddressAttributes();
249: if (addressAttributes != null) {
250: Iterator attrIter = addressAttributes.iterator();
251: while (attrIter.hasNext()) {
252: OMAttribute omAttributes = (OMAttribute) attrIter
253: .next();
254: addressE.addAttribute(omAttributes);
255: }
256: }
257:
258: List metaData = epr.getMetaData();
259: if (metaData != null
260: && AddressingConstants.Final.WSA_NAMESPACE
261: .equals(addressingNamespace)) {
262: OMElement metadataE = factory.createOMElement(
263: AddressingConstants.Final.WSA_METADATA, wsaNS,
264: eprElement);
265: for (int i = 0, size = metaData.size(); i < size; i++) {
266: OMElement omElement = (OMElement) metaData.get(i);
267: metadataE.addChild(ElementHelper.importOMElement(
268: omElement, factory));
269: }
270:
271: ArrayList metadataAttributes = epr
272: .getMetadataAttributes();
273: if (metadataAttributes != null) {
274: Iterator attrIter = metadataAttributes.iterator();
275: while (attrIter.hasNext()) {
276: OMAttribute omAttributes = (OMAttribute) attrIter
277: .next();
278: metadataE.addAttribute(omAttributes);
279: }
280: }
281: }
282:
283: Map referenceParameters = epr.getAllReferenceParameters();
284: if (referenceParameters != null) {
285: OMElement refParameterElement = factory
286: .createOMElement(
287: AddressingConstants.EPR_REFERENCE_PARAMETERS,
288: wsaNS, eprElement);
289: Iterator iterator = referenceParameters.values()
290: .iterator();
291: while (iterator.hasNext()) {
292: OMElement omElement = (OMElement) iterator.next();
293: refParameterElement.addChild(ElementHelper
294: .importOMElement(omElement, factory));
295: }
296: }
297:
298: List attributes = epr.getAttributes();
299: if (attributes != null) {
300: for (int i = 0, size = attributes.size(); i < size; i++) {
301: OMAttribute omAttribute = (OMAttribute) attributes
302: .get(i);
303: AttributeHelper.importOMAttribute(omAttribute,
304: eprElement);
305: }
306: }
307:
308: // add xs:any
309: List extensibleElements = epr.getExtensibleElements();
310: if (extensibleElements != null) {
311: for (int i = 0, size = extensibleElements.size(); i < size; i++) {
312: OMElement omElement = (OMElement) extensibleElements
313: .get(i);
314: eprElement.addChild(ElementHelper.importOMElement(
315: omElement, factory));
316: }
317: }
318: } else {
319: throw new AxisFault("prefix must be specified");
320: }
321:
322: return eprElement;
323: }
324:
325: private static void fromOM(EndpointReference epr,
326: OMElement eprOMElement, Map map,
327: boolean isFinalAddressingNamespace) {
328: Iterator childElements = eprOMElement.getChildElements();
329:
330: while (childElements.hasNext()) {
331: OMElement eprChildElement = (OMElement) childElements
332: .next();
333: QName qname = eprChildElement.getQName();
334:
335: if (map.get(AddressingConstants.EPR_ADDRESS).equals(qname)) {
336: //We need to identify the address element again in order to ensure
337: //that it is not included with the extensibility elements.
338: epr.setAddress(eprChildElement.getText());
339: Iterator allAddrAttributes = eprChildElement
340: .getAllAttributes();
341: ArrayList addressAttributes = new ArrayList();
342: while (allAddrAttributes.hasNext()) {
343: OMAttribute attribute = (OMAttribute) allAddrAttributes
344: .next();
345: addressAttributes.add(attribute);
346: }
347: epr.setAddressAttributes(addressAttributes);
348: } else if (map.get(
349: AddressingConstants.EPR_REFERENCE_PARAMETERS)
350: .equals(qname)) {
351: Iterator iterator = eprChildElement.getChildElements();
352: while (iterator.hasNext()) {
353: OMElement element = (OMElement) iterator.next();
354: epr.addReferenceParameter(element);
355: }
356: } else if (isFinalAddressingNamespace
357: && map.get(AddressingConstants.Final.WSA_METADATA)
358: .equals(qname)) {
359: Iterator iterator = eprChildElement.getChildElements();
360: while (iterator.hasNext()) {
361: OMNode node = (OMNode) iterator.next();
362: epr.addMetaData(node);
363: }
364: Iterator allMDAttributes = eprChildElement
365: .getAllAttributes();
366: ArrayList metadataAttributes = new ArrayList();
367: while (allMDAttributes.hasNext()) {
368: OMAttribute attribute = (OMAttribute) allMDAttributes
369: .next();
370: metadataAttributes.add(attribute);
371: }
372: epr.setMetadataAttributes(metadataAttributes);
373: } else if (!isFinalAddressingNamespace
374: && map
375: .get(
376: AddressingConstants.Submission.EPR_REFERENCE_PROPERTIES)
377: .equals(qname)) {
378: // since we have the model for WS-Final, we don't have a place to keep this reference properties.
379: // The only compatible place is reference properties
380: Iterator iterator = eprChildElement.getChildElements();
381: while (iterator.hasNext()) {
382: OMElement element = (OMElement) iterator.next();
383: epr.addReferenceParameter(element);
384: }
385: } else {
386: epr.addExtensibleElement(eprChildElement);
387: }
388: }
389:
390: Iterator attributes = eprOMElement.getAllAttributes();
391: while (attributes.hasNext()) {
392: OMAttribute attribute = (OMAttribute) attributes.next();
393: epr.addAttribute(attribute);
394: }
395:
396: if (log.isDebugEnabled()) {
397: log.debug("fromOM: Endpoint reference, " + epr);
398: }
399: }
400:
401: static {
402: finalQNames.put(AddressingConstants.EPR_ADDRESS, new QName(
403: AddressingConstants.Final.WSA_NAMESPACE,
404: AddressingConstants.EPR_ADDRESS));
405: finalQNames.put(AddressingConstants.EPR_REFERENCE_PARAMETERS,
406: new QName(AddressingConstants.Final.WSA_NAMESPACE,
407: AddressingConstants.EPR_REFERENCE_PARAMETERS));
408: finalQNames.put(AddressingConstants.Final.WSA_METADATA,
409: new QName(AddressingConstants.Final.WSA_NAMESPACE,
410: AddressingConstants.Final.WSA_METADATA));
411:
412: submissionQNames.put(AddressingConstants.EPR_ADDRESS,
413: new QName(AddressingConstants.Submission.WSA_NAMESPACE,
414: AddressingConstants.EPR_ADDRESS));
415: submissionQNames.put(
416: AddressingConstants.EPR_REFERENCE_PARAMETERS,
417: new QName(AddressingConstants.Submission.WSA_NAMESPACE,
418: AddressingConstants.EPR_REFERENCE_PARAMETERS));
419: submissionQNames
420: .put(
421: AddressingConstants.Submission.EPR_REFERENCE_PROPERTIES,
422: new QName(
423: AddressingConstants.Submission.WSA_NAMESPACE,
424: AddressingConstants.Submission.EPR_REFERENCE_PROPERTIES));
425: }
426: }
|