Author: sergeyb
Date: Wed Jun 11 09:07:55 2008
New Revision: 666722
URL: http://svn.apache.org/viewvc?rev=666722&view=rev
Log:
CXF-1634 : applying a patch on behalf of Brad Moody(thanks) with minor update :
no XmlBean providers added to the default list.
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
(with props)
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
(with props)
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
(with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/pom.xml
Modified: cxf/trunk/rt/frontend/jaxrs/pom.xml
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/pom.xml?rev=666722&r1=666721&r2=666722&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/pom.xml (original)
+++ cxf/trunk/rt/frontend/jaxrs/pom.xml Wed Jun 11 09:07:55 2008
@@ -120,6 +120,11 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.xmlbeans</groupId>
+ <artifactId>xmlbeans</artifactId>
+ <version>2.3.0</version>
+ </dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java?rev=666722&view=auto
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
(added)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
Wed Jun 11 09:07:55 2008
@@ -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.cxf.jaxrs.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.xmlbeans.XmlObject;
+
+/**
+ * Serializes an XMLBean data object to an XML stream Note: uses an
intermediate file created by
+ * File.createTempFile(String, String) as I couldn't work out how to fit a
normal stream into an event driven
+ * XML stream.
+ */
+public class XMLBeanStreamSerializer {
+
+ /**
+ * Serialize the given XML data object. Writes the data object to a
temporary file then reads it back in
+ * with an <code>XMLStreamReader<code>.
+ * This allows the events from the reader to drive the output to the
<code>XMLStreamWriter</code>.
+ * Probably not the best way to do this.
+ *
+ * @param obj
+ * @param writer
+ */
+ public void serialize(XmlObject xObj, XMLStreamWriter writer) throws
IOException, XMLStreamException {
+
+ File tmpFile = null;
+
+ try {
+
+ // create tmp file
+ tmpFile = File.createTempFile(Integer.toString(xObj.hashCode()),
".xml");
+ // TODO may need to set some XMLOptions here
+ // write to tmp file
+ xObj.save(tmpFile);
+
+ InputStream tmpIn = new FileInputStream(tmpFile);
+ XMLStreamReader rdr =
XMLInputFactory.newInstance().createXMLStreamReader(tmpIn);
+
+ while (rdr.hasNext()) {
+
+ int event = rdr.next();
+
+ switch (event) {
+
+ case XMLStreamConstants.START_DOCUMENT:
+ writer.writeStartDocument();
+ break;
+
+ case XMLStreamConstants.END_DOCUMENT:
+ writer.writeEndDocument();
+ break;
+
+ case XMLStreamConstants.START_ELEMENT:
+ String name = rdr.getLocalName();
+ writer.writeStartElement(name);
+
+ // handle attributes
+ int attrCount = rdr.getAttributeCount();
+ for (int i = 0; i < attrCount; i++) {
+ String attrName = rdr.getAttributeLocalName(i);
+ String attrNS = rdr.getAttributeNamespace(i);
+ String attrVal = rdr.getAttributeValue(i);
+ if (attrNS == null) {
+
+ writer.writeAttribute(attrName, attrVal);
+
+ } else {
+
+ writer.writeAttribute(attrNS, attrName, attrVal);
+ }
+
+ }
+ break;
+
+ case XMLStreamConstants.END_ELEMENT:
+ writer.writeEndElement();
+ break;
+
+ case XMLStreamConstants.ATTRIBUTE:
+ // do nothing
+ break;
+
+ case XMLStreamConstants.CHARACTERS:
+ String txt = rdr.getText();
+ writer.writeCharacters(txt);
+ break;
+
+ default:
+ // ignore
+ break;
+ }
+ }
+
+ } finally {
+
+ if (tmpFile != null && tmpFile.exists() && tmpFile.canWrite()) {
+
+ tmpFile.delete();
+ }
+ }
+ }
+}
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java?rev=666722&view=auto
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
(added)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
Wed Jun 11 09:07:55 2008
@@ -0,0 +1,234 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+
+import javax.ws.rs.ConsumeMime;
+import javax.ws.rs.ProduceMime;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.xmlbeans.XmlObject;
+
+/**
+ * Provider for XMLBeans data objects.
+ */
[EMAIL PROTECTED]("application/xml")
[EMAIL PROTECTED]("application/xml")
[EMAIL PROTECTED]
+public class XMLBeansElementProvider implements MessageBodyReader<XmlObject>,
MessageBodyWriter<XmlObject> {
+
+ /** [EMAIL PROTECTED] */
+ public XmlObject readFrom(Class type, MediaType mediaType, MultivaluedMap
httpHeaders,
+ InputStream entityStream) throws IOException {
+
+ XmlObject result = parseXmlBean(type, entityStream);
+
+ return result;
+ }
+
+ /** [EMAIL PROTECTED] */
+ public void writeTo(XmlObject t, MediaType mediaType, MultivaluedMap
httpHeaders,
+ OutputStream entityStream)
+ throws IOException {
+
+ // May need to set some XMLOptions here
+ t.save(entityStream);
+ }
+
+ /** [EMAIL PROTECTED] */
+ public long getSize(XmlObject t) {
+ // return length not known
+ return -1;
+ }
+
+ /** [EMAIL PROTECTED] */
+ public boolean isReadable(Class type) {
+ return isXmlBean(type);
+ }
+
+ /** [EMAIL PROTECTED] */
+ public boolean isWriteable(Class type) {
+ return isXmlBean(type);
+ }
+
+ /**
+ * Create an XMLBean object from an XML stream.
+ *
+ * @param type declared type of the target object
+ * @param reader stream reader for the XML stream
+ * @return an XMLBean data object, or none if unable to process
+ */
+ protected XmlObject parseXmlBean(Class type, XMLStreamReader reader) {
+
+ XmlObject result = null;
+
+ // get XMLBeans inner class Factory
+ Class factory = getFactory(type);
+
+ try {
+
+ // find and invoke method parse(InputStream)
+ Method m = factory.getMethod("parse", reader.getClass());
+ Object[] args = {
+ reader
+ };
+ Object obj = m.invoke(type, args);
+
+ if (obj instanceof XmlObject) {
+ result = (XmlObject)obj;
+ }
+
+ } catch (NoSuchMethodException nsme) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ } catch (InvocationTargetException ite) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ } catch (IllegalAccessException iae) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ }
+
+ return result;
+ }
+
+ /**
+ * Create an XMLBean data object from an <code>InputStream</code>
+ *
+ * @param type declared type of the required object
+ * @param inStream
+ * @return an XMLBean object if successful, otherwise null
+ */
+ protected XmlObject parseXmlBean(Class type, InputStream inStream) {
+ XmlObject result = null;
+
+ Reader r = new InputStreamReader(inStream);
+
+ // delegate to parseXmlBean(Class type, Reader reader)
+ result = parseXmlBean(type, r);
+
+ return result;
+ }
+
+ /**
+ * Create an XMLBean data object using a stream <code>Reader</code>
+ *
+ * @param type declared type of the desired XMLBean data object
+ * @param reader
+ * @return an instance of the required object, otherwise null
+ */
+ protected XmlObject parseXmlBean(Class type, Reader reader) {
+ XmlObject result = null;
+
+ Class factory = getFactory(type);
+
+ try {
+
+ // get factory method parse(InputStream)
+ Method m = factory.getMethod("parse", Reader.class);
+ Object[] args = {reader};
+ Object obj = m.invoke(type, args);
+
+ if (obj instanceof XmlObject) {
+ result = (XmlObject)obj;
+ }
+
+ } catch (NoSuchMethodException nsme) {
+ // do nothing, just return null
+ } catch (InvocationTargetException ite) {
+ // do nothing, just return null
+ } catch (IllegalAccessException iae) {
+ // do nothing, just return null
+ }
+
+ return result;
+ }
+
+ /**
+ * Locate the XMLBean <code>Factory</code> inner class.
+ *
+ * @param type
+ * @return the Factory class if present, otherwise null.
+ */
+ private Class getFactory(Class type) {
+ Class result = null;
+
+ Class[] interfaces = type.getInterfaces();
+
+ // look for XMLBeans inner class Factory
+ for (Class inter : interfaces) {
+
+ Class[] declared = inter.getDeclaredClasses();
+
+ for (Class c : declared) {
+
+ if (c.getSimpleName().equals("Factory")) {
+ result = c;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Check if a <code>Class</code> is a valid XMLBeans data object. The
check procedure involves looking
+ * for the Interface <code>XmlObject</code> in the target type's
declaration. Assumed to be sufficient
+ * to identify the type as an XMLBean. From the javadoc (2.3.0) for
XmlObject: "Corresponds to the XML
+ * Schema xs:anyType, the base type for all XML Beans."
+ *
+ * @param type
+ * @return true if found to be an XMLBean object, otherwise false
+ */
+ protected boolean isXmlBean(Class type) {
+ boolean result = false;
+
+ Class[] interfaces = {type};
+
+ if (!type.isInterface()) {
+
+ interfaces = type.getInterfaces();
+ }
+
+ for (Class i : interfaces) {
+
+ Class[] superInterfaces = i.getInterfaces();
+
+ for (Class superI : superInterfaces) {
+
+ if (superI.getName().equals("org.apache.xmlbeans.XmlObject")) {
+ result = true;
+ }
+ }
+ }
+
+ return result;
+ }
+}
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java?rev=666722&view=auto
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
(added)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
Wed Jun 11 09:07:55 2008
@@ -0,0 +1,102 @@
+/**
+ * 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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.ConsumeMime;
+import javax.ws.rs.ProduceMime;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.xmlbeans.XmlObject;
+import org.codehaus.jettison.mapped.MappedXMLInputFactory;
+import org.codehaus.jettison.mapped.MappedXMLOutputFactory;
+
+/**
+ * JSON provider for XMLBeans data objects.
+ */
[EMAIL PROTECTED]("application/json")
[EMAIL PROTECTED]("application/json")
[EMAIL PROTECTED]
+public final class XMLBeansJSONProvider extends XMLBeansElementProvider {
+
+ /** [EMAIL PROTECTED] */
+ public XmlObject readFrom(Class type, MediaType m, MultivaluedMap headers,
InputStream is) {
+ XmlObject result = null;
+
+ try {
+
+ Map<String, String> nstojns = new HashMap<String, String>();
+
+ MappedXMLInputFactory factory = new MappedXMLInputFactory(nstojns);
+ XMLStreamReader xsr = factory.createXMLStreamReader(is);
+ Reader r = (Reader)xsr;
+ result = parseXmlBean(type, r);
+
+ xsr.close();
+ result = null;
+
+ } catch (XMLStreamException e) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ }
+
+ return result;
+ }
+
+ /** [EMAIL PROTECTED] */
+ public void writeTo(XmlObject obj, MediaType m, MultivaluedMap headers,
OutputStream os) {
+
+ try {
+
+ // Set up the JSON StAX implementation
+ Map<String, String> nstojns = new HashMap<String, String>();
+ XMLOutputFactory factory = new MappedXMLOutputFactory(nstojns);
+ XMLStreamWriter xsw = factory.createXMLStreamWriter(os);
+
+ if (obj instanceof XmlObject) {
+
+ XmlObject xObj = (XmlObject)obj;
+ XMLBeanStreamSerializer ser = new XMLBeanStreamSerializer();
+ ser.serialize(xObj, xsw);
+ }
+
+ xsw.flush();
+ xsw.close();
+
+ } catch (XMLStreamException e) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ } catch (IOException ioe) {
+ throw new
WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
+ }
+ }
+}
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/XMLBeansJSONProvider.java
------------------------------------------------------------------------------
svn:keywords = Rev Date