jaxbblockimpl.java
来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 598 行 · 第 1/2 页
JAVA
598 行
}
});
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
/**
* Marshal objects by type
*
* @param b Object that can be rendered as an element, but the element name is not known to the
* schema (i.e. rpc)
* @param m Marshaller
* @param writer XMLStreamWriter
* @param type
*/
private static void marshalByType(final Object b, final Marshaller m,
final XMLStreamWriter writer, final Class type,
final boolean isList, final JAXBUtils.CONSTRUCTION_TYPE ctype)
throws WebServiceException {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// NOTE
// Example:
// <xsd:simpleType name="LongList">
// <xsd:list>
// <xsd:simpleType>
// <xsd:restriction base="xsd:unsignedInt"/>
// </xsd:simpleType>
// </xsd:list>
// </xsd:simpleType>
// <element name="myLong" nillable="true" type="impl:LongList"/>
//
// LongList will be represented as an int[]
// On the wire myLong will be represented as a list of integers
// with intervening whitespace
// <myLong>1 2 3</myLong>
//
// Unfortunately, we are trying to marshal by type. Therefore
// we want to marshal an element (foo) that is unknown to schema.
// If we use the normal marshal code, the wire will look like
// this (which is incorrect):
// <foo><item>1</item><item>2</item><item>3</item></foo>
//
// The solution is to detect this situation and marshal the
// String instead. Then we get the correct wire format:
// <foo>1 2 3</foo>
Object jbo = b;
if (isList || (type != null && type.isArray())) {
if (DEBUG_ENABLED) {
log.debug("marshalling type which is a List or Array");
}
// We conver to xsdListString only if the type is not known
// to the context. In case a jaxbcontext is created from package
// the array types or list are not know to the context.
if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(b);
String text = XSDListUtils.toXSDListString(getTypeEnabledObject(b));
jbo = new JAXBElement(qName, String.class, text);
} else if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY) {
// do nothing common array types should be know to the jaxbcontext.
// so do not use xsdListString conversion.
}
}
// When JAXBContext is created using a context path, it will not include Enum
// classes.
// These classes have @XmlEnum annotation but not @XmlType/@XmlElement, so the
// user will see MarshallingEx, class not known to ctxt.
//
// This is a jax-b defect, for now this fix is in place to pass CTS. This only
// fixes the
// situation where the enum is the top-level object (e.g., message-part in
// rpc-lit scenario)
//
// Sample of what enum looks like:
// @XmlEnum public enum EnumString {
// @XmlEnumValue("String1") STRING_1("String1"),
// @XmlEnumValue("String2") STRING_2("String2");
// ... }
if (type.isEnum()) {
if (b != null) {
if (DEBUG_ENABLED) {
log.debug("marshalByType. Marshaling " + type.getName()
+ " as Enum");
}
JAXBElement jbe = (JAXBElement) b;
String value = XMLRootElementUtil.getEnumValue((Enum) jbe.getValue());
jbo = new JAXBElement(jbe.getName(), String.class, value);
}
}
if (DEBUG_ENABLED) {
log.debug("Invoking marshalByType. " +
"Marshaling to an XMLStreamWriter. Object is "
+ getDebugName(b));
}
m.marshal(jbo, writer);
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
return null;
}
});
}
/**
* The root element being read is defined by schema/JAXB; however its contents are known by
* schema/JAXB. Therefore we use unmarshal by the declared type (This method is used to
* unmarshal rpc elements)
*
* @param u Unmarshaller
* @param reader XMLStreamReader
* @param type Class
* @return Object
* @throws WebServiceException
*/
private static Object unmarshalByType(final Unmarshaller u, final XMLStreamReader reader,
final Class type, final boolean isList,
final JAXBUtils.CONSTRUCTION_TYPE ctype)
throws WebServiceException {
if (DEBUG_ENABLED) {
log.debug("Invoking unmarshalByType.");
}
return AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// Unfortunately RPC is type based. Thus a
// declared type must be used to unmarshal the xml.
Object jaxb;
if (!isList) {
// case: We are not unmarshalling an xsd:list but an Array.
if (type.isArray()) {
// If the context is created using package
// we will not have common arrays or type array in the context
// so let use a differet way to unmarshal this type
if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
jaxb = unmarshalAsListOrArray(reader, u, type);
}
// list on client array on server, Can happen only in start from java
// case.
else if ((ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY)) {
// The type could be any Object or primitive
// I will first unmarshall the xmldata to a String[]
// Then use the unmarshalled jaxbElement to create
// proper type Object Array.
jaxb = u.unmarshal(reader, String[].class);
Object typeObj = getTypeEnabledObject(jaxb);
// Now convert String Array in to the required Type Array.
if (getTypeEnabledObject(typeObj) instanceof String[]) {
String[] strArray = (String[]) typeObj;
String strTokens = new String();
for (String str : strArray) {
strTokens = strTokens + " " + str;
}
QName qName =
XMLRootElementUtil.
getXmlRootElementQNameFromObject(jaxb);
Object obj = XSDListUtils.fromXSDListString(strTokens, type);
jaxb = new JAXBElement(qName, type, obj);
}
} else {
jaxb = u.unmarshal(reader, type);
}
} else if (type.isEnum()) {
// When JAXBContext is created using a context path, it will not
// include Enum classes.
// These classes have @XmlEnum annotation but not @XmlType/@XmlElement,
// so the user will see MarshallingEx, class not known to ctxt.
//
// This is a jax-b defect, for now this fix is in place to pass CTS.
// This only fixes the
// situation where the enum is the top-level object (e.g., message-part
// in rpc-lit scenario)
//
// Sample of what enum looks like:
// @XmlEnum public enum EnumString {
// @XmlEnumValue("String1") STRING_1("String1"),
// @XmlEnumValue("String2") STRING_2("String2");
//
// public static getValue(String){} <-- resolves a "value" to an emum
// object
// ... }
if (DEBUG_ENABLED) {
log.debug("unmarshalByType. Unmarshalling " + type.getName()
+ " as Enum");
}
JAXBElement<String> enumValue = u.unmarshal(reader, String.class);
if (enumValue != null) {
Method m =
type.getMethod("fromValue", new Class[] { String.class });
jaxb = m.invoke(null, new Object[] { enumValue.getValue() });
} else {
jaxb = null;
}
}
//Normal case: We are not unmarshalling a xsd:list or Array
else {
jaxb = u.unmarshal(reader, type);
}
} else {
// If this is an xsd:list, we need to return the appropriate
// list or array (see NOTE above)
// First unmarshal as a String
//Second convert the String into a list or array
jaxb = unmarshalAsListOrArray(reader, u, type);
}
return jaxb;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
});
}
/**
* convert the String into a list or array
* @param <T>
* @param jaxb
* @param type
* @return
* @throws IllegalAccessException
* @throws ParseException
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws DatatypeConfigurationException
* @throws InvocationTargetException
*/
private static Object unmarshalAsListOrArray(XMLStreamReader reader, Unmarshaller u,
Class type)
throws IllegalAccessException, ParseException,NoSuchMethodException,InstantiationException,
DatatypeConfigurationException,InvocationTargetException,JAXBException {
//If this is an xsd:list, we need to return the appropriate
// list or array (see NOTE above)
// First unmarshal as a String
Object jaxb = u.unmarshal(reader, String.class);
//Second convert the String into a list or array
if (getTypeEnabledObject(jaxb) instanceof String) {
QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(jaxb);
Object obj = XSDListUtils.fromXSDListString((String) getTypeEnabledObject(jaxb), type);
return new JAXBElement(qName, type, obj);
} else {
return jaxb;
}
}
public boolean isElementData() {
return true;
}
/**
* Return type enabled object
*
* @param obj type or element enabled object
* @return type enabled object
*/
static Object getTypeEnabledObject(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof JAXBElement) {
return ((JAXBElement) obj).getValue();
}
return obj;
}
private static String getDebugName(Object o) {
return (o == null) ? "null" : o.getClass().getCanonicalName();
}
/**
* If the writer is backed by an OutputStream, then return the OutputStream
* @param writer
* @return OutputStream or null
*/
private static OutputStream getOutputStream(XMLStreamWriter writer) throws XMLStreamException {
if (writer.getClass() == MTOMXMLStreamWriter.class) {
return ((MTOMXMLStreamWriter) writer).getOutputStream();
}
return null;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?