You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-commits@ws.apache.org by da...@apache.org on 2006/06/12 18:04:01 UTC
svn commit: r413690 - in /webservices/muse/trunk/modules/muse-util-xstream:
pom.xml src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java
Author: danj
Date: Mon Jun 12 09:04:00 2006
New Revision: 413690
URL: http://svn.apache.org/viewvc?rev=413690&view=rev
Log:
Initial check-in of IBM-donated code for Muse 2.0 - with
support for Axis2 (re-try after failure due to problem
with email to muse-commits).
Currently, the modules that are not implementations of the
WS-* specs - core, utils, WS-A/SOAP, etc. - have working
Maven 2.0 build files. Right now they simply compile and
write to the user's local $module/build directory. I have
not determined how to get Maven to skip this intermediary
copy and just put the jars in the user's local repository.
I currently use a script to build each module's POM file,
but as I learn more about Maven I will hopefully find a way
to aggregate POM files into one larger project. If not, I
will provide a simple Ant script.
I'm not sure where the design doc should go, and don't
want to mess with the web site yet, so please look at the
design-doc.zip that was uploaded to JIRA along with the
other IBM contributions until I determine the proper place.
Added:
webservices/muse/trunk/modules/muse-util-xstream/pom.xml
webservices/muse/trunk/modules/muse-util-xstream/src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java
Added: webservices/muse/trunk/modules/muse-util-xstream/pom.xml
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-util-xstream/pom.xml?rev=413690&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-util-xstream/pom.xml (added)
+++ webservices/muse/trunk/modules/muse-util-xstream/pom.xml Mon Jun 12 09:04:00 2006
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>muse</groupId>
+ <artifactId>muse-util-xstream</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0-SNAPSHOT</version>
+ <name>Apache Muse - XStream Serialization</name>
+ <url>http://ws.apache.org/muse</url>
+ <dependencies>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util-qname</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.1.2</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <outputDirectory>build/classes</outputDirectory>
+ <directory>build/jars</directory>
+ </build>
+</project>
Added: webservices/muse/trunk/modules/muse-util-xstream/src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-util-xstream/src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java?rev=413690&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-util-xstream/src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java (added)
+++ webservices/muse/trunk/modules/muse-util-xstream/src/org/apache/muse/core/serializer/xstream/XStreamSerializer.java Mon Jun 12 09:04:00 2006
@@ -0,0 +1,299 @@
+/*=============================================================================*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.muse.core.serializer.xstream;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.ReflectUtils;
+import org.apache.muse.util.xml.XmlUtils;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.alias.ClassMapper;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+import com.thoughtworks.xstream.io.xml.DomReader;
+import com.thoughtworks.xstream.io.xml.DomWriter;
+import com.thoughtworks.xstream.mapper.MapperWrapper;
+
+/**
+ *
+ * XStreamSerializer is a generic Serializer that relies on the XStream
+ * library to serialize and deserialize objects to/from XML without any
+ * configuration files or schemas. To use this class within Muse
+ * applications, simply sub-class it an override the getSerializableType()
+ * method to return the class or interface that is being serialized. That's it!
+ * <br><br>
+ * This serializer has some additional code that helps XStream create "pure"
+ * XML by adding better support for XML namespaces and prefixes, as well as
+ * being more flexible in the Java field name conventions that can be read
+ * and converted into proper XML element names.
+ * <br><br>
+ * For more information about how XStream serializes your objects, and to get
+ * the JAR file needed to execute this code, please visit XStream's web site:
+ * <br><br>
+ * <a href="http://xstream.codehaus.org">http://xstream.codehaus.org</a>
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ * @see org.apache.muse.core.serializer.Serializer
+ *
+ */
+
+public abstract class XStreamSerializer implements Serializer
+{
+ //
+ // The XStream facade that aggregates all of the core XStream features.
+ // Note we initialize XStream with the DOM driver so that sub-classes
+ // that use the XStream.toXML and XStream.fromXML convenience methods
+ // will not have to configure this themselves (the default driver is
+ // XML Pull Parser, which we do not wish to include for legal reasons).
+ //
+ // This version of the XStream facade is an extension that calls
+ // on this Serializer class to get the name/type that is being
+ // serialized. This, in combination with some prefix/namespace support
+ // code, allows us to generate "pure" XML that has no Java connotations.
+ //
+ private XStream _xstream = new MuseSerializerXStream();
+
+ /**
+ *
+ * This method takes the non-namespace-aware DOM (DOM Level 1) that
+ * is generated by XStream and converts it into an equivalent DOM
+ * tree with the proper namespaces and prefixes. The namespace and
+ * prefix values should be taken from the QName that is provided to
+ * the Serializer.toXML() method.
+ *
+ */
+ protected Element copySubTree(Element[] children,
+ Element root,
+ String namespace,
+ String prefix)
+ {
+ Document doc = root.getOwnerDocument();
+
+ for (int n = 0; n < children.length; ++n)
+ {
+ //
+ // create a QName using the user's URI/prefix and the
+ // local name created by XStream
+ //
+ QName qname = new QName(namespace, children[n].getLocalName(), prefix);
+
+ //
+ // now copy over the text and sub-child elements
+ //
+
+ Element childCopy = XmlUtils.createElement(doc, qname);
+ root.appendChild(childCopy);
+
+ String text = XmlUtils.extractText(children[n]);
+
+ if (text != null)
+ XmlUtils.setElementText(childCopy, text);
+
+ Element[] subChildren = XmlUtils.getAllElements(children[n]);
+ copySubTree(subChildren, childCopy, namespace, prefix);
+ }
+
+ return root;
+ }
+
+ /**
+ *
+ * @return A POJO representation of the given XML fragment.
+ *
+ */
+ public Object fromXML(Element xml)
+ {
+ return getXStream().unmarshal(new DomReader(xml));
+ }
+
+ /**
+ *
+ * @return The XStream API, initialized with the DOM parser/driver.
+ *
+ */
+ public final XStream getXStream()
+ {
+ return _xstream;
+ }
+
+ /**
+ *
+ * @return The XML representation of the object, with the root element
+ * having the given QName.
+ *
+ */
+ public Element toXML(Object result, QName qname)
+ {
+ Document doc = XmlUtils.createDocument();
+
+ //
+ // use marshal rather than toXML so we can serialize the object
+ // directly to DOM (toXML returns a string of XML)
+ //
+ getXStream().marshal(result, new DomWriter(doc));
+
+ //
+ // XStream creates DOM Level 1 - argh! we need qualified names
+ // to be schema-compliant, so we have to copy the whole DOM tree
+ // in a Level 2 way. DOM (both levels) does not permit the
+ // changing of the name(space) of nodes after their creation.
+ //
+ Element root = XmlUtils.getFirstElement(doc);
+ Element[] children = XmlUtils.getAllElements(root);
+
+ String namespace = qname.getNamespaceURI();
+ String prefix = qname.getPrefix();
+ Element qualifiedRoot = XmlUtils.createElement(doc, qname);
+
+ return copySubTree(children, qualifiedRoot, namespace, prefix);
+ }
+
+ /**
+ *
+ * MuseSerializerXStream is a version of XStream that uses our
+ * JavaFieldConverter class to map Java field names to XML elements.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+ private class MuseSerializerXStream extends XStream
+ {
+ public MuseSerializerXStream()
+ {
+ super(new DomDriver());
+ }
+
+ protected MapperWrapper wrapMapper(MapperWrapper next)
+ {
+ return new JavaFieldConverter(next);
+ }
+ }
+
+ /**
+ *
+ * JavaFieldConverter is a pluggable XStream component that allows us
+ * more control over the naming conventions XStream uses/accepts when
+ * serializing and deserializing XML. We use this component to achieve
+ * two goals:
+ * <ol>
+ * <li>Tolerate namespaces and prefixes in XML elements when XStream
+ * is deserializing XML into POJOs. Normally, it would balk at the
+ * prefixed-name of the element because it doesn't match the field
+ * name or any of its aliases.
+ * </li>
+ * <br>
+ * <li>Tolerate Java field naming conventions - camel casing (first
+ * letter lowercase) and underscore prefixes. We drop underscore prefixes
+ * from the name and convert the first letter to uppercase before using
+ * the name to create an XML element. This makes it impossible to tell
+ * that the XML came from a Java class.
+ * </li>
+ * <br>
+ * </ol>
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+ private class JavaFieldConverter extends MapperWrapper
+ {
+ public JavaFieldConverter(ClassMapper wrapper)
+ {
+ super(wrapper);
+ }
+
+ /**
+ *
+ * This method returns Serializer.getSerializableType(). Because
+ * each XStreamSerializer-based serializer will have its own
+ * instance of XStream, we can assume it is serializing this type.
+ *
+ */
+ public Class realClass(String className)
+ {
+ return getSerializableType();
+ }
+
+ /**
+ *
+ * This method converts the XML element name to the Java field name.
+ *
+ */
+ public String realMember(Class theClass, String elementName)
+ {
+ //
+ // strip prefix from DOM element name
+ //
+ int colonIndex = elementName.indexOf(':');
+
+ if (colonIndex >= 0)
+ elementName = elementName.substring(colonIndex + 1);
+
+ //
+ // make two options - just camel case, or camel case with an
+ // underscore prefix. try 'em both
+ //
+ String withLowerCase = Character.toLowerCase(elementName.charAt(0)) + elementName.substring(1);
+ String withPrefix = '_' + withLowerCase;
+
+ try
+ {
+ theClass.getDeclaredField(withPrefix);
+ return withPrefix; // has the underscore - return it!
+ }
+
+ catch (NoSuchFieldException error)
+ {
+ //
+ // no underscore - return regular name
+ //
+ return withLowerCase;
+ }
+ }
+
+ /**
+ *
+ * This method returns the unqualified (no package) name of the
+ * Java class (com.ibm.example.MyClass becomes "MyClass").
+ *
+ */
+ public String serializedClass(Class theClass)
+ {
+ return ReflectUtils.getShortName(theClass);
+ }
+
+ /**
+ *
+ * This method strips an camel casing or underscore prefix from
+ * the given field name so it can be used as an XML element name.
+ *
+ */
+ public String serializedMember(Class theClass, String fieldName)
+ {
+ if (fieldName.charAt(0) == '_')
+ fieldName = fieldName.substring(1);
+
+ fieldName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
+
+ return super.serializedMember(theClass, fieldName);
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: muse-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-commits-help@ws.apache.org