summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src')
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/BeanXMLStreamReaderImpl.java313
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2Node.java72
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2SAX.java70
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2String.java74
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2XMLStreamReader.java73
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java182
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java106
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBWrapperHandler.java175
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Node2JAXB.java69
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Reader2JAXB.java70
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/String2JAXB.java76
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/XMLStreamReader2JAXB.java73
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding19
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer32
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java129
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBReflectionTestCase.java108
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java163
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.java72
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyBean.java158
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterface.java29
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterfaceImpl.java67
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/POJOTestCase.java219
-rw-r--r--sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/resources/ipo.xsd136
23 files changed, 2485 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/BeanXMLStreamReaderImpl.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/BeanXMLStreamReaderImpl.java
new file mode 100644
index 0000000000..359d0fa20d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/BeanXMLStreamReaderImpl.java
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
+import org.apache.tuscany.sca.databinding.xml.SimpleXmlNodeImpl;
+import org.apache.tuscany.sca.databinding.xml.XmlNode;
+import org.apache.tuscany.sca.databinding.xml.XmlTreeStreamReaderImpl;
+import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
+import org.jvnet.jaxb.reflection.model.annotation.RuntimeInlineAnnotationReader;
+import org.jvnet.jaxb.reflection.model.core.Ref;
+import org.jvnet.jaxb.reflection.model.impl.RuntimeModelBuilder;
+import org.jvnet.jaxb.reflection.model.runtime.RuntimeClassInfo;
+import org.jvnet.jaxb.reflection.model.runtime.RuntimePropertyInfo;
+import org.jvnet.jaxb.reflection.model.runtime.RuntimeTypeInfoSet;
+import org.jvnet.jaxb.reflection.runtime.IllegalAnnotationsException;
+import org.jvnet.jaxb.reflection.runtime.JAXBContextImpl;
+
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BeanXMLStreamReaderImpl extends XmlTreeStreamReaderImpl {
+ private final static Comparator<Accessor> COMPARATOR = new Comparator<Accessor>() {
+ public int compare(Accessor o1, Accessor o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private final static String XSI_PREFIX = "xsi";
+ private final static String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
+
+ private final static XmlNode getXSIType(QName realType) {
+ QName xsiType = new QName(XSI_NS, "type", XSI_PREFIX);
+ String prefix = realType.getPrefix();
+ String typeName = realType.getLocalPart();
+ if (prefix != null && !prefix.equals("")) {
+ typeName = prefix + ":" + realType.getLocalPart();
+ }
+ return new SimpleXmlNodeImpl(xsiType, XmlNode.Type.ATTRIBUTE);
+ }
+
+ /**
+ * Represent a Map.Entry XML node
+ * @version $Rev$ $Date$
+ */
+ public static class MapEntryXmlNodeImpl extends SimpleXmlNodeImpl implements XmlNode {
+ private Map.Entry entry;
+
+ public MapEntryXmlNodeImpl(Entry entry) {
+ super(new QName("", "entry"), entry);
+ this.entry = entry;
+ }
+
+ public Iterator<XmlNode> children() {
+ List<XmlNode> nodes = new ArrayList<XmlNode>();
+ XmlNode key = new BeanXmlNodeImpl(new QName("", "key"), entry.getKey());
+ XmlNode value = new BeanXmlNodeImpl(new QName("", "value"), entry.getValue());
+ nodes.add(key);
+ nodes.add(value);
+ return nodes.iterator();
+ }
+ }
+
+ public static class BeanXmlNodeImpl extends SimpleXmlNodeImpl implements XmlNode {
+ private static final Object[] NULL = null;
+ private static final SimpleTypeMapperImpl MAPPER = new SimpleTypeMapperImpl();
+
+ public BeanXmlNodeImpl(Object bean) {
+ super(getName(bean == null ? null : bean.getClass()), bean);
+ }
+
+ public BeanXmlNodeImpl(QName name, Object bean) {
+ super(name, bean);
+ }
+
+ private static boolean isSimpleType(Class<?> javaType) {
+ return SimpleTypeMapperImpl.getXMLType(javaType) != null;
+ }
+
+ private static String getStringValue(Object o) {
+ if (o == null) {
+ return null;
+ }
+ TypeInfo info = SimpleTypeMapperImpl.getXMLType(o.getClass());
+ if (info != null) {
+ return MAPPER.toXMLLiteral(info.getQName(), o, null);
+ } else {
+ return String.valueOf(o);
+ }
+ }
+
+ public Iterator<XmlNode> children() {
+ if (name == null) {
+ return null;
+ }
+ if (value == null) {
+ return super.children();
+ }
+ if (isSimpleType(value.getClass())) {
+ XmlNode textNode = new BeanXmlNodeImpl(null, value);
+ return Arrays.asList(textNode).iterator();
+ }
+ if (Map.class.isAssignableFrom(value.getClass())) {
+ List<XmlNode> entries = new ArrayList<XmlNode>();
+ Map map = (Map)value;
+ if (map != null) {
+ for (Object e : map.entrySet()) {
+ Map.Entry entry = (Map.Entry)e;
+ entries.add(new MapEntryXmlNodeImpl(entry));
+ }
+ }
+ return entries.iterator();
+ }
+ try {
+ Map<String, Accessor> accessorMap = getAccessors(value);
+ List<Accessor> accessorList = new ArrayList<Accessor>(accessorMap.values());
+ Collections.sort(accessorList, COMPARATOR);
+
+ List<XmlNode> props = new ArrayList<XmlNode>();
+ for (Accessor accessor : accessorList) {
+ Class<?> pType = accessor.getType();
+
+ QName pName = new QName(name.getNamespaceURI(), accessor.getName());
+ Object pValue = accessor.getValue();
+ if (pType.isArray()) {
+ if (pValue != null) {
+ int i1 = Array.getLength(pValue);
+ for (int j = 0; j < i1; j++) {
+ Object o = Array.get(pValue, j);
+ props.add(new BeanXmlNodeImpl(pName, o));
+ }
+ } else {
+ // TODO: How to handle null?
+ }
+ } else if (Collection.class.isAssignableFrom(pType)) {
+ Collection objList = (Collection)pValue;
+ if (objList != null && objList.size() > 0) {
+ for (Iterator j = objList.iterator(); j.hasNext();) {
+ Object o = j.next();
+ props.add(new BeanXmlNodeImpl(pName, o));
+ }
+
+ } else {
+ // How to handle null
+ }
+ } else {
+ props.add(new BeanXmlNodeImpl(pName, pValue));
+ }
+ }
+ return props.iterator();
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public QName getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return getStringValue(value);
+ }
+
+ public static QName getName(Class<?> cls) {
+ if (cls == null) {
+ return null;
+ }
+ Package pkg = cls.getPackage();
+ if (pkg == null) {
+ return new QName("", cls.getSimpleName());
+ }
+ StringBuffer ns = new StringBuffer("http://");
+ String[] names = pkg.getName().split("\\.");
+ for (int i = names.length - 1; i >= 0; i--) {
+ ns.append(names[i]);
+ if (i != 0) {
+ ns.append('.');
+ }
+ }
+ ns.append('/');
+ return new QName(ns.toString(), cls.getSimpleName());
+ }
+
+ }
+
+ public BeanXMLStreamReaderImpl(QName name, Object bean) {
+ super(getXmlNode(name, bean));
+ }
+
+ private static BeanXmlNodeImpl getXmlNode(QName name, Object bean) {
+ BeanXmlNodeImpl root = null;
+ if (name != null) {
+ root = new BeanXmlNodeImpl(name, bean);
+ } else {
+ root = new BeanXmlNodeImpl(bean);
+ }
+ return root;
+ }
+
+ public static interface Accessor {
+ String getName();
+
+ Class<?> getType();
+
+ Object getValue() throws Exception;
+
+ void setValue(Object value) throws Exception;
+ }
+
+ private static RuntimeTypeInfoSet create(Class... classes) throws Exception {
+ IllegalAnnotationsException.Builder errorListener = new IllegalAnnotationsException.Builder();
+ RuntimeInlineAnnotationReader reader = new RuntimeInlineAnnotationReader();
+ JAXBContextImpl context =
+ new JAXBContextImpl(classes, null, Collections.<Class, Class> emptyMap(), null, false, reader, false, false);
+ RuntimeModelBuilder builder =
+ new RuntimeModelBuilder(context, reader, Collections.<Class, Class> emptyMap(), null);
+ builder.setErrorHandler(errorListener);
+ for (Class c : classes)
+ builder.getTypeInfo(new Ref<Type, Class>(c));
+
+ RuntimeTypeInfoSet r = builder.link();
+ errorListener.check();
+ return r;
+ }
+
+ private static class JAXBAccessor implements Accessor {
+ private Object target;
+ private RuntimePropertyInfo prop;
+
+ public JAXBAccessor(Object target, RuntimePropertyInfo field) {
+ super();
+ this.target = target;
+ this.prop = field;
+ }
+
+ public String getName() {
+ return prop.getName();
+ }
+
+ public Object getValue() throws Exception {
+ return prop.getAccessor().get(target);
+ }
+
+ public void setValue(Object value) throws Exception {
+ prop.getAccessor().set(target, value);
+ }
+
+ public Class<?> getType() {
+ Type type = prop.getRawType();
+ if (type instanceof Class) {
+ return (Class<?>)type;
+ } else if (type instanceof ParameterizedType) {
+ ParameterizedType pType = (ParameterizedType)type;
+ type = pType.getRawType();
+ if (type instanceof Class) {
+ return (Class<?>)type;
+ }
+ }
+ return Object.class;
+ }
+
+ }
+
+ private static Map<String, Accessor> getAccessors(Object target) throws Exception {
+ if (target == null) {
+ return Collections.emptyMap();
+ }
+ Map<String, Accessor> map = new HashMap<String, Accessor>();
+ Class<?> type = target.getClass();
+ RuntimeTypeInfoSet set = create(type);
+ RuntimeClassInfo clsInfo = (RuntimeClassInfo)set.getTypeInfo(type);
+ for (RuntimePropertyInfo f : clsInfo.getProperties()) {
+ map.put(f.getName(), new JAXBAccessor(target, f));
+ }
+ return map;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2Node.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2Node.java
new file mode 100644
index 0000000000..d1a64a782c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/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.sca.databinding.jaxb;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.databinding.impl.DOMHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public class JAXB2Node extends BaseTransformer<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 DOMHelper.adjustElementName(tContext, document.getDocumentElement());
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 30;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2SAX.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2SAX.java
new file mode 100644
index 0000000000..12f44b479e
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2SAX.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.sca.databinding.jaxb;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+
+import org.apache.tuscany.sca.databinding.PushTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.xml.sax.ContentHandler;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JAXB2SAX extends BaseTransformer<Object, ContentHandler> implements
+ PushTransformer<Object, ContentHandler> {
+
+ @Override
+ protected Class getSourceType() {
+ return Object.class;
+ }
+
+ @Override
+ protected Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.PushTransformer#transform(java.lang.Object, java.lang.Object, org.apache.tuscany.sca.databinding.TransformationContext)
+ */
+ public void transform(Object source, ContentHandler target, TransformationContext tContext) {
+ try {
+ JAXBContext context = JAXBContextHelper.createJAXBContext(tContext, true);
+ Marshaller marshaller = context.createMarshaller();
+ JAXBElement<?> jaxbElement = JAXBContextHelper.createJAXBElement(tContext.getSourceDataType(), source);
+ marshaller.marshal(jaxbElement, target);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public int getWeight() {
+ return 20;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2String.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2String.java
new file mode 100644
index 0000000000..d34ee8b13c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2String.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import java.io.StringWriter;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.databinding.xml.XMLStringDataBinding;
+
+public class JAXB2String extends BaseTransformer<Object, String> implements PullTransformer<Object, String> {
+
+ public String transform(Object source, TransformationContext tContext) {
+ try {
+ JAXBContext context = JAXBContextHelper.createJAXBContext(tContext, true);
+ Marshaller marshaller = context.createMarshaller();
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ JAXBElement<?> jaxbElement = JAXBContextHelper.createJAXBElement(tContext.getSourceDataType(), source);
+ marshaller.marshal(jaxbElement, result);
+ return writer.toString();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return String.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 30;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return XMLStringDataBinding.NAME;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2XMLStreamReader.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2XMLStreamReader.java
new file mode 100644
index 0000000000..8aaee84f80
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXB2XMLStreamReader.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+
+public class JAXB2XMLStreamReader extends BaseTransformer<Object, XMLStreamReader> implements
+ PullTransformer<Object, XMLStreamReader> {
+
+ public JAXB2XMLStreamReader() {
+ super();
+ }
+
+ public XMLStreamReader transform(Object source, TransformationContext context) {
+ if (source == null) {
+ return null;
+ }
+ try {
+ QName name = null;
+ Object bean = source;
+ JAXBElement<?> element = JAXBContextHelper.createJAXBElement(context.getSourceDataType(), source);
+ name = element.getName();
+ bean = element.getValue();
+ BeanXMLStreamReaderImpl reader = new BeanXMLStreamReaderImpl(name, bean);
+ return reader;
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return Object.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
new file mode 100644
index 0000000000..4a240b3f55
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import java.beans.Introspector;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+
+public class JAXBContextHelper {
+ // TODO: Do we need to set them for source and target?
+ public static final String JAXB_CLASSES = "jaxb.classes";
+
+ public static final String JAXB_CONTEXT_PATH = "jaxb.contextPath";
+
+ private JAXBContextHelper() {
+ }
+
+ public static JAXBContext createJAXBContext(TransformationContext tContext, boolean source) throws JAXBException {
+ if (tContext == null)
+ throw new TransformationException("JAXB context is not set for the transformation.");
+
+ DataType<?> dataType = source ? tContext.getSourceDataType() : tContext.getTargetDataType();
+ // FIXME: We should check the context path or classes
+ // FIXME: What should we do if JAXB is an intermediate node?
+
+ // String contextPath = null;
+ JAXBContext context = null;
+ Class<?> cls = getJavaType(dataType);
+
+ context = JAXBContext.newInstance(cls);
+
+ if (context == null) {
+ throw new TransformationException("JAXB context is not set for the transformation.");
+ }
+ return context;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static JAXBElement createJAXBElement(DataType dataType, Object value) {
+ if (value instanceof JAXBElement) {
+ return (JAXBElement)value;
+ } else {
+ Class type = dataType.getPhysical();
+ Object logical = dataType.getLogical();
+ QName elementName = JAXBDataBinding.ROOT_ELEMENT;
+ if (logical instanceof XMLType) {
+ XMLType xmlType = (XMLType)logical;
+ QName element = xmlType.getElementName();
+ if (element != null) {
+ elementName = element;
+ } else {
+ /**
+ * Set the declared type to Object.class so that xsi:type
+ * will be produced
+ */
+ type = Object.class;
+ }
+ } else {
+ type = Object.class;
+ }
+ return new JAXBElement(elementName, type, value);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Object createReturnValue(DataType dataType, Object value) {
+ Class<?> cls = getJavaType(dataType);
+ if (cls == JAXBElement.class) {
+ return createJAXBElement(dataType, value);
+ } else {
+ if (value instanceof JAXBElement) {
+ return ((JAXBElement)value).getValue();
+ } else {
+ return value;
+ }
+ }
+ }
+
+ public static Class<?> getJavaType(DataType<?> dataType) {
+ if (dataType == null) {
+ return null;
+ }
+ Class type = dataType.getPhysical();
+ if (JAXBElement.class.isAssignableFrom(type)) {
+ type = Object.class;
+ }
+ if (type == Object.class && dataType.getLogical() instanceof XMLType) {
+ XMLType xType = (XMLType)dataType.getLogical();
+ Class javaType = SimpleTypeMapperImpl.getJavaType(xType.getTypeName());
+ if (javaType != null) {
+ type = javaType;
+ }
+ }
+ return type;
+ }
+
+ public static XMLType getXmlTypeName(Class<?> javaType) {
+ if (javaType.isInterface()) {
+ // JAXB doesn't support interfaces
+ return null;
+ }
+ String namespace = null;
+ String name = null;
+ Package pkg = javaType.getPackage();
+ if (pkg != null) {
+ XmlSchema schema = pkg.getAnnotation(XmlSchema.class);
+ if (schema != null) {
+ namespace = schema.namespace();
+ }
+ }
+
+ QName elementQName = null;
+ QName typeQName = null;
+ XmlRootElement rootElement = javaType.getAnnotation(XmlRootElement.class);
+ if (rootElement != null) {
+ String elementName = rootElement.name();
+ String elementNamespace = rootElement.namespace();
+ if (elementNamespace.equals("##default")) {
+ elementNamespace = namespace;
+ }
+ if (elementName.equals("##default")) {
+ elementName = Introspector.decapitalize(javaType.getSimpleName());
+ }
+ elementQName = new QName(elementNamespace, elementName);
+ }
+ XmlType type = javaType.getAnnotation(XmlType.class);
+ if (type != null) {
+ String typeNamespace = type.namespace();
+ String typeName = type.name();
+
+ if (typeNamespace.equals("##default")) {
+ // namespace is from the package
+ typeNamespace = namespace;
+ }
+
+ if (typeName.equals("##default")) {
+ typeName = Introspector.decapitalize(javaType.getSimpleName());
+ }
+ typeQName = new QName(typeNamespace, typeName);
+ } else {
+ XmlEnum xmlEnum = javaType.getAnnotation(XmlEnum.class);
+ if (xmlEnum != null) {
+ name = Introspector.decapitalize(javaType.getSimpleName());
+ typeQName = new QName(namespace, name);
+ }
+ }
+ if (elementQName == null && typeQName == null) {
+ return null;
+ }
+ return new XMLType(elementQName, typeQName);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.java
new file mode 100644
index 0000000000..a8b98fc214
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBDataBinding.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.sca.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.sca.databinding.impl.BaseDataBinding;
+import org.apache.tuscany.sca.databinding.impl.DOMHelper;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.w3c.dom.Document;
+
+/**
+ * JAXB DataBinding
+ */
+public class JAXBDataBinding extends BaseDataBinding {
+ 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) {
+ Class javaType = dataType.getPhysical();
+ 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(NAME);
+ return true;
+ }
+ }
+ }
+ if (dataType.getLogical() == null) {
+ dataType.setLogical(XMLType.UNKNOWN);
+ }
+ dataType.setDataBinding(NAME);
+ return true;
+ }
+
+ XMLType xmlType = JAXBContextHelper.getXmlTypeName(javaType);
+ if (xmlType == null) {
+ return false;
+ }
+ dataType.setLogical(xmlType);
+ dataType.setDataBinding(NAME);
+ 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);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBWrapperHandler.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBWrapperHandler.java
new file mode 100644
index 0000000000..c3e97a4818
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBWrapperHandler.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import java.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.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.WrapperHandler;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+
+/**
+ * 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) {
+ //FIXME Understand why we need this, the classloader should be passed in
+ 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.sca.databinding.WrapperHandler#getChildren(java.lang.Object, List, TransformationContext)
+ */
+ public List getChildren(JAXBElement<?> wrapper, List<ElementInfo> childElements, TransformationContext context) {
+ 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;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.WrapperHandler#getWrapperType(org.apache.tuscany.sca.interfacedef.util.ElementInfo, List, org.apache.tuscany.sca.databinding.TransformationContext)
+ */
+ public DataType getWrapperType(ElementInfo element, List<ElementInfo> childElements, 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) {
+ //FIXME Understand why we need this, the classloader should be passed in
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+ Class<?> factoryClass = Class.forName(factoryClassName, true, classLoader);
+ assert factoryClass.isAnnotationPresent(XmlRegistry.class);
+ 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];
+ DataType<XMLType> wrapperType =
+ new DataTypeImpl<XMLType>(JAXBDataBinding.NAME, typeClass, new XMLType(element));
+ return wrapperType;
+ }
+
+ return null;
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.WrapperHandler#isInstance(java.lang.Object, org.apache.tuscany.sca.interfacedef.util.ElementInfo, java.util.List, org.apache.tuscany.sca.databinding.TransformationContext)
+ */
+ public boolean isInstance(Object wrapper,
+ ElementInfo element,
+ List<ElementInfo> childElements,
+ TransformationContext context) {
+ // TODO: Implement the logic
+ return true;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Node2JAXB.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Node2JAXB.java
new file mode 100644
index 0000000000..05e420f1c6
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/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.sca.databinding.jaxb;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.w3c.dom.Node;
+
+public class Node2JAXB extends BaseTransformer<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, JAXBContextHelper.getJavaType(context.getTargetDataType()));
+ return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return Object.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 30;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Reader2JAXB.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/Reader2JAXB.java
new file mode 100644
index 0000000000..61b3075539
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/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.sca.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.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+
+public class Reader2JAXB extends BaseTransformer<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, JAXBContextHelper.getJavaType(context.getTargetDataType()));
+ return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return Reader.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return Object.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 30;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/String2JAXB.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/String2JAXB.java
new file mode 100644
index 0000000000..79e8dc027f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/String2JAXB.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import java.io.StringReader;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.databinding.xml.XMLStringDataBinding;
+
+public class String2JAXB extends BaseTransformer<String, Object> implements
+ PullTransformer<String, Object> {
+
+ public Object transform(final String source, final TransformationContext context) {
+ if (source == null) {
+ return null;
+ }
+ try {
+ JAXBContext jaxbContext = JAXBContextHelper.createJAXBContext(context, false);
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ StreamSource streamSource = new StreamSource(new StringReader(source));
+ Object result = unmarshaller.unmarshal(streamSource, JAXBContextHelper.getJavaType(context.getTargetDataType()));
+ return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return Object.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 30;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return XMLStringDataBinding.NAME;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/XMLStreamReader2JAXB.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/XMLStreamReader2JAXB.java
new file mode 100644
index 0000000000..ef3112eb22
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/XMLStreamReader2JAXB.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.databinding.jaxb;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+
+public class XMLStreamReader2JAXB extends BaseTransformer<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();
+ // FIXME: [rfeng] If the java type is Object.class, the unmarshalled result will be
+ // a DOM Node
+ Object result = unmarshaller.unmarshal(source, JAXBContextHelper.getJavaType(context.getTargetDataType()));
+ source.close();
+ return JAXBContextHelper.createReturnValue(context.getTargetDataType(), result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ @Override
+ public Class getTargetType() {
+ return Object.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return JAXBDataBinding.NAME;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding
new file mode 100644
index 0000000000..58d6123373
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.DataBinding
@@ -0,0 +1,19 @@
+# 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.
+
+# implementation classes for the databindings
+org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding;type=javax.xml.bind.JAXBElement,name=jaxb
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer
new file mode 100644
index 0000000000..4e062e4c22
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/main/resources/META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer
@@ -0,0 +1,32 @@
+# 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.
+
+# Implementation classes for the transformers
+org.apache.tuscany.sca.databinding.jaxb.JAXB2Node;source=javax.xml.bind.JAXBElement,target=org.w3c.dom.Node,weight=500
+org.apache.tuscany.sca.databinding.jaxb.Node2JAXB;source=org.w3c.dom.Node,target=javax.xml.bind.JAXBElement,weight=500
+org.apache.tuscany.sca.databinding.jaxb.Reader2JAXB;source=java.io.Reader,target=javax.xml.bind.JAXBElement,weight=510
+org.apache.tuscany.sca.databinding.jaxb.XMLStreamReader2JAXB;source=javax.xml.stream.XMLStreamReader,target=javax.xml.bind.JAXBElement,weight=490
+
+org.apache.tuscany.sca.databinding.jaxb.JAXB2Node;source=java:complexType,target=org.w3c.dom.Node,weight=90000
+org.apache.tuscany.sca.databinding.jaxb.Node2JAXB;source=org.w3c.dom.Node,target=java:complexType,weight=90000
+
+org.apache.tuscany.sca.databinding.jaxb.Node2JAXB;source=org.w3c.dom.Node,target=java:simpleType,weight=90000
+org.apache.tuscany.sca.databinding.jaxb.JAXB2Node;source=java:simpleType,target=org.w3c.dom.Node,weight=90000
+
+org.apache.tuscany.sca.databinding.jaxb.XMLStreamReader2JAXB;source=javax.xml.stream.XMLStreamReader,target=java:complexType,weight=90000
+org.apache.tuscany.sca.databinding.jaxb.XMLStreamReader2JAXB;source=javax.xml.stream.XMLStreamReader,target=java:simpleType,weight=90000
+
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java
new file mode 100644
index 0000000000..b121e2c99f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBDataBindingTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * 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.TestCase;
+
+import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+
+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()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ binding = new JAXBDataBinding();
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding#introspect(java.lang.Class, Annotation)}.
+ */
+ public final void testIntrospect() {
+ DataType dataType = new DataTypeImpl<Class>(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 DataTypeImpl<Class>(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 DataTypeImpl<Class>(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 DataTypeImpl<Class>(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", (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", (copy).getCity());
+
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBReflectionTestCase.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBReflectionTestCase.java
new file mode 100644
index 0000000000..2efbfe3962
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBReflectionTestCase.java
@@ -0,0 +1,108 @@
+/*
+ * 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.IOException;
+import java.lang.reflect.Type;
+import java.util.Collections;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Result;
+import javax.xml.transform.dom.DOMResult;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.databinding.xml.Node2String;
+import org.jvnet.jaxb.reflection.model.annotation.RuntimeInlineAnnotationReader;
+import org.jvnet.jaxb.reflection.model.core.Ref;
+import org.jvnet.jaxb.reflection.model.impl.RuntimeModelBuilder;
+import org.jvnet.jaxb.reflection.model.runtime.RuntimeClassInfo;
+import org.jvnet.jaxb.reflection.model.runtime.RuntimeTypeInfoSet;
+import org.jvnet.jaxb.reflection.runtime.IllegalAnnotationsException;
+import org.jvnet.jaxb.reflection.runtime.JAXBContextImpl;
+import org.w3c.dom.Node;
+
+import com.example.ipo.jaxb.PurchaseOrderType;
+import com.example.ipo.jaxb.USAddress;
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JAXBReflectionTestCase extends TestCase {
+
+ public void testGenerateSchema() throws Exception {
+ JAXBContext context = JAXBContext.newInstance("com.example.ipo.jaxb");
+ SchemaOutputResolverImpl resolver = new SchemaOutputResolverImpl();
+ context.generateSchema(resolver);
+ System.out.println(new Node2String().transform(resolver.getSchema(), null));
+ }
+
+ public static class SchemaOutputResolverImpl extends SchemaOutputResolver {
+ private DOMResult result = new DOMResult();
+
+ @Override
+ public Result createOutput(String ns, String file) throws IOException {
+ System.out.println(ns);
+ System.out.println(file);
+ result.setSystemId("sca:dom");
+ return result;
+ }
+
+ public Node getSchema() {
+ return result != null ? result.getNode() : null;
+ }
+
+ }
+
+ /**
+ * This is a workaround for the NPE bug in jaxb-reflection
+ * @param classes
+ * @return
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ private static RuntimeTypeInfoSet create(Class... classes) throws Exception {
+ IllegalAnnotationsException.Builder errorListener = new IllegalAnnotationsException.Builder();
+ RuntimeInlineAnnotationReader reader = new RuntimeInlineAnnotationReader();
+ JAXBContextImpl context =
+ new JAXBContextImpl(classes, null, Collections.<Class, Class> emptyMap(), null, false, reader, false, false);
+ RuntimeModelBuilder builder =
+ new RuntimeModelBuilder(context, reader, Collections.<Class, Class> emptyMap(), null);
+ builder.setErrorHandler(errorListener);
+ for (Class c : classes)
+ builder.getTypeInfo(new Ref<Type, Class>(c));
+
+ RuntimeTypeInfoSet r = builder.link();
+ errorListener.check();
+ return r;
+ }
+
+ public void testReflection() throws Exception {
+ org.jvnet.jaxb.reflection.model.runtime.RuntimeTypeInfoSet model = create(PurchaseOrderType.class);
+ RuntimeClassInfo type = (RuntimeClassInfo) model.getTypeInfo(PurchaseOrderType.class);
+ Assert.assertEquals(new QName("http://www.example.com/IPO", "PurchaseOrderType"), type.getTypeName());
+ type = (RuntimeClassInfo) model.getTypeInfo(USAddress.class);
+ Assert.assertEquals(new QName("http://www.example.com/IPO", "USAddress"), type.getTypeName());
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java
new file mode 100644
index 0000000000..512e1c625f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBTestCase.java
@@ -0,0 +1,163 @@
+/*
+ * 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.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.jaxb.JAXB2Node;
+import org.apache.tuscany.sca.databinding.jaxb.Node2JAXB;
+import org.apache.tuscany.sca.databinding.jaxb.Reader2JAXB;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+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>";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public void testTransform() throws Exception {
+ Reader2JAXB t0 = new Reader2JAXB();
+
+ DataType targetDataType = new DataTypeImpl<Class>(PurchaseOrderType.class, null);
+
+ 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 DataTypeImpl<Class>(PurchaseOrderType.class, null);
+
+ TransformationContext tContext1 = createMock(TransformationContext.class);
+ expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes();
+ expect(tContext1.getTargetDataType()).andReturn(null).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 DataTypeImpl<XMLType>(PurchaseOrderType.class, new XMLType(root, 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 DataTypeImpl<XMLType>(PurchaseOrderType.class, new XMLType(root, null));
+ // sourceDataType.setMetadata(JAXBContextHelper.JAXB_CONTEXT_PATH, contextPath);
+
+ TransformationContext tContext1 = createMock(TransformationContext.class);
+ expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes();
+ expect(tContext1.getTargetDataType()).andReturn(null).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 DataTypeImpl<Class>(PurchaseOrderType.class, null);
+
+ TransformationContext tContext1 = createMock(TransformationContext.class);
+ expect(tContext1.getSourceDataType()).andReturn(sourceDataType).anyTimes();
+ expect(tContext1.getTargetDataType()).andReturn(null).anyTimes();
+ replay(tContext1);
+
+ JAXB2Node t1 = new JAXB2Node();
+ PurchaseOrderType po = new ObjectFactory().createPurchaseOrderType();
+ Node node = t1.transform(po, tContext1);
+
+ Assert.assertNotNull(node);
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/JAXBWrapperHandlerTestCase.java
new file mode 100644
index 0000000000..563d6232b1
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/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 junit.framework.TestCase;
+
+import org.apache.tuscany.sca.databinding.jaxb.JAXBWrapperHandler;
+
+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()
+ */
+ @Override
+ 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, null, null);
+ assertNotNull(children);
+ assertEquals(4, children.size());
+ assertEquals("Comment", children.get(2));
+ assertNull(children.get(0));
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyBean.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyBean.java
new file mode 100644
index 0000000000..49fb38b1fa
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyBean.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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MyBean {
+ private int age;
+ private String name;
+ private float[] rates = new float[] {1.0f, 2.0f};
+ private List<String> notes = new ArrayList<String>();
+ private Map<String, Integer> map = new HashMap<String, Integer>();
+ private Object service;
+ private Object otherService;
+ private boolean good;
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<String> getNotes() {
+ return notes;
+ }
+
+ public void setNotes(List<String> notes) {
+ this.notes = notes;
+ }
+
+ public float[] getRates() {
+ return rates;
+ }
+
+ public void setRates(float[] rates) {
+ this.rates = rates;
+ }
+
+ public Map<String, Integer> getMap() {
+ return map;
+ }
+
+ public void setMap(Map<String, Integer> map) {
+ this.map = map;
+ }
+
+ public Object getService() {
+ return service;
+ }
+
+ public void setService(Object service) {
+ this.service = service;
+ }
+
+ public Object getOtherService() {
+ return otherService;
+ }
+
+ public void setOtherService(Object otherService) {
+ this.otherService = otherService;
+ }
+
+ public boolean isGood() {
+ return good;
+ }
+
+ public void setGood(boolean good) {
+ this.good = good;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + age;
+ result = prime * result + (good ? 1231 : 1237);
+ result = prime * result + ((map == null) ? 0 : map.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((notes == null) ? 0 : notes.hashCode());
+ result = prime * result + ((otherService == null) ? 0 : otherService.hashCode());
+ result = prime * result + Arrays.hashCode(rates);
+ result = prime * result + ((service == null) ? 0 : service.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final MyBean other = (MyBean)obj;
+ if (age != other.age)
+ return false;
+ if (good != other.good)
+ return false;
+ if (map == null) {
+ if (other.map != null)
+ return false;
+ } else if (!map.equals(other.map))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (notes == null) {
+ if (other.notes != null)
+ return false;
+ } else if (!notes.equals(other.notes))
+ return false;
+ if (otherService == null) {
+ if (other.otherService != null)
+ return false;
+ } else if (!otherService.equals(other.otherService))
+ return false;
+ if (!Arrays.equals(rates, other.rates))
+ return false;
+ if (service == null) {
+ if (other.service != null)
+ return false;
+ } else if (!service.equals(other.service))
+ return false;
+ return true;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterface.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterface.java
new file mode 100644
index 0000000000..2fc561b577
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterface.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface MyInterface {
+ public void setId(String id);
+
+ public String getId();
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterfaceImpl.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterfaceImpl.java
new file mode 100644
index 0000000000..928acb9f3c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/MyInterfaceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MyInterfaceImpl implements MyInterface {
+ private String id;
+
+ /**
+ * @see org.apache.tuscany.databinding.jaxb.MyInterface#getId()
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @see org.apache.tuscany.databinding.jaxb.MyInterface#setId(java.lang.String)
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final MyInterfaceImpl other = (MyInterfaceImpl)obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/POJOTestCase.java b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/POJOTestCase.java
new file mode 100644
index 0000000000..9758292aea
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/java/org/apache/tuscany/databinding/jaxb/POJOTestCase.java
@@ -0,0 +1,219 @@
+/*
+ * 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.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stream.StreamSource;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.impl.TransformationContextImpl;
+import org.apache.tuscany.sca.databinding.jaxb.JAXB2XMLStreamReader;
+
+import com.sun.xml.bind.v2.model.annotation.RuntimeInlineAnnotationReader;
+import com.sun.xml.bind.v2.model.core.Ref;
+import com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder;
+import com.sun.xml.bind.v2.model.runtime.RuntimeClassInfo;
+import com.sun.xml.bind.v2.model.runtime.RuntimePropertyInfo;
+import com.sun.xml.bind.v2.model.runtime.RuntimeTypeInfoSet;
+import com.sun.xml.bind.v2.runtime.IllegalAnnotationsException;
+import com.sun.xml.bind.v2.runtime.JAXBContextImpl;
+
+public class POJOTestCase extends TestCase {
+ public void testPOJO() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(MyBean.class, MyInterfaceImpl.class);
+ StringWriter writer = new StringWriter();
+ MyBean bean = new MyBean();
+ bean.setName("Test");
+ bean.setAge(20);
+ bean.getNotes().add("1");
+ bean.getNotes().add("2");
+ bean.getMap().put("1", 1);
+ MyInterface service = new MyInterfaceImpl();
+ service.setId("ID001");
+ bean.setService(service);
+ bean.setOtherService(service);
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, bean);
+ context.createMarshaller().marshal(element, writer);
+ // System.out.println(writer.toString());
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(writer.toString()));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertTrue(e2.getValue() instanceof MyBean);
+ MyBean newBean = (MyBean)e2.getValue();
+ assertEquals(bean, newBean);
+ }
+
+ public void testXMLStreamReader() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(MyBean.class, MyInterfaceImpl.class);
+
+ MyBean bean = new MyBean();
+ bean.setName("Test");
+ bean.setAge(20);
+ bean.getNotes().add("1");
+ bean.getNotes().add("2");
+ bean.getMap().put("1", 1);
+ MyInterface service = new MyInterfaceImpl();
+ service.setId("ID001");
+ bean.setService(service);
+ bean.setOtherService(service);
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, bean);
+ TransformationContext tContext = new TransformationContextImpl();
+ XMLStreamReader reader = new JAXB2XMLStreamReader().transform(element, tContext);
+
+// XMLStreamReader2String t2 = new XMLStreamReader2String();
+// String xml = t2.transform(reader, null);
+ // System.out.println(xml);
+ Object result = context.createUnmarshaller().unmarshal(reader, MyBean.class);
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertTrue(e2.getValue() instanceof MyBean);
+ MyBean newBean = (MyBean)e2.getValue();
+ // FIXME :To be implemented
+ // assertEquals(bean, newBean);
+ }
+
+ public void testString() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(String.class);
+ StringWriter writer = new StringWriter();
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, "ABC");
+ context.createMarshaller().marshal(element, writer);
+ // System.out.println(writer.toString());
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(writer.toString()));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertEquals("ABC", e2.getValue());
+ }
+
+ public void testNull() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(String.class);
+ StringWriter writer = new StringWriter();
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, null);
+ element.setNil(true);
+ context.createMarshaller().marshal(element, writer);
+ // System.out.println(writer.toString());
+ StreamSource source = new StreamSource(new StringReader(writer.toString()));
+ Object result = context.createUnmarshaller().unmarshal(source, String.class);
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertNull(e2.getValue());
+ }
+
+ public void testArray() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(String[].class);
+ StringWriter writer = new StringWriter();
+ JAXBElement<Object> element =
+ new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, new String[] {"ABC", "123"});
+ context.createMarshaller().marshal(element, writer);
+ // System.out.println(writer.toString());
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(writer.toString()));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertTrue(e2.getValue() instanceof String[]);
+ }
+
+ public void testByteArray() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(byte[].class);
+ StringWriter writer = new StringWriter();
+ JAXBElement<Object> element =
+ new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, "ABC".getBytes());
+ context.createMarshaller().marshal(element, writer);
+ String xml = writer.toString();
+ assertTrue(xml.contains("QUJD"));
+ assertTrue(xml.contains("base64Binary"));
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(xml));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertTrue(e2.getValue() instanceof byte[]);
+ }
+
+ public void testPrimitive() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(int.class);
+ StringWriter writer = new StringWriter();
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, 1);
+ context.createMarshaller().marshal(element, writer);
+ // System.out.println(writer.toString());
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(writer.toString()));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertEquals(1, e2.getValue());
+ }
+
+ /*
+ public void testException() throws Exception {
+ JAXBContext context = JAXBContext.newInstance(IllegalArgumentException.class);
+ StringWriter writer = new StringWriter();
+ Exception e = new IllegalArgumentException("123");
+ JAXBElement<Object> element = new JAXBElement<Object>(new QName("http://ns1", "bean"), Object.class, e);
+ context.createMarshaller().marshal(element, writer);
+ System.out.println(writer.toString());
+
+ Object result = context.createUnmarshaller().unmarshal(new StringReader(writer.toString()));
+ assertTrue(result instanceof JAXBElement);
+ JAXBElement e2 = (JAXBElement)result;
+ assertTrue(e2.getValue() instanceof Exception);
+ }
+ */
+
+ private static RuntimeTypeInfoSet create(Class... classes) throws Exception {
+ IllegalAnnotationsException.Builder errorListener = new IllegalAnnotationsException.Builder();
+ RuntimeInlineAnnotationReader reader = new RuntimeInlineAnnotationReader();
+ JAXBContextImpl context =
+ new JAXBContextImpl(classes, null, Collections.<Class, Class> emptyMap(), null, false, reader, false, false);
+ RuntimeModelBuilder builder =
+ new RuntimeModelBuilder(context, reader, Collections.<Class, Class> emptyMap(), null);
+ builder.setErrorHandler(errorListener);
+ for (Class c : classes)
+ builder.getTypeInfo(new Ref<Type, Class>(c));
+
+ RuntimeTypeInfoSet r = builder.link();
+ errorListener.check();
+ return r;
+ }
+
+ public void testReflection() throws Exception {
+ MyBean bean = new MyBean();
+ RuntimeTypeInfoSet model = create(MyBean.class);
+ RuntimeClassInfo clsInfo = (RuntimeClassInfo)model.getTypeInfo(MyBean.class);
+ for (RuntimePropertyInfo p : clsInfo.getProperties()) {
+ // System.out.print(p.getName());
+ // System.out.println(" " + p.isCollection());
+ if (p.getName().equals("notes")) {
+ Collection c = (Collection)p.getAccessor().get(bean);
+ c.add("123");
+ }
+ }
+
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/resources/ipo.xsd b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/resources/ipo.xsd
new file mode 100644
index 0000000000..241ec15d36
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.2.1/modules/databinding-jaxb/src/test/resources/ipo.xsd
@@ -0,0 +1,136 @@
+<!--
+ * 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.
+-->
+<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>
+