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.marshaller.impl.alt;
020:
021: import org.apache.axis2.jaxws.ExceptionFactory;
022: import org.apache.axis2.jaxws.description.EndpointDescription;
023: import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
024: import org.apache.axis2.jaxws.description.OperationDescription;
025: import org.apache.axis2.jaxws.description.ParameterDescription;
026: import org.apache.axis2.jaxws.i18n.Messages;
027: import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
028: import org.apache.axis2.jaxws.message.Message;
029: import org.apache.axis2.jaxws.message.Protocol;
030: import org.apache.axis2.jaxws.message.factory.MessageFactory;
031: import org.apache.axis2.jaxws.registry.FactoryRegistry;
032: import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
033: import org.apache.axis2.jaxws.utility.ConvertUtils;
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036:
037: import javax.xml.namespace.QName;
038: import javax.xml.ws.WebServiceException;
039: import java.lang.reflect.Array;
040: import java.util.List;
041: import java.util.ArrayList;
042: import java.util.TreeSet;
043:
044: public class DocLitBareMethodMarshaller implements MethodMarshaller {
045:
046: private static Log log = LogFactory
047: .getLog(DocLitBareMethodMarshaller.class);
048:
049: public DocLitBareMethodMarshaller() {
050: super ();
051: }
052:
053: public Object demarshalResponse(Message message,
054: Object[] signatureArgs, OperationDescription operationDesc)
055: throws WebServiceException {
056:
057: EndpointInterfaceDescription ed = operationDesc
058: .getEndpointInterfaceDescription();
059: EndpointDescription endpointDesc = ed.getEndpointDescription();
060:
061: // Note all exceptions are caught and rethrown with a WebServiceException
062: try {
063: // Sample Document message
064: // ..
065: // <soapenv:body>
066: // <m:return ... >...</m:param>
067: // </soapenv:body>
068: //
069: // Important points.
070: // 1) There is no operation element in the message
071: // 2) The data blocks are located underneath the operation element.
072: // 3) The name of the data blocks (m:param) are defined by the schema.
073: // (SOAP indicates that the name of the element is not important, but
074: // for document processing, we will assume that the name corresponds to
075: // a schema root element)
076: // 4) The type of the data block is defined by schema; thus in most cases
077: // an xsi:type will not be present
078: ParameterDescription[] pds = operationDesc
079: .getParameterDescriptions();
080: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
081: .getMarshalDesc(endpointDesc);
082: TreeSet<String> packages = marshalDesc.getPackages();
083:
084: // Get the return value.
085: Class returnType = operationDesc.getResultActualType();
086: Object returnValue = null;
087: boolean hasReturnInBody = false;
088: if (returnType != void.class) {
089: // If the webresult is in the header, we need the name of the header so that we can find it.
090: Element returnElement = null;
091: if (operationDesc.isResultHeader()) {
092: returnElement = MethodMarshallerUtils
093: .getReturnElement(
094: packages,
095: message,
096: null,
097: false,
098: true,
099: operationDesc
100: .getResultTargetNamespace(),
101: operationDesc.getResultName(),
102: MethodMarshallerUtils
103: .numOutputBodyParams(pds) > 0);
104:
105: } else {
106: returnElement = MethodMarshallerUtils
107: .getReturnElement(
108: packages,
109: message,
110: null,
111: false,
112: false,
113: null,
114: null,
115: MethodMarshallerUtils
116: .numOutputBodyParams(pds) > 0);
117: hasReturnInBody = true;
118: }
119: returnValue = returnElement.getTypeValue();
120: if (ConvertUtils.isConvertable(returnValue, returnType)) {
121: returnValue = ConvertUtils.convert(returnValue,
122: returnType);
123: }
124:
125: }
126:
127: // Unmarshall the ParamValues from the Message
128: List<PDElement> pvList = MethodMarshallerUtils
129: .getPDElements(pds, message, packages, false, // output
130: hasReturnInBody, null); // always unmarshal with "by element" mode
131:
132: // Populate the response Holders
133: MethodMarshallerUtils.updateResponseSignatureArgs(pds,
134: pvList, signatureArgs);
135:
136: return returnValue;
137: } catch (Exception e) {
138: throw ExceptionFactory.makeWebServiceException(e);
139: }
140: }
141:
142: public Object[] demarshalRequest(Message message,
143: OperationDescription operationDesc)
144: throws WebServiceException {
145:
146: EndpointInterfaceDescription ed = operationDesc
147: .getEndpointInterfaceDescription();
148: EndpointDescription endpointDesc = ed.getEndpointDescription();
149:
150: // Note all exceptions are caught and rethrown with a WebServiceException
151: try {
152: // Sample Document message
153: // ..
154: // <soapenv:body>
155: // <m:param .. >...</m:param>
156: // </soapenv:body>
157: //
158: // Important points.
159: // 1) There is no operation element under the body.
160: // 2) The data blocks are located underneath the body.
161: // 3) The name of the data blocks (m:param) are defined by the schema
162: // 4) The type of the data block (data:foo) is defined by schema (and probably
163: // is not present in the message
164: ParameterDescription[] pds = operationDesc
165: .getParameterDescriptions();
166: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
167: .getMarshalDesc(endpointDesc);
168: TreeSet<String> packages = marshalDesc.getPackages();
169:
170: // Unmarshal the ParamValues from the message
171: List<PDElement> pvList = MethodMarshallerUtils
172: .getPDElements(pds, message, packages, true, // input
173: false, null); // always unmarshal using "by element" mode
174:
175: // Build the signature arguments
176: Object[] sigArguments = MethodMarshallerUtils
177: .createRequestSignatureArgs(pds, pvList);
178:
179: return sigArguments;
180: } catch (Exception e) {
181: throw ExceptionFactory.makeWebServiceException(e);
182: }
183: }
184:
185: public Message marshalResponse(Object returnObject,
186: Object[] signatureArgs, OperationDescription operationDesc,
187: Protocol protocol) throws WebServiceException {
188:
189: EndpointInterfaceDescription ed = operationDesc
190: .getEndpointInterfaceDescription();
191: EndpointDescription endpointDesc = ed.getEndpointDescription();
192:
193: // We want to respond with the same protocol as the request,
194: // It the protocol is null, then use the Protocol defined by the binding
195: if (protocol == null) {
196: protocol = Protocol.getProtocolForBinding(endpointDesc
197: .getBindingType());
198: }
199:
200: // Note all exceptions are caught and rethrown with a WebServiceException
201: try {
202: // Sample Document message
203: // ..
204: // <soapenv:body>
205: // <m:return ... >...</m:param>
206: // </soapenv:body>
207: //
208: // Important points.
209: // 1) There is no operation element in the message
210: // 2) The data blocks are located underneath the operation element.
211: // 3) The name of the data blocks (m:param) are defined by the schema.
212: // (SOAP indicates that the name of the element is not important, but
213: // for document processing, we will assume that the name corresponds to
214: // a schema root element)
215: // 4) The type of the data block is defined by schema; thus in most cases
216: // an xsi:type will not be present
217:
218: // Get the operation information
219: ParameterDescription[] pds = operationDesc
220: .getParameterDescriptions();
221: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
222: .getMarshalDesc(endpointDesc);
223: TreeSet<String> packages = marshalDesc.getPackages();
224:
225: // Create the message
226: MessageFactory mf = (MessageFactory) FactoryRegistry
227: .getFactory(MessageFactory.class);
228: Message m = mf.create(protocol);
229:
230: // Put the return object onto the message
231: Class returnType = operationDesc.getResultActualType();
232: if (returnType != void.class) {
233: Element returnElement = null;
234: QName returnQName = new QName(operationDesc
235: .getResultTargetNamespace(), operationDesc
236: .getResultName());
237: if (marshalDesc.getAnnotationDesc(returnType)
238: .hasXmlRootElement()) {
239: returnElement = new Element(returnObject,
240: returnQName);
241: } else {
242: /* when a schema defines a SimpleType with xsd list jaxws tooling generates art-effects with array rather than a java.util.List
243: * However the ObjectFactory definition uses a List and thus marshalling fails. Lets convert the Arrays to List.
244: */
245: if (operationDesc.isListType()) {
246: List list = new ArrayList();
247: if (returnType.isArray()) {
248: for (int count = 0; count < Array
249: .getLength(returnObject); count++) {
250: Object obj = Array.get(returnObject,
251: count);
252: list.add(obj);
253: }
254: returnElement = new Element(list,
255: returnQName, List.class);
256: }
257: } else {
258: returnElement = new Element(returnObject,
259: returnQName, returnType);
260: }
261: }
262: MethodMarshallerUtils.toMessage(returnElement,
263: returnType, operationDesc.isListType(),
264: marshalDesc, m, null, // always marshal using "by element" mode
265: operationDesc.isResultHeader());
266: }
267:
268: // Convert the holder objects into a list of JAXB objects for marshalling
269: List<PDElement> pvList = MethodMarshallerUtils
270: .getPDElements(marshalDesc, pds, signatureArgs,
271: false, // output
272: false, false);
273:
274: // Put values onto the message
275: MethodMarshallerUtils.toMessage(pvList, m, packages);
276:
277: return m;
278: } catch (Exception e) {
279: throw ExceptionFactory.makeWebServiceException(e);
280: }
281: }
282:
283: public Message marshalRequest(Object[] signatureArguments,
284: OperationDescription operationDesc)
285: throws WebServiceException {
286:
287: EndpointInterfaceDescription ed = operationDesc
288: .getEndpointInterfaceDescription();
289: EndpointDescription endpointDesc = ed.getEndpointDescription();
290: Protocol protocol = Protocol.getProtocolForBinding(endpointDesc
291: .getClientBindingID());
292:
293: // Note all exceptions are caught and rethrown with a WebServiceException
294: try {
295: // Sample Document message
296: // ..
297: // <soapenv:body>
298: // <m:param .. >...</m:param>
299: // </soapenv:body>
300: //
301: // Important points.
302: // 1) There is no operation element under the body.
303: // 2) The data blocks are located underneath the body.
304: // 3) The name of the data blocks (m:param) are defined by the schema
305: // 4) The type of the data block (data:foo) is defined by schema (and probably
306: // is not present in the message
307:
308: // Get the operation information
309: ParameterDescription[] pds = operationDesc
310: .getParameterDescriptions();
311: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
312: .getMarshalDesc(endpointDesc);
313: TreeSet<String> packages = marshalDesc.getPackages();
314:
315: // Create the message
316: MessageFactory mf = (MessageFactory) FactoryRegistry
317: .getFactory(MessageFactory.class);
318: Message m = mf.create(protocol);
319:
320: // The input object represent the signature arguments.
321: // Signature arguments are both holders and non-holders
322: // Convert the signature into a list of JAXB objects for marshalling
323: List<PDElement> pvList = MethodMarshallerUtils
324: .getPDElements(marshalDesc, pds,
325: signatureArguments, true, // input
326: false, false);
327:
328: // Put values onto the message
329: MethodMarshallerUtils.toMessage(pvList, m, packages);
330:
331: return m;
332: } catch (Exception e) {
333: throw ExceptionFactory.makeWebServiceException(e);
334: }
335: }
336:
337: public Message marshalFaultResponse(Throwable throwable,
338: OperationDescription operationDesc, Protocol protocol)
339: throws WebServiceException {
340:
341: EndpointInterfaceDescription ed = operationDesc
342: .getEndpointInterfaceDescription();
343: EndpointDescription endpointDesc = ed.getEndpointDescription();
344: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
345: .getMarshalDesc(endpointDesc);
346:
347: // We want to respond with the same protocol as the request,
348: // It the protocol is null, then use the Protocol defined by the binding
349: if (protocol == null) {
350: protocol = Protocol.getProtocolForBinding(endpointDesc
351: .getBindingType());
352: }
353:
354: // Note all exceptions are caught and rethrown with a WebServiceException
355: try {
356: // Create the message
357: MessageFactory mf = (MessageFactory) FactoryRegistry
358: .getFactory(MessageFactory.class);
359: Message m = mf.create(protocol);
360:
361: // Put the fault onto the message
362: MethodMarshallerUtils.marshalFaultResponse(throwable,
363: marshalDesc, operationDesc, m);
364: return m;
365: } catch (Exception e) {
366: throw ExceptionFactory.makeWebServiceException(e);
367: }
368: }
369:
370: public Throwable demarshalFaultResponse(Message message,
371: OperationDescription operationDesc)
372: throws WebServiceException {
373:
374: EndpointInterfaceDescription ed = operationDesc
375: .getEndpointInterfaceDescription();
376: EndpointDescription endpointDesc = ed.getEndpointDescription();
377: MarshalServiceRuntimeDescription marshalDesc = MethodMarshallerUtils
378: .getMarshalDesc(endpointDesc);
379:
380: // Note all exceptions are caught and rethrown with a WebServiceException
381: try {
382: Throwable t = MethodMarshallerUtils.demarshalFaultResponse(
383: operationDesc, marshalDesc, message);
384: return t;
385: } catch (Exception e) {
386: throw ExceptionFactory.makeWebServiceException(e);
387: }
388: }
389:
390: }
|