diff options
Diffstat (limited to 'sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java')
-rw-r--r-- | sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java new file mode 100644 index 0000000000..4a240b3f55 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java @@ -0,0 +1,182 @@ +/* + * 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.tuscany.sca.databinding.jaxb; + +import java.beans.Introspector; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchema; +import javax.xml.bind.annotation.XmlType; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.databinding.TransformationContext; +import org.apache.tuscany.sca.databinding.TransformationException; +import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.util.XMLType; + +public class JAXBContextHelper { + // TODO: Do we need to set them for source and target? + public static final String JAXB_CLASSES = "jaxb.classes"; + + public static final String JAXB_CONTEXT_PATH = "jaxb.contextPath"; + + private JAXBContextHelper() { + } + + public static JAXBContext createJAXBContext(TransformationContext tContext, boolean source) throws JAXBException { + if (tContext == null) + throw new TransformationException("JAXB context is not set for the transformation."); + + DataType<?> dataType = source ? tContext.getSourceDataType() : tContext.getTargetDataType(); + // FIXME: We should check the context path or classes + // FIXME: What should we do if JAXB is an intermediate node? + + // String contextPath = null; + JAXBContext context = null; + Class<?> cls = getJavaType(dataType); + + context = JAXBContext.newInstance(cls); + + if (context == null) { + throw new TransformationException("JAXB context is not set for the transformation."); + } + return context; + } + + @SuppressWarnings("unchecked") + public static JAXBElement createJAXBElement(DataType dataType, Object value) { + if (value instanceof JAXBElement) { + return (JAXBElement)value; + } else { + Class type = dataType.getPhysical(); + Object logical = dataType.getLogical(); + QName elementName = JAXBDataBinding.ROOT_ELEMENT; + if (logical instanceof XMLType) { + XMLType xmlType = (XMLType)logical; + QName element = xmlType.getElementName(); + if (element != null) { + elementName = element; + } else { + /** + * Set the declared type to Object.class so that xsi:type + * will be produced + */ + type = Object.class; + } + } else { + type = Object.class; + } + return new JAXBElement(elementName, type, value); + } + } + + @SuppressWarnings("unchecked") + public static Object createReturnValue(DataType dataType, Object value) { + Class<?> cls = getJavaType(dataType); + if (cls == JAXBElement.class) { + return createJAXBElement(dataType, value); + } else { + if (value instanceof JAXBElement) { + return ((JAXBElement)value).getValue(); + } else { + return value; + } + } + } + + public static Class<?> getJavaType(DataType<?> dataType) { + if (dataType == null) { + return null; + } + Class type = dataType.getPhysical(); + if (JAXBElement.class.isAssignableFrom(type)) { + type = Object.class; + } + if (type == Object.class && dataType.getLogical() instanceof XMLType) { + XMLType xType = (XMLType)dataType.getLogical(); + Class javaType = SimpleTypeMapperImpl.getJavaType(xType.getTypeName()); + if (javaType != null) { + type = javaType; + } + } + return type; + } + + public static XMLType getXmlTypeName(Class<?> javaType) { + if (javaType.isInterface()) { + // JAXB doesn't support interfaces + return null; + } + String namespace = null; + String name = null; + Package pkg = javaType.getPackage(); + if (pkg != null) { + XmlSchema schema = pkg.getAnnotation(XmlSchema.class); + if (schema != null) { + namespace = schema.namespace(); + } + } + + QName elementQName = null; + QName typeQName = null; + XmlRootElement rootElement = javaType.getAnnotation(XmlRootElement.class); + if (rootElement != null) { + String elementName = rootElement.name(); + String elementNamespace = rootElement.namespace(); + if (elementNamespace.equals("##default")) { + elementNamespace = namespace; + } + if (elementName.equals("##default")) { + elementName = Introspector.decapitalize(javaType.getSimpleName()); + } + elementQName = new QName(elementNamespace, elementName); + } + XmlType type = javaType.getAnnotation(XmlType.class); + if (type != null) { + String typeNamespace = type.namespace(); + String typeName = type.name(); + + if (typeNamespace.equals("##default")) { + // namespace is from the package + typeNamespace = namespace; + } + + if (typeName.equals("##default")) { + typeName = Introspector.decapitalize(javaType.getSimpleName()); + } + typeQName = new QName(typeNamespace, typeName); + } else { + XmlEnum xmlEnum = javaType.getAnnotation(XmlEnum.class); + if (xmlEnum != null) { + name = Introspector.decapitalize(javaType.getSimpleName()); + typeQName = new QName(namespace, name); + } + } + if (elementQName == null && typeQName == null) { + return null; + } + return new XMLType(elementQName, typeQName); + } + +} |