blob: b91e8e52bc0b8bd4ffa97675b3d3e7d7fd923f4d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.jaxws.marshaller.impl.alt;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.description.ParameterDescription;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
import org.apache.axis2.jaxws.utility.ConvertUtils;
import org.apache.axis2.jaxws.wrapper.JAXBWrapperTool;
import org.apache.axis2.jaxws.wrapper.impl.JAXBWrapperToolImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.jws.WebParam.Mode;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
/**
* The DocLitWrapped "plus" marshaller is used when the java method is doc/lit wrapped, but it does
* not exactly comply with the doc/lit rules. This can result from the customer adding annotations,
* but it can also be the result of WSGEN generation
* <p/>
* Here is an example:
*
* @WebMethod(action = "http://addheaders.sample.test.org/echoStringWSGEN1")
* @RequestWrapper(localName = "echoStringWSGEN1", targetNamespace = "http://wrap.sample.test.org",
* className = "org.test.sample.wrap.EchoStringWSGEN1")
* @ResponseWrapper(localName = "echoStringWSGEN1Response", targetNamespace =
* "http://wrap.sample.test.org", className = "org.test.sample.wrap.EchoStringWSGEN1Response")
* public String echoStringWSGEN1(
* @WebParam(name = "headerValue", targetNamespace = "http://wrap.sample.test.org", header = true)
* String headerValue )
* <p/>
* In this case the method is doc/lit, but the headerValue parameter is passed in the header. The
* wrapper class EchoStringWSGEN1 will not have any child elements.
* <p/>
* A similar example is:
* @WebMethod(action = "http://addheaders.sample.test.org/echoStringWSGEN2")
* @RequestWrapper(localName = "echoStringWSGEN2", targetNamespace = "http://wrap.sample.test.org",
* className = "org.test.sample.wrap.EchoStringWSGEN2")
* @ResponseWrapper(localName = "echoStringWSGEN2Response", targetNamespace =
* "http://wrap.sample.test.org", className = "org.test.sample.wrap.EchoStringWSGEN2Response")
* @WebResult(name = "headerValue", targetNamespace = "http://wrap.sample.test.org", header = true)
* public String echoStringWSGEN2(
* @WebParam(name = "data", targetNamespace = "") String data )
* <p/>
* In this second case, the return is passed in a header (as defined by @WebResult)
* <p/>
* At the time of this writing, the "plus" marshaller is only used if a doc/lit wrapped method has
* "header" parameters. If other deviations are found, this class will be updated. The advantage
* of using DocLitWrapperPlus for these deviations is that it does not impact the normal
* DocLitWrapper marshalling (which is used for 99% of the cases). Thus these deviations will not
* polute or slow down the normal flow.
* <p/>
* Scheu
*/
public class DocLitWrappedPlusMethodMarshaller implements MethodMarshaller {
private static Log log = LogFactory.getLog(DocLitWrappedPlusMethodMarshaller.class);
public DocLitWrappedPlusMethodMarshaller() {
super();
}
public Object demarshalResponse(Message message, Object[] signatureArgs,
OperationDescription operationDesc)
throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.demarshalResponse");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
// Note all exceptions are caught and rethrown with a WebServiceException
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
try {
// Sample Document message
// ..
// <soapenv:body>
// <m:operationResponse ... >
// <param>hello</param>
// </m:operationResponse>
// </soapenv:body>
//
// Important points.
// 1) There is no operation element in the message
// 2) The data blocks are located underneath the body element.
// 3) The name of the data block (m:operationResponse) is defined by the schema.
// It matches the operation name + "Response", and it has a corresponding JAXB element.
// This element is called the wrapper element
// 4) The parameters are (param) are child elements of the wrapper element.
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
String packagesKey = marshalDesc.getPackagesKey();
// Determine if a returnValue is expected.
// The return value may be an child element
// The wrapper element
// or null
Object returnValue = null;
Class returnType = operationDesc.getResultActualType();
boolean isChildReturn = !operationDesc.isJAXWSAsyncClientMethod() &&
(operationDesc.getResultPartName() != null);
boolean isNoReturn = (returnType == void.class);
// In usage=WRAPPED, there will be a single JAXB block inside the body.
// Get this block
JAXBBlockContext blockContext = new JAXBBlockContext(packages, packagesKey);
blockContext.setWebServiceNamespace(ed.getTargetNamespace());
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
Block block = message.getBodyBlock(blockContext, factory);
Object wrapperObject = block.getBusinessObject(true);
// The child elements are within the object that
// represents the type
if (wrapperObject instanceof JAXBElement) {
wrapperObject = ((JAXBElement)wrapperObject).getValue();
}
// Use the wrapper tool to get the child objects.
JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl();
// Get the list of names for the output parameters
List<String> names = new ArrayList<String>();
List<ParameterDescription> pdList = new ArrayList<ParameterDescription>();
for (int i = 0; i < pds.length; i++) {
ParameterDescription pd = pds[i];
if (pd.getMode() == Mode.OUT ||
pd.getMode() == Mode.INOUT) {
if (!pd.isHeader()) {
// Header names are not in the wrapped element
names.add(pd.getParameterName());
}
pdList.add(pd);
}
}
if (!operationDesc.isResultHeader()) {
// Normal case (Body Result) The return name is in the wrapped object
if (isChildReturn && !isNoReturn) {
names.add(operationDesc.getResultPartName());
}
}
// Get the child objects
Object[] objects = wrapperTool.unWrap(wrapperObject, names,
marshalDesc.getPropertyDescriptorMap(
wrapperObject.getClass()));
// Now create a list of paramValues so that we can populate the signature
List<PDElement> pvList = new ArrayList<PDElement>();
int bodyIndex = 0;
for (int i = 0; i < pdList.size(); i++) {
ParameterDescription pd = pdList.get(i);
if (!pd.isHeader()) {
// Body elements are obtained from the unwrapped array of objects
Object value = objects[bodyIndex];
// The object in the PDElement must be an element
QName qName = new QName(pd.getTargetNamespace(),
pd.getPartName());
Element element = null;
if (!marshalDesc.getAnnotationDesc(pd.getParameterActualType())
.hasXmlRootElement()) {
element = new Element(value, qName, pd.getParameterActualType());
} else {
element = new Element(value, qName);
}
pvList.add(new PDElement(pd, element, null));
bodyIndex++;
} else {
// Header
// Get the Block from the header
String localName = pd.getParameterName();
JAXBBlockContext blkContext = new JAXBBlockContext(packages, packagesKey);
// Set up "by java type" unmarshalling if necessary
if (blkContext.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE
.BY_CONTEXT_PATH) {
Class actualType = pd.getParameterActualType();
if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
blkContext.setProcessType(actualType);
blkContext.setIsxmlList(pd.isListType());
}
}
block = message.getHeaderBlock(pd.getTargetNamespace(), localName, blkContext,
factory);
Object value = block.getBusinessObject(true);
Element element =
new Element(value, new QName(pd.getTargetNamespace(), localName));
pvList.add(new PDElement(pd, element, blkContext.getProcessType()));
}
}
// Populate the response Holders in the signature
MethodMarshallerUtils.updateResponseSignatureArgs(pds, pvList, signatureArgs);
// Now get the return value
if (isNoReturn) {
returnValue = null;
} else if (isChildReturn) {
if (!operationDesc.isResultHeader()) {
// Normal: Get the return from the jaxb object
returnValue = objects[objects.length - 1];
} else {
// Header result: Get the value from the headers
Element returnElement =
MethodMarshallerUtils.getReturnElement(packages, message, null, false, true,
operationDesc.getResultTargetNamespace(),
operationDesc.getResultPartName(),
false);
returnValue = returnElement.getTypeValue();
}
// returnValue may be incompatible with JAX-WS signature
if (ConvertUtils.isConvertable(returnValue, returnType)) {
returnValue = ConvertUtils.convert(returnValue, returnType);
} else {
String objectClass =
(returnValue == null) ? "null" : returnValue.getClass().getName();
throw ExceptionFactory.makeWebServiceException(
Messages.getMessage("convertProblem", objectClass,
returnType.getName()));
}
} else {
returnValue = wrapperObject;
}
return returnValue;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
public Object[] demarshalRequest(Message message, OperationDescription operationDesc)
throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.demarshalRequest");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
// Note all exceptions are caught and rethrown with a WebServiceException
try {
// Sample Document message
// ..
// <soapenv:body>
// <m:operation>
// <param>hello</param>
// </m:operation>
// </soapenv:body>
//
// Important points.
// 1) There is no operation element under the body.
// 2) The data blocks are located underneath the body.
// 3) The name of the data block (m:operation) is defined by the schema and match the name of the operation.
// This is called the wrapper element. The wrapper element has a corresponding JAXB element pojo.
// 4) The parameters (m:param) are child elements of the wrapper element.
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
String packagesKey = marshalDesc.getPackagesKey();
// In usage=WRAPPED, there will be a single JAXB block inside the body.
// Get this block
JAXBBlockContext blockContext = new JAXBBlockContext(packages, packagesKey);
blockContext.setWebServiceNamespace(ed.getTargetNamespace());
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
Block block = message.getBodyBlock(blockContext, factory);
Object wrapperObject = block.getBusinessObject(true);
// The child elements are within the object that
// represents the type
if (wrapperObject instanceof JAXBElement) {
wrapperObject = ((JAXBElement)wrapperObject).getValue();
}
// Use the wrapper tool to get the child objects.
JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl();
// Get the list of names for the input parameters
List<String> xmlNames = new ArrayList<String>();
List<ParameterDescription> pdList = new ArrayList<ParameterDescription>();
for (int i = 0; i < pds.length; i++) {
ParameterDescription pd = pds[i];
if (pd.getMode() == Mode.IN ||
pd.getMode() == Mode.INOUT) {
if (!pd.isHeader()) {
// Only the body parameters will be present in the wrapper object
xmlNames.add(pd.getParameterName());
}
pdList.add(pd);
}
}
// Get the child objects
Object[] objects = wrapperTool.unWrap(wrapperObject, xmlNames,
marshalDesc.getPropertyDescriptorMap(
wrapperObject.getClass()));
// Now create a list of paramValues
List<PDElement> pvList = new ArrayList<PDElement>();
int bodyIndex = 0;
for (int i = 0; i < pdList.size(); i++) {
ParameterDescription pd = pdList.get(i);
if (!pd.isHeader()) {
// Normal case: Get the parameter value from the list of objects
Object value = objects[bodyIndex];
// The object in the PDElement must be an element
QName qName = new QName(pd.getTargetNamespace(), pd.getPartName());
Element element = null;
if (!marshalDesc.getAnnotationDesc(pd.getParameterActualType())
.hasXmlRootElement()) {
element = new Element(value, qName, pd.getParameterActualType());
} else {
element = new Element(value, qName);
}
pvList.add(new PDElement(pd, element, null));
bodyIndex++;
} else {
// Header
// Get the Block from the header
String localName = pd.getParameterName();
JAXBBlockContext blkContext =
new JAXBBlockContext(packages, marshalDesc.getPackagesKey());
// Set up "by java type" unmarshalling if necessary
if (blkContext.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE
.BY_CONTEXT_PATH) {
Class actualType = pd.getParameterActualType();
if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
blkContext.setProcessType(actualType);
} else {
Annotation annos[] = actualType.getAnnotations();
if (annos == null || annos.length == 0) {
blkContext.setProcessType(actualType);
blkContext.setIsxmlList(pd.isListType());
}
}
}
block = message.getHeaderBlock(pd.getTargetNamespace(), localName, blkContext,
factory);
Object value = block.getBusinessObject(true);
Element element =
new Element(value, new QName(pd.getTargetNamespace(), localName));
pvList.add(new PDElement(pd, element, blkContext.getProcessType()));
}
}
// Build the signature arguments
Object[] sigArguments = MethodMarshallerUtils.createRequestSignatureArgs(pds, pvList);
return sigArguments;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
public Message marshalResponse(Object returnObject, Object[] signatureArgs,
OperationDescription operationDesc, Protocol protocol)
throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.marshalResponse");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
// We want to respond with the same protocol as the request,
// It the protocol is null, then use the Protocol defined by the binding
if (protocol == null) {
protocol = Protocol.getProtocolForBinding(endpointDesc.getBindingType());
}
// Note all exceptions are caught and rethrown with a WebServiceException
try {
// Sample Document message
// ..
// <soapenv:body>
// <m:operationResponse ... >
// <param>hello</param>
// </m:operationResponse>
// </soapenv:body>
//
// Important points.
// 1) There is no operation element in the message
// 2) The data blocks are located underneath the body element.
// 3) The name of the data block (m:operationResponse) is defined by the schema.
// It matches the operation name + "Response", and it has a corresponding JAXB element.
// This element is called the wrapper element
// 4) The parameters are (param) are child elements of the wrapper element.
// Get the operation information
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
String packagesKey = marshalDesc.getPackagesKey();
// Create the message
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
Message m = mf.create(protocol);
// In usage=WRAPPED, there will be a single block in the body.
// The signatureArguments represent the child elements of that block
// The first step is to convert the signature arguments into a list
// of parameter values
List<PDElement> pdeList =
MethodMarshallerUtils.getPDElements(marshalDesc,
pds,
signatureArgs,
false, // output
true, false);
// Now we want to create a single JAXB element that contains the
// parameter values. We will use the wrapper tool to do this.
// Create the inputs to the wrapper tool
ArrayList<String> nameList = new ArrayList<String>();
Map<String, Object> objectList = new HashMap<String, Object>();
Map<String, Class> declaredClassMap = new HashMap<String, Class>();
List<PDElement> headerPDEList = new ArrayList<PDElement>();
Iterator<PDElement> it = pdeList.iterator();
while (it.hasNext()) {
PDElement pde = it.next();
String name = pde.getParam().getParameterName();
if (!pde.getParam().isHeader()) {
// Normal case
// The object list contains type rendered objects
Object value = pde.getElement().getTypeValue();
Class dclClass = pde.getParam().getParameterActualType();
nameList.add(name);
objectList.put(name, value);
declaredClassMap.put(name, dclClass);
} else {
// Header Case:
// Remove the header from the list, it will
// not be placed in the wrapper
it.remove();
headerPDEList.add(pde);
}
}
Class returnType = operationDesc.getResultActualType();
if (!operationDesc.isResultHeader()) {
// Normal (Body Result): Add the return object to the nameList and objectList
if (returnType != void.class) {
String name = operationDesc.getResultName();
Class dclClass = operationDesc.getResultActualType();
nameList.add(name);
objectList.put(name, returnObject);
declaredClassMap.put(name, dclClass);
}
} else {
// Header Result:
// Put the return object onto the message
if (returnType != void.class) {
Element returnElement = null;
QName returnQName = new QName(operationDesc.getResultTargetNamespace(),
operationDesc.getResultName());
if (marshalDesc.getAnnotationDesc(returnType).hasXmlRootElement()) {
returnElement = new Element(returnObject, returnQName);
} else {
returnElement = new Element(returnObject, returnQName, returnType);
}
Class byJavaType =
MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc) ? returnType : null;
MethodMarshallerUtils.toMessage(returnElement,
returnType,
operationDesc.isListType(),
marshalDesc,
m,
byJavaType,
true);
}
}
// Now create the single JAXB element
String wrapperName = marshalDesc.getResponseWrapperClassName(operationDesc);
Class cls;
try {
cls = MethodMarshallerUtils.loadClass(wrapperName);
} catch (ClassNotFoundException e){
cls = MethodMarshallerUtils.loadClass(wrapperName, endpointDesc.getAxisService().getClassLoader());
}
JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl();
Object object = wrapperTool.wrap(cls, nameList, objectList, declaredClassMap,
marshalDesc.getPropertyDescriptorMap(cls));
QName wrapperQName = new QName(operationDesc.getResponseWrapperTargetNamespace(),
operationDesc.getResponseWrapperLocalName());
// Make sure object can be rendered as an element
if (!marshalDesc.getAnnotationDesc(cls).hasXmlRootElement()) {
object = new JAXBElement(wrapperQName, cls, object);
}
// Put the object into the message
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
JAXBBlockContext blockContext = new JAXBBlockContext(packages, packagesKey);
blockContext.setWebServiceNamespace(ed.getTargetNamespace());
Block block = factory.createFrom(object,
blockContext,
wrapperQName); // The factory will get the qname from the value
m.setBodyBlock(block);
// Now place the headers in the message
if (headerPDEList.size() > 0) {
// Use "by java type" marshalling if necessary
for (PDElement pde : headerPDEList) {
Class actualType = pde.getParam().getParameterActualType();
if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
pde.setByJavaTypeClass(actualType);
}
}
MethodMarshallerUtils.toMessage(headerPDEList, m, packages);
}
// Enable SWA for nested SwaRef attachments
if (operationDesc.hasResponseSwaRefAttachments()) {
m.setDoingSWA(true);
}
return m;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
public Message marshalRequest(Object[] signatureArguments, OperationDescription operationDesc)
throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.marshalRequest");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
Protocol protocol = Protocol.getProtocolForBinding(endpointDesc.getClientBindingID());
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
String packagesKey = marshalDesc.getPackagesKey();
// Note all exceptions are caught and rethrown with a WebServiceException
try {
// Sample Document message
// ..
// <soapenv:body>
// <m:operation>
// <param>hello</param>
// </m:operation>
// </soapenv:body>
//
// Important points.
// 1) There is no operation element under the body.
// 2) The data blocks are located underneath the body.
// 3) The name of the data block (m:operation) is defined by the schema and match the name of the operation.
// This is called the wrapper element. The wrapper element has a corresponding JAXB element pojo.
// 4) The parameters (m:param) are child elements of the wrapper element.
// Get the operation information
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
// Create the message
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
Message m = mf.create(protocol);
// In usage=WRAPPED, there will be a single block in the body.
// The signatureArguments represent the child elements of that block
// The first step is to convert the signature arguments into list
// of parameter values
List<PDElement> pdeList = MethodMarshallerUtils.getPDElements(marshalDesc,
pds,
signatureArguments,
true, // input
true, false);
// Now we want to create a single JAXB element that contains the
// ParameterValues. We will use the wrapper tool to do this.
// Create the inputs to the wrapper tool
ArrayList<String> nameList = new ArrayList<String>();
Map<String, Object> objectList = new HashMap<String, Object>();
Map<String, Class> declardClassMap = new HashMap<String, Class>();
List<PDElement> headerPDEList = new ArrayList<PDElement>();
Iterator<PDElement> it = pdeList.iterator();
while (it.hasNext()) {
PDElement pde = it.next();
String name = pde.getParam().getParameterName();
if (!pde.getParam().isHeader()) {
// Normal case:
// The object list contains type rendered objects
Object value = pde.getElement().getTypeValue();
Class dclClass = pde.getParam().getParameterActualType();
nameList.add(name);
objectList.put(name, value);
declardClassMap.put(name, dclClass);
} else {
// Header Case:
// Remove the header from the list, it will
// not be placed in the wrapper
it.remove();
headerPDEList.add(pde);
}
}
// Now create the single JAXB element
String wrapperName = marshalDesc.getRequestWrapperClassName(operationDesc);
Class cls;
try {
cls = MethodMarshallerUtils.loadClass(wrapperName);
} catch (ClassNotFoundException e){
cls = MethodMarshallerUtils.loadClass(wrapperName, endpointDesc.getAxisService().getClassLoader());
}
JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl();
Object object = wrapperTool.wrap(cls, nameList, objectList, declardClassMap,
marshalDesc.getPropertyDescriptorMap(cls));
QName wrapperQName = new QName(operationDesc.getRequestWrapperTargetNamespace(),
operationDesc.getRequestWrapperLocalName());
// Make sure object can be rendered as an element
if (!marshalDesc.getAnnotationDesc(cls).hasXmlRootElement()) {
object = new JAXBElement(wrapperQName, cls, object);
}
// Put the object into the message
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
JAXBBlockContext blockContext = new JAXBBlockContext(packages, packagesKey);
blockContext.setWebServiceNamespace(ed.getTargetNamespace());
Block block = factory.createFrom(object,
blockContext,
wrapperQName); // The factory will get the qname from the value
m.setBodyBlock(block);
// Now place the headers in the message
if (headerPDEList.size() > 0) {
// Use "by java type" marshalling if necessary
for (PDElement pde : headerPDEList) {
Class actualType = pde.getParam().getParameterActualType();
if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
pde.setByJavaTypeClass(actualType);
}
}
MethodMarshallerUtils.toMessage(headerPDEList, m, packages);
}
// Enable SWA for nested SwaRef attachments
if (operationDesc.hasRequestSwaRefAttachments()) {
m.setDoingSWA(true);
}
return m;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
public Message marshalFaultResponse(Throwable throwable, OperationDescription operationDesc,
Protocol protocol) throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.marshalFaultResponse");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
// We want to respond with the same protocol as the request,
// It the protocol is null, then use the Protocol defined by the binding
if (protocol == null) {
protocol = Protocol.getProtocolForBinding(endpointDesc.getBindingType());
}
// Note all exceptions are caught and rethrown with a WebServiceException
try {
// Create the message
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
Message m = mf.create(protocol);
// Put the fault onto the message
MethodMarshallerUtils.marshalFaultResponse(throwable,
marshalDesc,
operationDesc,
m);
return m;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
public Throwable demarshalFaultResponse(Message message, OperationDescription operationDesc)
throws WebServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling DocLitWrapperPlusMethodMarshaller.demarshalFaultResponse");
log.debug(
" The DocLitWrapped Plus marshaller is used when the web service method deviates from the normal doc/lit rules.");
}
EndpointInterfaceDescription ed = operationDesc.getEndpointInterfaceDescription();
EndpointDescription endpointDesc = ed.getEndpointDescription();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
// Note all exceptions are caught and rethrown with a WebServiceException
try {
Throwable t = MethodMarshallerUtils.demarshalFaultResponse(operationDesc,
marshalDesc,
message);
return t;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
}