methodmarshallerutils.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 1,273 行 · 第 1/4 页
JAVA
1,273 行
/*
* 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.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.AttachmentDescription;
import org.apache.axis2.jaxws.description.AttachmentType;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.FaultDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.description.ParameterDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.i18n.Messages;
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.XMLFault;
import org.apache.axis2.jaxws.message.XMLFaultReason;
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.util.XMLFaultUtils;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.runtime.description.marshal.AnnotationDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.FaultBeanDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescriptionFactory;
import org.apache.axis2.jaxws.utility.ClassUtils;
import org.apache.axis2.jaxws.utility.ConvertUtils;
import org.apache.axis2.jaxws.utility.SAAJFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.activation.DataHandler;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPFault;
import javax.xml.stream.XMLStreamException;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Holder;
import javax.xml.ws.ProtocolException;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPFaultException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TreeSet;
/** Static Utilty Classes used by the MethodMarshaller implementations in the alt package. */
public class MethodMarshallerUtils {
private static Log log = LogFactory.getLog(MethodMarshallerUtils.class);
private static JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
/** Intentionally Private. This is a static utility class */
private MethodMarshallerUtils() {
}
/**
* Returns the list of PDElements that need to be marshalled onto the wire
*
* @param marshalDesc
* @param params ParameterDescription for this operation
* @param sigArguments arguments
* @param isInput indicates if input or output params(input args on client,
* output args on server)
* @param isDocLitWrapped
* @param isRPC
* @return PDElements
*/
static List<PDElement> getPDElements(MarshalServiceRuntimeDescription marshalDesc,
ParameterDescription[] params,
Object[] sigArguments,
boolean isInput,
boolean isDocLitWrapped,
boolean isRPC) {
List<PDElement> pdeList = new ArrayList<PDElement>();
int index = 0;
for (int i = 0; i < params.length; i++) {
ParameterDescription pd = params[i];
if (pd.getMode() == Mode.IN && isInput ||
pd.getMode() == Mode.INOUT ||
pd.getMode() == Mode.OUT && !isInput) {
// Get the matching signature argument
Object value = sigArguments[i];
// Don't consider async handlers, they are are not represented on the wire,
// thus they don't have a PDElement
if (isAsyncHandler(value)) {
continue;
}
// Convert from Holder into value
if (isHolder(value)) {
value = ((Holder)value).value;
}
// Get the formal type representing the value
Class formalType = pd.getParameterActualType();
// The namespace and local name are obtained differently depending on
// the style/use and header
QName qName = null;
if (pd.isHeader()) {
// Headers (even rpc) are marshalled with the name defined by the
// element= attribute on the wsd:part
qName = new QName(pd.getTargetNamespace(), pd.getParameterName());
} else if (isDocLitWrapped) {
// For doc/lit wrapped, the localName comes from the PartName
qName = new QName(pd.getTargetNamespace(), pd.getPartName());
} else if (isRPC) {
// Per WSI-BP, the namespace uri is unqualified
qName = new QName(pd.getPartName());
} else {
qName = new QName(pd.getTargetNamespace(), pd.getParameterName());
}
// Create an Element rendering
Element element = null;
AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
if (attachmentDesc != null) {
PDElement pde = createPDElementForAttachment(pd, qName, value, formalType);
pdeList.add(pde);
} else {
if (!marshalDesc.getAnnotationDesc(formalType).hasXmlRootElement()) {
/* when a schema defines a SimpleType with xsd list jaxws tooling
* generates artifacts with array rather than a java.util.List
* However the ObjectFactory definition uses a List and thus
* marshalling fails. Lets convert the Arrays to List and recreate
* the JAXBElements for the same.
*/
if (pd.isListType()) {
List<Object> list = new ArrayList<Object>();
if (formalType.isArray()) {
for (int count = 0; count < Array.getLength(value); count++) {
Object obj = Array.get(value, count);
list.add(obj);
}
}
element = new Element(list, qName, List.class);
} else {
element = new Element(value, qName, formalType);
}
}
else{
element = new Element(value, qName);
}
// The object is now ready for marshalling
PDElement pde = new PDElement(pd, element, null);
pdeList.add(pde);
}
}
}
return pdeList;
}
/**
* @param pd
* @param qName
* @param value
* @param formalType
* @return
*/
private static PDElement createPDElementForAttachment(ParameterDescription pd,
QName qName,
Object value,
Class formalType) {
PDElement pde;
if (log.isDebugEnabled()) {
log.debug("Creating a PDElement for an attachment value: " +
((value == null)? "null":value.getClass().getName()));
log.debug("ParameterDescription = " + pd.toString());
}
AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
AttachmentType attachmentType = attachmentDesc.getAttachmentType();
if (attachmentType == AttachmentType.SWA) {
// Create an Attachment object with the signature value
Attachment attachment = new Attachment(value,
formalType,
attachmentDesc);
pde = new PDElement(pd,
null, // For SWA Attachments, there is no element reference to the attachment
null,
attachment);
} else {
// TODO NLS and clean this up
throw ExceptionFactory.
makeWebServiceException("SWAREF and MTOM attachment parameters are not " +
"supported in this style/use.");
}
return pde;
}
/**
* Return the list of PDElements that is unmarshalled from the wire
*
* @param params ParameterDescription for this operation
* @param message Message
* @param packages set of packages needed to unmarshal objects for this operation
* @param isInput indicates if input or output params (input on server, output on client)
* @param hasReturnInBody if isInput=false, then this parameter indicates whether a
* return value is expected in the body.
* @param unmarshalByJavaType in most scenarios this is null.
* Only use this in the scenarios that require unmarshalling by java type
* @return ParamValues
*/
static List<PDElement> getPDElements(ParameterDescription[] params,
Message message,
TreeSet<String> packages,
boolean isInput,
boolean hasReturnInBody,
Class[] unmarshalByJavaType) throws XMLStreamException {
List<PDElement> pdeList = new ArrayList<PDElement>();
// Count
int totalBodyBlocks = 0;
for (int i = 0; i < params.length; i++) {
ParameterDescription pd = params[i];
if (pd.getMode() == Mode.IN && isInput ||
pd.getMode() == Mode.INOUT ||
pd.getMode() == Mode.OUT && !isInput) {
if (!pd.isHeader() && !isSWAAttachment(pd)) {
totalBodyBlocks++;
}
}
}
if (!isInput && hasReturnInBody) {
totalBodyBlocks++;
}
int index = (!isInput && hasReturnInBody) ? 1 : 0;
// TODO What if return is an swa attachment, then this should start
// at 1 not 0.
int swaIndex = 0;
for (int i = 0; i < params.length; i++) {
ParameterDescription pd = params[i];
if (pd.getMode() == Mode.IN && isInput ||
pd.getMode() == Mode.INOUT ||
pd.getMode() == Mode.OUT && !isInput) {
// Don't consider async handlers, they are are not represented on the wire,
// thus they don't have a PDElement
// TODO
//if (isAsyncHandler(param)) {
// continue;
//}
Block block = null;
JAXBBlockContext context = new JAXBBlockContext(packages);
AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
if (attachmentDesc == null) {
// Normal Processing: Not an Attachment
// Trigger unmarshal by java type if necessary
if (unmarshalByJavaType != null && unmarshalByJavaType[i] != null) {
context.setProcessType(unmarshalByJavaType[i]);
context.setIsxmlList(pd.isListType());
}
// Unmarshal the object into a JAXB object or JAXBElement
if (pd.isHeader()) {
// Get the Block from the header
// NOTE The parameter name is always used to get the header
// element...even if the style is RPC.
String localName = pd.getParameterName();
block = message.getHeaderBlock(pd.getTargetNamespace(),
localName,
context,
factory);
} else {
if (totalBodyBlocks > 1) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?