diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java')
9 files changed, 923 insertions, 0 deletions
diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXB2Node.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXB2Node.java new file mode 100755 index 0000000000..34f3dbbac3 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXB2Node.java @@ -0,0 +1,72 @@ +/* + * 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.databinding.jaxb; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.Marshaller; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +@Service(Transformer.class) +public class JAXB2Node extends TransformerExtension<Object, Node> implements PullTransformer<Object, Node> { + + public Node transform(Object source, TransformationContext tContext) { + if (source == null) { + return null; + } + try { + JAXBContext context = JAXBContextHelper.createJAXBContext(tContext, true); + Marshaller marshaller = context.createMarshaller(); + // FIXME: The default Marshaller doesn't support + // marshaller.getNode() + Document document = DOMHelper.newDocument(); + JAXBElement<?> jaxbElement = JAXBContextHelper.createJAXBElement(tContext.getSourceDataType(), source); + marshaller.marshal(jaxbElement, document); + return document; + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Object.class; + } + + public Class getTargetType() { + return Node.class; + } + + public int getWeight() { + return 30; + } + + @Override + public String getSourceDataBinding() { + return JAXBDataBinding.NAME; + } +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBContextHelper.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBContextHelper.java new file mode 100644 index 0000000000..0fc554d785 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBContextHelper.java @@ -0,0 +1,192 @@ +/* + * 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.databinding.jaxb; + +import java.beans.Introspector; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +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.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.idl.XMLType; +import org.apache.tuscany.spi.model.DataType; +import org.apache.tuscany.spi.model.Operation; + +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."); + + // FIXME: We should check the context path or classes + // FIXME: What should we do if JAXB is an intermediate node? + DataType<?> bindingContext = source ? tContext.getSourceDataType() : tContext.getTargetDataType(); + String contextPath = (String)bindingContext.getMetadata(JAXB_CONTEXT_PATH); + if (contextPath == null) { + Operation op = (Operation)bindingContext.getOperation(); + contextPath = op != null ? (String)op.getMetaData().get(JAXB_CONTEXT_PATH) : null; + } + JAXBContext context = null; + if (contextPath != null) { + context = JAXBContext.newInstance(contextPath); + } else { + Class[] classes = (Class[])bindingContext.getMetadata(JAXB_CLASSES); + if (classes != null) { + context = JAXBContext.newInstance(classes); + } else { + Type type = bindingContext.getPhysical(); + if (type instanceof Class) { + Class cls = (Class)type; + if (cls.getPackage() != null) { + contextPath = cls.getPackage().getName(); + context = JAXBContext.newInstance(contextPath); + } + } + } + } + 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 = (Class)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; + } + Type type = dataType.getPhysical(); + if (type instanceof Class) { + Class cls = (Class)type; + if (JAXBElement.class.isAssignableFrom(cls)) { + return null; + } else { + return cls; + } + } else if (type instanceof ParameterizedType) { + ParameterizedType pType = (ParameterizedType)type; + return (Class)pType.getRawType(); + } + return null; + } + + public static XMLType getXmlTypeName(Class<?> javaType) { + 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(); + } + } + XmlType type = javaType.getAnnotation(XmlType.class); + if (type != null) { + String typeNamespace = type.namespace(); + String typeName = type.name(); + + if (typeNamespace.equals("##default") && typeName.equals("")) { + XmlRootElement rootElement = javaType.getAnnotation(XmlRootElement.class); + if (rootElement != null) { + namespace = rootElement.namespace(); + } else { + // FIXME: The namespace should be from the referencing + // property + namespace = null; + } + } else if (typeNamespace.equals("##default")) { + // namespace is from the package + } else { + namespace = typeNamespace; + } + + if (typeName.equals("##default")) { + name = Introspector.decapitalize(javaType.getSimpleName()); + } else { + name = typeName; + } + } else { + XmlEnum xmlEnum = javaType.getAnnotation(XmlEnum.class); + if (xmlEnum != null) { + name = Introspector.decapitalize(javaType.getSimpleName()); + } + } + if (name == null) { + return null; + } + return new XMLType(null, new QName(namespace, name)); + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBDataBinding.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBDataBinding.java new file mode 100644 index 0000000000..6fc8510717 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBDataBinding.java @@ -0,0 +1,114 @@ +/* + * 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.databinding.jaxb; + +import java.lang.annotation.Annotation; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.databinding.ExceptionHandler; +import org.apache.tuscany.spi.databinding.extension.DOMHelper; +import org.apache.tuscany.spi.databinding.extension.DataBindingExtension; +import org.apache.tuscany.spi.idl.XMLType; +import org.apache.tuscany.spi.model.DataType; +import org.w3c.dom.Document; + +/** + * JAXB DataBinding + */ +public class JAXBDataBinding extends DataBindingExtension { + public static final String NAME = JAXBElement.class.getName(); + public static final String[] ALIASES = new String[] {"jaxb"}; + + public static final String ROOT_NAMESPACE = "http://tuscany.apache.org/xmlns/sca/databinding/jaxb/1.0"; + public static final QName ROOT_ELEMENT = new QName(ROOT_NAMESPACE, "root"); + + public JAXBDataBinding() { + super(NAME, ALIASES, JAXBElement.class); + } + + @Override + public boolean introspect(DataType dataType, Annotation[] annotations) { + Object physical = dataType.getPhysical(); + if (!(physical instanceof Class)) { + return false; + } + Class javaType = (Class)physical; + if (JAXBElement.class.isAssignableFrom(javaType)) { + Type type = javaType.getGenericSuperclass(); + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = ((ParameterizedType)type); + Type rawType = parameterizedType.getRawType(); + if (rawType == JAXBElement.class) { + Type actualType = parameterizedType.getActualTypeArguments()[0]; + if (actualType instanceof Class) { + XMLType xmlType = JAXBContextHelper.getXmlTypeName((Class)actualType); + dataType.setLogical(xmlType); + dataType.setDataBinding(getName()); + return true; + } + } + } + dataType.setLogical(XMLType.UNKNOWN); + dataType.setDataBinding(getName()); + return true; + } + + XMLType xmlType = JAXBContextHelper.getXmlTypeName(javaType); + if (xmlType == null) { + return false; + } + dataType.setLogical(xmlType); + dataType.setDataBinding(getName()); + return true; + } + + @SuppressWarnings("unchecked") + @Override + public Object copy(Object arg) { + try { + boolean isElement = false; + Class cls = arg.getClass(); + if (arg instanceof JAXBElement) { + isElement = true; + cls = ((JAXBElement)arg).getDeclaredType(); + } else { + arg = new JAXBElement(ROOT_ELEMENT, Object.class, arg); + } + JAXBContext context = JAXBContext.newInstance(cls); + Document doc = DOMHelper.newDocument(); + context.createMarshaller().marshal(arg, doc); + JAXBElement<?> element = context.createUnmarshaller().unmarshal(doc, cls); + return isElement ? element : element.getValue(); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public ExceptionHandler getExceptionHandler() { + return new JAXBExceptionHandler(); + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandler.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandler.java new file mode 100644 index 0000000000..6b0c7ab10c --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandler.java @@ -0,0 +1,106 @@ +/* + * 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.databinding.jaxb; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import javax.xml.namespace.QName; +import javax.xml.ws.WebFault; + +import org.apache.tuscany.spi.databinding.ExceptionHandler; +import org.apache.tuscany.spi.idl.XMLType; +import org.apache.tuscany.spi.model.DataType; + +/** + * JAXB implementation of ExceptionHandler + * + * @version $Rev$ $Date$ + */ +public class JAXBExceptionHandler implements ExceptionHandler { + private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + + /** + * <ul> + * <li>WrapperException(String message, FaultBean faultInfo) <br> + * A constructor where WrapperException is replaced with the name of the + * generated wrapper exception and FaultBean is replaced by the name of the + * generated fault bean. + * <li> WrapperException(String message, FaultBean faultInfo, Throwable + * cause) <br> + * A constructor whereWrapperException is replaced with the name of the + * generated wrapper exception and FaultBean is replaced by the name of the + * generated fault bean. The last argument, cause, may be used to convey + * protocol specific fault information + * </ul> + */ + public Exception createException(DataType<DataType> exceptionType, String message, Object faultInfo, Throwable cause) { + Class exceptionClass = (Class)exceptionType.getPhysical(); + DataType<?> faultBeanType = exceptionType.getLogical(); + Class faultBeanClass = (Class)faultBeanType.getPhysical(); + try { + Constructor constructor = + exceptionClass.getConstructor(new Class[] {String.class, faultBeanClass, Throwable.class}); + return (Exception)constructor.newInstance(new Object[] {message, faultInfo, cause}); + } catch (Throwable e) { + throw new IllegalArgumentException(e); + } + } + + public Object getFaultInfo(Exception exception) { + if (exception == null) { + return null; + } + try { + Method method = exception.getClass().getMethod("getFaultInfo", EMPTY_CLASS_ARRAY); + return method.invoke(exception, (Object[])null); + } catch (Throwable e) { + throw new IllegalArgumentException(e); + } + } + + public DataType<?> getFaultType(DataType exDataType) { + Class<?> exceptionType = (Class) exDataType.getPhysical(); + WebFault webFault = exceptionType.getAnnotation(WebFault.class); + if (webFault == null) { + return null; + } else { + QName element = new QName(webFault.targetNamespace(), webFault.name()); + // TODO: Need to determine the fault bean class + // String faultBean = webFault.faultBean(); + Class faultBeanClass = null; + try { + Method method = exceptionType.getMethod("getFaultInfo", EMPTY_CLASS_ARRAY); + faultBeanClass = method.getReturnType(); + } catch (NoSuchMethodException e) { + faultBeanClass = null; + } + // The logical type of a fault is the QName of the element that the + // only part in + // the fault message references + DataType<XMLType> faultType = + new DataType<XMLType>(JAXBDataBinding.NAME, faultBeanClass, new XMLType(element, null)); + // faultType.setMetadata(ElementInfo.class.getName(), new + // ElementInfo(element, null)); + return faultType; + } + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandler.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandler.java new file mode 100644 index 0000000000..449fc4c75e --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandler.java @@ -0,0 +1,123 @@ +/* + * 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.databinding.jaxb; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.bind.annotation.XmlType; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.WrapperHandler; +import org.apache.tuscany.spi.idl.ElementInfo; + +/** + * JAXB WrapperHandler implementation + */ +public class JAXBWrapperHandler implements WrapperHandler<JAXBElement<?>> { + + public JAXBElement<?> create(ElementInfo element, TransformationContext context) { + try { + // FIXME: How do we map the global element to a factory? + String packageName = null; + String factoryClassName = packageName + ".ObjectFactory"; + ClassLoader classLoader = context != null ? context.getClassLoader() : null; + if (classLoader == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + } + Class<?> factoryClass = Class.forName(factoryClassName, true, classLoader); + assert factoryClass.isAnnotationPresent(XmlRegistry.class); + Object factory = factoryClass.newInstance(); + QName elementName = element.getQName(); + Method method = null; + for (Method m : factoryClass.getMethods()) { + XmlElementDecl xmlElement = m.getAnnotation(XmlElementDecl.class); + QName name = new QName(xmlElement.namespace(), xmlElement.name()); + if (xmlElement != null && name.equals(elementName)) { + method = m; + break; + } + } + if (method != null) { + Class typeClass = method.getParameterTypes()[0]; + Object value = typeClass.newInstance(); + return (JAXBElement<?>)method.invoke(factory, new Object[] {value}); + } else { + throw new TransformationException("ObjectFactory cannot be resolved."); + } + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public void setChild(JAXBElement<?> wrapper, int i, ElementInfo childElement, Object value) { + Object wrapperValue = wrapper.getValue(); + Class<?> wrapperClass = wrapperValue.getClass(); + + XmlType xmlType = wrapperClass.getAnnotation(XmlType.class); + String[] properties = xmlType.propOrder(); + String property = properties[i]; + + try { + for (Method m : wrapperClass.getMethods()) { + if (m.getName().equals("set" + capitalize(property))) { + m.invoke(wrapperValue, new Object[] {value}); + return; + } + } + } catch (Throwable e) { + throw new TransformationException(e); + } + } + + private static String capitalize(String name) { + char first = Character.toUpperCase(name.charAt(0)); + return first + name.substring(1); + } + + /** + * @see org.apache.tuscany.spi.databinding.WrapperHandler#getChildren(java.lang.Object) + */ + public List getChildren(JAXBElement<?> wrapper) { + Object wrapperValue = wrapper.getValue(); + Class<?> wrapperClass = wrapperValue.getClass(); + + XmlType xmlType = wrapperClass.getAnnotation(XmlType.class); + String[] properties = xmlType.propOrder(); + List<Object> elements = new ArrayList<Object>(); + for (String p : properties) { + try { + Method method = wrapperClass.getMethod("get" + capitalize(p), (Class[])null); + Object value = method.invoke(wrapperValue, (Object[])null); + elements.add(value); + } catch (Throwable e) { + throw new TransformationException(e); + } + } + return elements; + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXWSJavaInterfaceProcessor.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXWSJavaInterfaceProcessor.java new file mode 100644 index 0000000000..8ad3d38b82 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/JAXWSJavaInterfaceProcessor.java @@ -0,0 +1,107 @@ +/* + * 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.databinding.jaxb; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Map; + +import javax.jws.WebMethod; +import javax.jws.WebService; +import javax.xml.namespace.QName; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + +import org.apache.tuscany.spi.idl.ElementInfo; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.idl.java.JavaInterfaceProcessorExtension; +import org.apache.tuscany.spi.idl.java.JavaServiceContract; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.WrapperInfo; + +/** + * The databinding annotation processor for java interfaces + * + * @version $Rev$ $Date$ + */ +public class JAXWSJavaInterfaceProcessor extends JavaInterfaceProcessorExtension { + + public JAXWSJavaInterfaceProcessor() { + super(); + } + + public void visitInterface(Class<?> clazz, Class<?> callbackClass, JavaServiceContract contract) + throws InvalidServiceContractException { + if (!contract.isRemotable()) { + return; + } + Map<String, Operation<Type>> operations = contract.getOperations(); + processInterface(clazz, contract, operations); + if (callbackClass != null) { + Map<String, Operation<Type>> callbackOperations = contract.getCallbackOperations(); + processInterface(callbackClass, contract, callbackOperations); + } + } + + private static String getValue(String value, String defaultValue) { + return "".equals(value) ? defaultValue : value; + } + + private void processInterface(Class<?> clazz, JavaServiceContract contract, Map<String, Operation<Type>> operations) { + + for (Method method : clazz.getMethods()) { + Operation<?> operation = operations.get(method.getName()); + + WebMethod webMethod = method.getAnnotation(WebMethod.class); + if (webMethod == null) { + return; + } + + String operationName = getValue(webMethod.operationName(), operation.getName()); + + RequestWrapper requestWrapper = method.getAnnotation(RequestWrapper.class); + ResponseWrapper responseWrapper = method.getAnnotation(ResponseWrapper.class); + if (requestWrapper == null) { + return; + } + + WebService webService = clazz.getAnnotation(WebService.class); + String tns = ""; + if (webService != null) { + tns = webService.targetNamespace(); + } + + String ns = getValue(requestWrapper.targetNamespace(), tns); + String name = getValue(requestWrapper.localName(), operationName); + QName inputWrapper = new QName(ns, name); + + ns = getValue(responseWrapper.targetNamespace(), tns); + name = getValue(responseWrapper.localName(), operationName + "Response"); + + QName outputWrapper = new QName(ns, name); + + WrapperInfo wrapperInfo = + new WrapperInfo(JAXBDataBinding.NAME, new ElementInfo(inputWrapper, null), + new ElementInfo(outputWrapper, null), null, null); + operation.setWrapperStyle(true); + operation.setWrapper(wrapperInfo); + } + } +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Node2JAXB.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Node2JAXB.java new file mode 100755 index 0000000000..301e316889 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Node2JAXB.java @@ -0,0 +1,69 @@ +/* + * 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.databinding.jaxb; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Node; + +@Service(Transformer.class) +public class Node2JAXB extends TransformerExtension<Node, Object> implements PullTransformer<Node, Object> { + + public Node2JAXB() { + super(); + } + + public Object transform(Node source, TransformationContext context) { + if (source == null) + return null; + try { + JAXBContext jaxbContext = JAXBContextHelper.createJAXBContext(context, false); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + Object result = unmarshaller.unmarshal(source); + return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Node.class; + } + + public Class getTargetType() { + return Object.class; + } + + public int getWeight() { + return 30; + } + + @Override + public String getTargetDataBinding() { + return JAXBDataBinding.NAME; + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Reader2JAXB.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Reader2JAXB.java new file mode 100644 index 0000000000..273c15db1b --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/Reader2JAXB.java @@ -0,0 +1,70 @@ +/* + * 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.databinding.jaxb; + +import java.io.Reader; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class Reader2JAXB extends TransformerExtension<Reader, Object> implements + PullTransformer<Reader, Object> { + + public Object transform(final Reader source, final TransformationContext context) { + if (source == null) { + return null; + } + try { + JAXBContext jaxbContext = JAXBContextHelper.createJAXBContext(context, false); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + StreamSource streamSource = new StreamSource(source); + Object result = unmarshaller.unmarshal(streamSource); + return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return Reader.class; + } + + public Class getTargetType() { + return Object.class; + } + + public int getWeight() { + return 30; + } + + @Override + public String getTargetDataBinding() { + return JAXBDataBinding.NAME; + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/XMLStreamReader2JAXB.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/XMLStreamReader2JAXB.java new file mode 100755 index 0000000000..3f6a2f64d3 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/java/org/apache/tuscany/databinding/jaxb/XMLStreamReader2JAXB.java @@ -0,0 +1,70 @@ +/* + * 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.databinding.jaxb; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.spi.databinding.PullTransformer; +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.databinding.TransformationException; +import org.apache.tuscany.spi.databinding.Transformer; +import org.apache.tuscany.spi.databinding.extension.TransformerExtension; +import org.osoa.sca.annotations.Service; + +@Service(Transformer.class) +public class XMLStreamReader2JAXB extends TransformerExtension<XMLStreamReader, Object> implements + PullTransformer<XMLStreamReader, Object> { + + public XMLStreamReader2JAXB() { + super(); + } + + public Object transform(XMLStreamReader source, TransformationContext context) { + if (source == null) { + return null; + } + try { + JAXBContext jaxbContext = JAXBContextHelper.createJAXBContext(context, false); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + Object result = unmarshaller.unmarshal(source); + return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result); + } catch (Exception e) { + throw new TransformationException(e); + } + } + + public Class getSourceType() { + return XMLStreamReader.class; + } + + public Class getTargetType() { + return Object.class; + } + + public int getWeight() { + return 10; + } + + @Override + public String getTargetDataBinding() { + return JAXBDataBinding.NAME; + } +} |