diff options
Diffstat (limited to 'branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src')
19 files changed, 1698 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; + } +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/databinding.jaxb.scdl b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/databinding.jaxb.scdl new file mode 100644 index 0000000000..13a33a935c --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/databinding.jaxb.scdl @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--
+ * 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.
+--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.databinding.jaxb.include">
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.services.databinding</group>
+ <name>databinding-jaxb</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version> + </dependency>
+
+ <component name="databinding.jaxb">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.JAXBDataBinding" />
+ </component>
+
+ <component name="transformer.XMLStreamReader2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.XMLStreamReader2JAXB" />
+ </component>
+
+ <component name="transformer.Node2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.Node2JAXB" />
+ </component>
+
+ <component name="transformer.JAXB2Node">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.JAXB2Node" />
+ </component>
+
+ <component name="transformer.Reader2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.Reader2JAXB" />
+ </component>
+
+</composite> diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/default.scdl b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..00f321922e --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/default.scdl @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--
+ * 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.
+--> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.databinding.jaxb">
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.services.databinding</group>
+ <name>databinding-jaxb</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version> + </dependency>
+
+ <component name="databinding.jaxb">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.JAXBDataBinding" />
+ </component>
+
+ <component name="transformer.XMLStreamReader2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.XMLStreamReader2JAXB" />
+ </component>
+
+ <component name="transformer.Node2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.Node2JAXB" />
+ </component>
+
+ <component name="transformer.JAXB2Node">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.JAXB2Node" />
+ </component>
+
+ <component name="transformer.Reader2JAXB">
+ <system:implementation.system class="org.apache.tuscany.databinding.jaxb.Reader2JAXB" />
+ </component>
+
+</composite> diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/extension.composite b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/extension.composite new file mode 100644 index 0000000000..36f0d251bb --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/main/resources/META-INF/sca/extension.composite @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="org.apache.tuscany.databinding.jaxb">
+ <include name="org.apache.tuscany.databinding.jaxb.include" scdlLocation="databinding.jaxb.scdl" />
+</composite>
\ No newline at end of file diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java new file mode 100644 index 0000000000..ac12d2f2a8 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java @@ -0,0 +1,127 @@ +/* + * 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 javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.spi.idl.XMLType; +import org.apache.tuscany.spi.model.DataType; + +import com.example.ipo.jaxb.ObjectFactory; +import com.example.ipo.jaxb.PurchaseOrderType; +import com.example.ipo.jaxb.USAddress; +import com.example.ipo.jaxb.USState; + +/** + * + */ +public class JAXBDataBindingTestCase extends TestCase { + private JAXBDataBinding binding; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + binding = new JAXBDataBinding(); + } + + /** + * Test method for + * {@link org.apache.tuscany.databinding.jaxb.JAXBDataBinding#introspect(java.lang.Class, Annotation)}. + */ + public final void testIntrospect() { + DataType dataType = new DataType(JAXBElement.class, null); + boolean yes = binding.introspect(dataType, null); + assertTrue(yes); + assertTrue(dataType.getDataBinding().equals(binding.getName())); + assertTrue(dataType.getPhysical() == JAXBElement.class && dataType.getLogical() == XMLType.UNKNOWN); + dataType = new DataType(MockJAXBElement.class, null); + yes = binding.introspect(dataType, null); + assertTrue(yes); + assertEquals(MockJAXBElement.class, dataType.getPhysical()); + assertEquals(new QName("http://www.example.com/IPO", "PurchaseOrderType"), ((XMLType)dataType.getLogical()) + .getTypeName()); + dataType = new DataType(USAddress.class, null); + yes = binding.introspect(dataType, null); + assertTrue(yes); + assertEquals(USAddress.class, dataType.getPhysical()); + assertEquals(new QName("http://www.example.com/IPO", "USAddress"), ((XMLType)dataType.getLogical()) + .getTypeName()); + dataType = new DataType(USState.class, null); + yes = binding.introspect(dataType, null); + assertTrue(yes); + assertTrue(dataType.getDataBinding().equals(binding.getName())); + assertEquals(USState.class, dataType.getPhysical()); + assertEquals(new QName("http://www.example.com/IPO", "USState"), ((XMLType)dataType.getLogical()).getTypeName()); + + } + + private static class MockJAXBElement extends JAXBElement<PurchaseOrderType> { + + private static final long serialVersionUID = -2767569071002707973L; + + /** + * @param elementName + * @param type + * @param value + */ + public MockJAXBElement(QName elementName, Class<PurchaseOrderType> type, PurchaseOrderType value) { + super(elementName, type, value); + } + + } + + @SuppressWarnings("unchecked") + public void testCopy() { + ObjectFactory factory = new ObjectFactory(); + PurchaseOrderType poType = factory.createPurchaseOrderType(); + JAXBElement<PurchaseOrderType> po = factory.createPurchaseOrder(poType); + JAXBElement<PurchaseOrderType> copy = (JAXBElement<PurchaseOrderType>)binding.copy(po); + assertEquals(new QName("http://www.example.com/IPO", "purchaseOrder"), copy.getName()); + } + + @SuppressWarnings("unchecked") + public void testCopyNonElement() { + ObjectFactory factory = new ObjectFactory(); + PurchaseOrderType poType = factory.createPurchaseOrderType(); + poType.setComment("Comment"); + PurchaseOrderType copy = (PurchaseOrderType)binding.copy(poType); + assertTrue(copy instanceof PurchaseOrderType); + assertEquals("Comment", ((PurchaseOrderType)copy).getComment()); + } + + @SuppressWarnings("unchecked") + public void testCopyNonRoot() { + ObjectFactory factory = new ObjectFactory(); + USAddress address = factory.createUSAddress(); + address.setCity("San Jose"); + USAddress copy = (USAddress)binding.copy(address); + assertTrue(copy instanceof USAddress); + assertEquals("San Jose", ((USAddress)copy).getCity()); + + } +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandlerTestCase.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandlerTestCase.java new file mode 100644 index 0000000000..62990e38a6 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBExceptionHandlerTestCase.java @@ -0,0 +1,77 @@ +/* + * 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.namespace.QName; + +import org.apache.tuscany.databinding.jaxb.fault.InvalidSymbolFault; +import org.apache.tuscany.databinding.jaxb.fault.InvalidSymbolFault_Exception; +import org.apache.tuscany.spi.idl.XMLType; +import org.apache.tuscany.spi.model.DataType; + +import junit.framework.TestCase; + +/** + * Test case for JAXBExceptionHandler + */ +public class JAXBExceptionHandlerTestCase extends TestCase { + private static final QName ELEMENT = new QName("http://www.example.com/stock", "InvalidSymbolFault"); + private JAXBExceptionHandler handler; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + this.handler = new JAXBExceptionHandler(); + } + + public void testGetFaultType() { + DataType exType = new DataType<XMLType>(InvalidSymbolFault_Exception.class, XMLType.UNKNOWN); + DataType<?> dataType = handler.getFaultType(exType); + assertEquals(InvalidSymbolFault.class, dataType.getPhysical()); + assertEquals(ELEMENT, ((XMLType) dataType.getLogical()).getElementName()); + assertEquals(JAXBDataBinding.NAME, dataType.getDataBinding()); + } + + public void testCreate() { + DataType execType = new DataType<XMLType>(InvalidSymbolFault_Exception.class, XMLType.UNKNOWN); + DataType<?> faultType = handler.getFaultType(execType); + InvalidSymbolFault fault = new InvalidSymbolFault(); + fault.setMessage("ABC"); + fault.setSymbol("IBM0"); + DataType<DataType> exType = new DataType<DataType>(InvalidSymbolFault_Exception.class, faultType); + Exception ex = handler.createException(exType, "Invalid symbol", fault, null); + assertTrue(ex instanceof InvalidSymbolFault_Exception); + InvalidSymbolFault_Exception exception = (InvalidSymbolFault_Exception)ex; + assertEquals("Invalid symbol", exception.getMessage()); + assertSame(fault, exception.getFaultInfo()); + } + + public void testGetFaultInfo() { + InvalidSymbolFault fault = new InvalidSymbolFault(); + fault.setMessage("ABC"); + fault.setSymbol("IBM0"); + InvalidSymbolFault_Exception exception = new InvalidSymbolFault_Exception("Invalid symbol", fault); + Object faultInfo = handler.getFaultInfo(exception); + assertSame(fault, faultInfo); + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java new file mode 100755 index 0000000000..08583d9729 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java @@ -0,0 +1,158 @@ +/* + * 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 static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +import java.io.StringReader; + +import javax.xml.namespace.QName; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.apache.tuscany.spi.databinding.TransformationContext; +import org.apache.tuscany.spi.model.DataType; +import org.w3c.dom.Node; + +import com.example.ipo.jaxb.ObjectFactory; +import com.example.ipo.jaxb.PurchaseOrderType; + +public class JAXBTestCase extends TestCase { + private static final String IPO_XML = + "<?xml version=\"1.0\"?>" + "<ipo:purchaseOrder" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + + " xmlns:ipo=\"http://www.example.com/IPO\"" + + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\"" + + " orderDate=\"1999-12-01\">" + + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">" + + " <name>Helen Zoe</name>" + + " <street>47 Eden Street</street>" + + " <city>Cambridge</city>" + + " <postcode>CB1 1JR</postcode>" + + " </shipTo>" + + " <billTo xsi:type=\"ipo:USAddress\">" + + " <name>Robert Smith</name>" + + " <street>8 Oak Avenue</street>" + + " <city>Old Town</city>" + + " <state>PA</state>" + + " <zip>95819</zip>" + + " </billTo>" + + " <items>" + + " <item partNum=\"833-AA\">" + + " <productName>Lapis necklace</productName>" + + " <quantity>1</quantity>" + + " <USPrice>99.95</USPrice>" + + " <ipo:comment>Want this for the holidays</ipo:comment>" + + " <shipDate>1999-12-05</shipDate>" + + " </item>" + + " </items>" + + "</ipo:purchaseOrder>"; + + private String contextPath = "com.example.ipo.jaxb"; + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testTransform() throws Exception { + Reader2JAXB t0 = new Reader2JAXB(); + + DataType targetDataType = new DataType<Class>(Object.class, null); + targetDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath); + + TransformationContext tContext = createMock(TransformationContext.class); + expect(tContext.getTargetDataType()).andReturn(targetDataType).anyTimes(); + replay(tContext); + + Object object1 = t0.transform(new StringReader(IPO_XML), tContext); + + DataType sourceDataType = new DataType<Class>(Object.class, null); + sourceDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath); + + TransformationContext tContext1 = createMock(TransformationContext.class); + expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes(); + replay(tContext1); + + JAXB2Node t1 = new JAXB2Node(); + Node node = t1.transform(object1, tContext1); + + Assert.assertNotNull(node); + + Node2JAXB t2 = new Node2JAXB(); + Object object2 = t2.transform(node, tContext); + Assert.assertNotNull(object2); + + } + + public void testTransform2() throws Exception { + Reader2JAXB t0 = new Reader2JAXB(); + + QName root = new QName("http://www.example.com/IPO", "purchaseOrder"); + DataType targetDataType = new DataType<QName>(PurchaseOrderType.class, root); + // targetDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath); + + TransformationContext tContext = createMock(TransformationContext.class); + expect(tContext.getTargetDataType()).andReturn(targetDataType).anyTimes(); + replay(tContext); + + Object object1 = t0.transform(new StringReader(IPO_XML), tContext); + + DataType sourceDataType = new DataType<QName>(PurchaseOrderType.class, root); + // sourceDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath); + + TransformationContext tContext1 = createMock(TransformationContext.class); + expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes(); + replay(tContext1); + + JAXB2Node t1 = new JAXB2Node(); + Node node = t1.transform(object1, tContext1); + + Assert.assertNotNull(node); + + Node2JAXB t2 = new Node2JAXB(); + Object object2 = t2.transform(node, tContext); + Assert.assertNotNull(object2); + + } + + public void testTransform3() throws Exception { + + DataType sourceDataType = new DataType<Class>(PurchaseOrderType.class, null); + sourceDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath); + + TransformationContext tContext1 = createMock(TransformationContext.class); + expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes(); + replay(tContext1); + + JAXB2Node t1 = new JAXB2Node(); + PurchaseOrderType po = new ObjectFactory().createPurchaseOrderType(); + Node node = t1.transform(po, tContext1); + + Assert.assertNotNull(node); + + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.java new file mode 100644 index 0000000000..d6267013fe --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.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 java.util.List; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +import junit.framework.TestCase; + +import org.apache.tuscany.spi.idl.ElementInfo; + +import com.example.ipo.jaxb.ObjectFactory; +import com.example.ipo.jaxb.PurchaseOrderType; + +/** + * Test case for JAXBExceptionHandler + */ +public class JAXBWrapperHandlerTestCase extends TestCase { + private static final QName ELEMENT = new QName("http://www.example.com/IPO", "purchaseOrder"); + private JAXBWrapperHandler handler; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + this.handler = new JAXBWrapperHandler(); + } + + public void testCreate() { + // ElementInfo element = new ElementInfo(ELEMENT, null); + // JAXBElement<?> jaxbElement = handler.create(element, null); + } + + public void testSetChild() { + ObjectFactory factory = new ObjectFactory(); + PurchaseOrderType po = factory.createPurchaseOrderType(); + JAXBElement<PurchaseOrderType> wrapper = factory.createPurchaseOrder(po); + handler.setChild(wrapper, 2, null, "Comment"); + } + + public void testGetChildren() { + ObjectFactory factory = new ObjectFactory(); + PurchaseOrderType po = factory.createPurchaseOrderType(); + po.setComment("Comment"); + JAXBElement<PurchaseOrderType> wrapper = factory.createPurchaseOrder(po); + List children = handler.getChildren(wrapper); + assertNotNull(children); + assertEquals(4, children.size()); + assertEquals("Comment", children.get(2)); + assertNull(children.get(0)); + } +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault.java new file mode 100644 index 0000000000..240ffaea7b --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault.java @@ -0,0 +1,59 @@ +package org.apache.tuscany.databinding.jaxb.fault; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * <p> + * Java class for anonymous complex type. + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = {"message", "symbol"}) +@XmlRootElement(name = "InvalidSymbolFault") +public class InvalidSymbolFault { + + @XmlElement(required = true) + protected String message; + @XmlElement(required = true) + protected String symbol; + + /** + * Gets the value of the message property. + * + * @return possible object is {@link String } + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value allowed object is {@link String } + */ + public void setMessage(String value) { + this.message = value; + } + + /** + * Gets the value of the symbol property. + * + * @return possible object is {@link String } + */ + public String getSymbol() { + return symbol; + } + + /** + * Sets the value of the symbol property. + * + * @param value allowed object is {@link String } + */ + public void setSymbol(String value) { + this.symbol = value; + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault_Exception.java b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault_Exception.java new file mode 100644 index 0000000000..4a7d8d8660 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/fault/InvalidSymbolFault_Exception.java @@ -0,0 +1,44 @@ +package org.apache.tuscany.databinding.jaxb.fault; + +import javax.xml.ws.WebFault; + +/** + * This class was generated by the JAXWS SI. JAX-WS RI 2.1-02/02/2007 09:55 + * AM(vivekp)-FCS Generated source version: 2.1 + */ +@WebFault(name = "InvalidSymbolFault", targetNamespace = "http://www.example.com/stock") +public class InvalidSymbolFault_Exception extends Exception { + + /** + * Java type that goes as soapenv:Fault detail element. + */ + private InvalidSymbolFault faultInfo; + + /** + * @param faultInfo + * @param message + */ + public InvalidSymbolFault_Exception(String message, InvalidSymbolFault faultInfo) { + super(message); + this.faultInfo = faultInfo; + } + + /** + * @param faultInfo + * @param message + * @param cause + */ + public InvalidSymbolFault_Exception(String message, InvalidSymbolFault faultInfo, Throwable cause) { + super(message, cause); + this.faultInfo = faultInfo; + } + + /** + * @return returns fault bean: + * org.apache.tuscany.sca.test.exceptions.impl.jaxb.InvalidSymbolFault + */ + public InvalidSymbolFault getFaultInfo() { + return faultInfo; + } + +} diff --git a/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/resources/ipo.xsd b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/resources/ipo.xsd new file mode 100755 index 0000000000..5468542693 --- /dev/null +++ b/branches/sca-java-integration/sca/services/databinding/databinding-jaxb/src/test/resources/ipo.xsd @@ -0,0 +1,118 @@ +<schema targetNamespace="http://www.example.com/IPO" + xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:ipo="http://www.example.com/IPO"> + + <annotation> + <documentation xml:lang="en"> + International Purchase order schema for Example.com + Copyright 2000 Example.com. All rights reserved. + </documentation> + </annotation> + + + <element name="purchaseOrder" type="ipo:PurchaseOrderType" /> + + <element name="comment" type="string" /> + + <complexType name="PurchaseOrderType"> + <sequence> + <element name="shipTo" type="ipo:Address" /> + <element name="billTo" type="ipo:Address" /> + <element ref="ipo:comment" minOccurs="0" /> + <element name="items" type="ipo:Items" /> + </sequence> + <attribute name="orderDate" type="date" /> + </complexType> + + <complexType name="Items"> + <sequence> + <element name="item" minOccurs="0" maxOccurs="unbounded"> + <complexType> + <sequence> + <element name="productName" type="string" /> + <element name="quantity"> + <simpleType> + <restriction base="positiveInteger"> + <maxExclusive value="100" /> + </restriction> + </simpleType> + </element> + <element name="USPrice" type="decimal" /> + <element ref="ipo:comment" minOccurs="0" /> + <element name="shipDate" type="date" + minOccurs="0" /> + </sequence> + <attribute name="partNum" type="ipo:SKU" + use="required" /> + </complexType> + </element> + </sequence> + </complexType> + + <simpleType name="SKU"> + <restriction base="string"> + <pattern value="\d{3}-[A-Z]{2}" /> + </restriction> + </simpleType> + + <complexType name="Address"> + <sequence> + <element name="name" type="string" /> + <element name="street" type="string" /> + <element name="city" type="string" /> + </sequence> + </complexType> + + <complexType name="USAddress"> + <complexContent> + <extension base="ipo:Address"> + <sequence> + <element name="state" type="ipo:USState" /> + <element name="zip" type="positiveInteger" /> + </sequence> + </extension> + </complexContent> + </complexType> + + <complexType name="UKAddress"> + <complexContent> + <extension base="ipo:Address"> + <sequence> + <element name="postcode" type="ipo:UKPostcode" /> + </sequence> + <attribute name="exportCode" type="positiveInteger" + fixed="1" /> + </extension> + </complexContent> + </complexType> + + <!-- other Address derivations for more countries --> + + <simpleType name="USState"> + <restriction base="string"> + <enumeration value="AK" /> + <enumeration value="AL" /> + <enumeration value="AR" /> + <enumeration value="CA" /> + <enumeration value="PA" /> + <!-- and so on ... --> + </restriction> + </simpleType> + + <simpleType name="Postcode"> + <restriction base="string"> + <length value="7" fixed="true" /> + </restriction> + </simpleType> + + + <simpleType name="UKPostcode"> + <restriction base="ipo:Postcode"> + <pattern value="[A-Z]{2}\d\s\d[A-Z]{2}" /> + </restriction> + </simpleType> + + + +</schema> + |