incubator-wink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ngalla...@apache.org
Subject svn commit: r787557 [10/12] - in /incubator/wink/contrib/ibm-jaxrs: ./ lib/ src/ src/com/ src/com/ibm/ src/com/ibm/ws/ src/com/ibm/ws/jaxrs/ src/com/ibm/ws/jaxrs/annotations/ src/com/ibm/ws/jaxrs/context/ src/com/ibm/ws/jaxrs/core/ src/com/ibm/ws/jaxrs...
Date Tue, 23 Jun 2009 05:41:55 GMT
Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomEntryProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomEntryProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomEntryProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomEntryProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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 org.apache.abdera.Abdera;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.writer.Writer;
+
+@Produces( { "application/atom+xml", "application/atom+xml;type=entry",
+        "application/json" })
+@Consumes( { "application/atom+xml", "application/atom+xml;type=entry" })
+@Provider
+public class AtomEntryProvider implements MessageBodyReader<Entry>, MessageBodyWriter<Entry> {
+
+    private static final Abdera ATOM_ENGINE = new Abdera();
+    private static final String JSON_TYPE = "application/json";
+
+    public long getSize(Entry entry, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return Entry.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(Entry entry, Class<?> clazz, Type type, Annotation[] a, MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+        if (JSON_TYPE.equals(mt.toString())) {
+            Writer w = ATOM_ENGINE.getWriterFactory().getWriter("json");
+            entry.writeTo(w, os);
+        } else {
+            entry.writeTo(os);
+        }
+
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return Entry.class.equals(type);
+    }
+
+    public Entry readFrom(Class<Entry> clazz, Type t, Annotation[] a, MediaType mt, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        Document<Entry> doc = ATOM_ENGINE.getParser().parse(is);
+        return doc.getRoot();
+    }
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomFeedProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomFeedProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomFeedProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/AtomFeedProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,79 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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 org.apache.abdera.Abdera;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.writer.Writer;
+
+@Produces( { "application/atom+xml", "application/atom+xml;type=feed",
+        "application/json" })
+@Consumes( { "application/atom+xml", "application/atom+xml;type=feed" })
+@Provider
+public class AtomFeedProvider implements MessageBodyWriter<Feed>, MessageBodyReader<Feed> {
+
+    private static final String JSON_TYPE = "application/json";
+    private static final Abdera ATOM_ENGINE = new Abdera();
+
+    public long getSize(Feed feed, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return Feed.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(Feed feed, Class<?> clazz, Type type, Annotation[] a, MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+        if (JSON_TYPE.equals(mt.toString())) {
+            Writer w = ATOM_ENGINE.getWriterFactory().getWriter("json");
+            feed.writeTo(w, os);
+        } else {
+            feed.writeTo(os);
+        }
+
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return Feed.class.equals(type);
+    }
+
+    public Feed readFrom(Class<Feed> clazz, Type t, Annotation[] a, MediaType mt, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        Document<Feed> doc = ATOM_ENGINE.getParser().parse(is);
+        return doc.getRoot();
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,144 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.StreamingOutput;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.helpers.IOUtils;
+
+import com.ibm.ws.jaxrs.i18n.Messages;
+
+@Provider
+@Produces("*/*")
+@Consumes("*/*")
+public class BinaryDataProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+    private static final int BUFFER_SIZE = 4096;
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return byte[].class.equals(type)
+                || InputStream.class.equals(type) || Reader.class.equals(type)
+                || File.class.equals(type);
+    }
+
+    public Object readFrom(Class<Object> clazz, Type genericType, Annotation[] annotations, MediaType type, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        if (InputStream.class.equals(clazz)) {
+            return is;
+        }
+        if (Reader.class.equals(clazz)) {
+            return new InputStreamReader(is, getEncoding(type));
+        }
+        if (byte[].class.equals(clazz)) {
+            return IOUtils.readBytesFromStream(is);
+        }
+        if (File.class.equals(clazz)) {
+            /*
+             * TODO FIXME: need to correct to a pre-defined temporary space.
+             * should this only be creating the file when relevant HTTP headers
+             * are sent in?
+             */
+            File f = File.createTempFile("jaxrs", "tmp");
+            FileOutputStream fos = new FileOutputStream(f);
+            IOUtils.copy(is, fos, BUFFER_SIZE);
+            fos.close();
+            /*
+             * TODO FIXME: should we delete this file somehow after the resource method
+             * is invoked?  what if it gets passed back as the Response entity?
+             */
+            return f;
+        }
+        throw new IOException(Messages.getMessage("invalidInput00",
+                clazz != null ? clazz.getName() : "<null>"));
+    }
+
+    public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        if (byte[].class.isAssignableFrom(t.getClass())) {
+            return ((byte[]) t).length;
+        }
+        if (File.class.isAssignableFrom(t.getClass())) {
+            return ((File) t).length();
+        }
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return byte[].class.isAssignableFrom(type)
+                || InputStream.class.isAssignableFrom(type)
+                || File.class.isAssignableFrom(type)
+                || Reader.class.isAssignableFrom(type)
+                || StreamingOutput.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(Object o, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType type, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+
+        if (InputStream.class.isAssignableFrom(o.getClass())) {
+            IOUtils.copyAndCloseInput((InputStream) o, os);
+        } else if (File.class.isAssignableFrom(o.getClass())) {
+            IOUtils.copyAndCloseInput(new BufferedInputStream(
+                    new FileInputStream((File) o)), os);
+        } else if (byte[].class.isAssignableFrom(o.getClass())) {
+            os.write((byte[]) o);
+        } else if (Reader.class.isAssignableFrom(o.getClass())) {
+            try {
+                Writer writer = new OutputStreamWriter(os, getEncoding(type));
+                IOUtils.copy((Reader) o, writer, BUFFER_SIZE);
+                writer.flush();
+            } finally {
+                ((Reader) o).close();
+            }
+
+        } else if (StreamingOutput.class.isAssignableFrom(o.getClass())) {
+            ((StreamingOutput) o).write(os);
+        } else {
+            throw new IOException(Messages.getMessage("invalidInput00",
+                    clazz != null ? clazz.getName() : "<null>"));
+        }
+
+    }
+
+    private String getEncoding(MediaType mt) {
+        String enc = mt.getParameters().get("charset");
+        return enc == null ? "UTF-8" : enc;
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,146 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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 org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+
+@Consumes("application/x-www-form-urlencoded")
+@Produces("application/x-www-form-urlencoded")
+@Provider
+public final class FormEncodingProvider implements MessageBodyReader<MultivaluedMap<String, String>>, MessageBodyWriter<MultivaluedMap<String, String>> {
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return MultivaluedMap.class.equals(type);
+    }
+
+    public MultivaluedMap<String, String> readFrom(Class<MultivaluedMap<String, String>> clazz, Type genericType, Annotation[] annotations, MediaType type, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        try {
+
+            String charset = "UTF-8";
+
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            copy(is, bos, 1024);
+            String postBody = new String(bos.toByteArray(), charset);
+
+            MultivaluedMap<String, String> params = getParams(postBody);
+
+            return params;
+        } catch (Exception e) {
+            throw new WebApplicationException(e);
+        }
+    }
+
+    public static void copy(final InputStream input, final OutputStream output, final int bufferSize)
+            throws IOException {
+        final byte[] buffer = new byte[bufferSize];
+        int n = 0;
+        n = input.read(buffer);
+        while (-1 != n) {
+            output.write(buffer, 0, n);
+            n = input.read(buffer);
+        }
+    }
+
+    /**
+     * Retrieve map of parameters from the passed in message
+     *
+     * @param message
+     * @return a Map of parameters.
+     */
+    protected static MultivaluedMap<String, String> getParams(String body) {
+        MultivaluedMap<String, String> params = new MetadataMap<String, String>();
+        if (!StringUtils.isEmpty(body)) {
+            List<String> parts = Arrays.asList(body.split("&"));
+            for (String part : parts) {
+                String[] keyValue = part.split("=");
+                // Change to add blank string if key but not value is specified
+                if (keyValue.length == 2) {
+                    params.add(keyValue[0], keyValue[1]);
+                } else {
+                    params.add(keyValue[0], "");
+                }
+            }
+        }
+        return params;
+    }
+
+    public long getSize(MultivaluedMap<String, String> arg0, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4) {
+        /*
+         * TODO can probably calculate the length in most situations
+         */
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) {
+        return true;
+    }
+
+    public void writeTo(MultivaluedMap<String, String> metadataMap, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream os)
+            throws IOException, WebApplicationException {
+        Writer w = new OutputStreamWriter(os);
+        boolean isFirstOut = true;
+        /*
+         * TODO : should we form url encode here or hope that the application has
+         * done the encoding?
+         */
+        for (String key : metadataMap.keySet()) {
+            List<String> values = metadataMap.get(key);
+            if (values == null || values.size() == 0) {
+                if (!isFirstOut) {
+                    w.write("&");
+                }
+                w.write(key + "=");
+                isFirstOut = false;
+            } else {
+                for (String v : values) {
+                    if (!isFirstOut) {
+                        w.write("&");
+                    }
+                    w.write(key + "=" + v);
+                    isFirstOut = false;
+                }
+            }
+        }
+        w.flush();
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,144 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+@Provider
+@Produces(value = { MediaType.APPLICATION_XML, MediaType.TEXT_XML,
+        "application/*+xml" })
+@Consumes(value = { MediaType.APPLICATION_XML, MediaType.TEXT_XML,
+        "application/*+xml" })
+public final class JAXBElementProvider extends AbstractJAXBProvider {
+
+    private static final Log log = LogFactory.getLog(JAXBElementProvider.class);
+
+    @Context
+    protected ContextResolver<JAXBContext> resolver;
+
+    public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        Object obj = null;
+        try {
+            setContextResolver(resolver);
+            Class<?> theType = getActualType(type, genericType);
+            JAXBContext context = getJAXBContext(theType, genericType);
+
+            //TODO: Revisit this! This is done to check to see if null input was
+            // sent. We cannot necessarily rely on the 'Content-Length' header
+            // for this, but there may be a much better way to do this.
+            BufferedInputStream bis = new BufferedInputStream(is);
+            bis.mark(1);
+            int firstByte = bis.read();
+            bis.reset();
+            if (firstByte == -1) {
+                return null;
+            }
+
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            if (JAXBElement.class.isAssignableFrom(type)
+                    || type.getAnnotation(XmlRootElement.class) == null) {
+                if (JAXBElement.class.isAssignableFrom(type)) {
+                    obj = unmarshaller
+                            .unmarshal(new StreamSource(bis), theType);
+                } else {
+                    JAXBElement element = unmarshaller.unmarshal(
+                            new StreamSource(bis), theType);
+                    obj = element.getValue();
+                }
+            } else {
+                obj = unmarshaller.unmarshal(bis);
+            }
+
+            obj = unwrapResponse(type, obj);
+            return obj;
+        }
+
+        catch (JAXBException e) {
+            if(log.isErrorEnabled())
+                log.error(e);
+            throw new WebApplicationException(e);
+        }
+    }
+
+    public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns, MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+        try {
+            setContextResolver(resolver);
+            Object actualObject = checkAdapter(obj, anns);
+            Class<?> actualClass = actualObject.getClass();
+            Type gType = genericType;
+            if (cls == gType) {
+                gType = actualClass;
+            }
+            Marshaller ms = createMarshaller(actualObject, actualClass, gType,
+                    m);
+            if (!JAXBElement.class.isAssignableFrom(actualClass)
+                    && actualClass.getAnnotation(XmlRootElement.class) == null) {
+                QName qName = getElementName(actualClass);
+                if (qName != null) {
+                    JAXBElement element = new JAXBElement(qName, actualClass,
+                            actualObject);
+                    ms.marshal(element, os);
+                } else {
+                    throw new RuntimeException(
+                            "The "
+                                    + actualClass.getName()
+                                    + " could "
+                                    + "not be marshalled to XML because its element name "
+                                    + "could not be determined.");
+                }
+            } else {
+                ms.marshal(actualObject, os);
+            }
+
+        } catch (JAXBException e) {
+            if(log.isErrorEnabled())
+                log.error(e);
+            throw new WebApplicationException(e);
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/PrimitiveTextProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/PrimitiveTextProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/PrimitiveTextProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/PrimitiveTextProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,71 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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 org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+
+@Provider
+@Produces("text/plain")
+@Consumes("text/plain")
+public class PrimitiveTextProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+    private static boolean isSupported(Class<?> type) {
+        return type.isPrimitive() || Number.class.isAssignableFrom(type);
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return isSupported(type);
+    }
+
+    public Object readFrom(Class type, Type genType, Annotation[] anns, MediaType mt, MultivaluedMap headers, InputStream is)
+            throws IOException {
+        return InjectionUtils.handleParameter(IOUtils.readStringFromStream(is)
+                .toString(), type, false);
+    }
+
+    public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return isSupported(type);
+    }
+
+    public void writeTo(Object obj, Class type, Type genType, Annotation[] anns, MediaType mt, MultivaluedMap headers, OutputStream os)
+            throws IOException {
+        os.write(obj.toString().getBytes("UTF-8"));
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/ProviderFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/ProviderFactory.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/ProviderFactory.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,713 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+import com.ibm.ws.jaxrs.context.ContextConstants;
+import com.ibm.ws.jaxrs.context.RESTContext;
+import com.ibm.ws.jaxrs.integration.IntegrationRegistry;
+import com.ibm.ws.jaxrs.integration.JAXRSProviderCacheProvider;
+import com.ibm.ws.jaxrs.lifecycle.LifecycleManager;
+import com.ibm.ws.jaxrs.lifecycle.LifecycleManagerFactory;
+import com.ibm.ws.jaxrs.metadata.RESTMetaData;
+import com.ibm.ws.jaxrs.model.reflective.ProviderInfoImpl;
+import com.ibm.ws.jaxrs.utils.ClassUtils;
+
+public final class ProviderFactory {
+
+    private static final Log log = LogFactory.getLog(ProviderFactory.class);
+
+    private final List<ProviderInfo<MessageBodyReader>> defaultMessageReaders = new ArrayList<ProviderInfo<MessageBodyReader>>();
+    private final List<ProviderInfo<MessageBodyWriter>> defaultMessageWriters = new ArrayList<ProviderInfo<MessageBodyWriter>>();
+    private final List<ProviderInfo<MessageBodyReader>> userMessageReaders = new ArrayList<ProviderInfo<MessageBodyReader>>();
+    private final List<ProviderInfo<MessageBodyWriter>> userMessageWriters = new ArrayList<ProviderInfo<MessageBodyWriter>>();
+    private final List<ProviderInfo<ContextResolver>> defaultContextResolvers = new ArrayList<ProviderInfo<ContextResolver>>();
+    private final List<ProviderInfo<ContextResolver>> userContextResolvers = new ArrayList<ProviderInfo<ContextResolver>>();
+    private final List<ProviderInfo<ExceptionMapper>> defaultExceptionMappers = new ArrayList<ProviderInfo<ExceptionMapper>>();
+    private final List<ProviderInfo<ExceptionMapper>> userExceptionMappers = new ArrayList<ProviderInfo<ExceptionMapper>>();
+
+    private ProviderFactory(List<ProviderInfo> userProviders, RESTContext context) {
+        // TODO : this needs to be done differently,
+        // we need to use cxf-jaxrs-extensions
+        List<Object> providers = new ArrayList<Object>();
+
+        String[] providerClasses = {
+                "org.apache.cxf.jaxrs.provider.JAXBElementProvider",
+                //                     "org.apache.cxf.jaxrs.provider.JSONProvider",
+                "org.apache.cxf.jaxrs.provider.BinaryDataProvider",
+                "org.apache.cxf.jaxrs.provider.StringProvider",
+                "org.apache.cxf.jaxrs.provider.SourceProvider",
+                "org.apache.cxf.jaxrs.provider.FormEncodingProvider",
+                "org.apache.cxf.jaxrs.provider.PrimitiveTextProvider",
+                "org.apache.cxf.jaxrs.provider.AtomFeedProvider",
+                "org.apache.cxf.jaxrs.provider.AtomEntryProvider",
+                "org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper",
+                "com.ibm.ws.jaxrs.resolver.JAXBContextResolver",
+                "com.ibm.ws.jaxrs.provider.DataSourceProvider" };
+        ClassLoader cl = (ClassLoader) context
+                .getProperty(ContextConstants.CONTEXT_CLASSLOADER);
+        if (cl == null) {
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        for (int i = 0; i < providerClasses.length; i++) {
+            try {
+                Class clazz = ClassUtils.loadClass(providerClasses[i], cl);
+                providers.add(ClassUtils.newInstance(clazz));
+            } catch (Throwable t) {
+                System.out.println("Unable to load " + providerClasses[i]
+                        + " - skipping due to " + t.getMessage());
+                continue;
+            }
+        }
+
+        setProviders(defaultMessageReaders, defaultMessageWriters,
+                defaultContextResolvers, defaultExceptionMappers, providers);
+
+        setProviders(userMessageReaders, userMessageWriters,
+                userContextResolvers, userExceptionMappers, userProviders);
+
+    }
+
+    public static ProviderFactory getInstance(RESTContext context) {
+        JAXRSProviderCacheProvider cache = null;
+
+        Object integrationRegistrationKey = context
+                .getProperty(ContextConstants.INTEGRATION_REGISTRATION_KEY);
+
+        if (integrationRegistrationKey != null) {
+            cache = (JAXRSProviderCacheProvider) IntegrationRegistry
+                    .getIntegrationProvider(
+                            context
+                                    .getProperty(ContextConstants.INTEGRATION_REGISTRATION_KEY),
+                            JAXRSProviderCacheProvider.class);
+            if (log.isDebugEnabled()) {
+                log.debug("Using ProviderFactory cache: " + cache);
+            }
+        }
+
+        if (cache == null) {
+            RESTMetaData metadata = (RESTMetaData) context
+                    .getProperty(ContextConstants.REST_METADATA);
+            ProviderFactory pf = new ProviderFactory(metadata
+                    .getProviderInfoList(), context);
+
+            if (log.isDebugEnabled()) {
+                log
+                        .debug("Did not find ProviderCache so returning new ProviderFactory: "
+                                + pf);
+            }
+            return pf;
+        }
+
+        ProviderFactory pf = cache.getProviderFactory(context
+                .getProperty(ContextConstants.METADATA_KEY));
+        if (pf != null) {
+            if (log.isDebugEnabled()) {
+                log
+                        .debug("Found ProviderFactory in cache ProviderCache: "
+                                + pf);
+            }
+            return pf;
+        }
+        RESTMetaData metadata = (RESTMetaData) context
+                .getProperty(ContextConstants.REST_METADATA);
+        if (metadata == null) {
+            /*
+             * if the metadata hasn't been built, then there's no chance of putting it into a cache
+             */
+            pf = new ProviderFactory(new ArrayList<ProviderInfo>(), context);
+            if (log.isDebugEnabled()) {
+                log
+                        .debug("Could not find built metadata so returning default ProviderFactory: "
+                                + pf);
+            }
+            return pf;
+        }
+        pf = new ProviderFactory(metadata.getProviderInfoList(), context);
+        if (log.isDebugEnabled()) {
+            log
+                    .debug("Did not find ProviderFactory in cache so created: "
+                            + pf);
+        }
+
+        cache.cacheProviderFactory(context
+                .getProperty(ContextConstants.METADATA_KEY), pf);
+        return pf;
+    }
+
+    public <T> ContextResolver<T> createContextResolver(Type contextType, MediaType mt, RESTContext context) {
+        final ContextResolver<T> userDefinedResolver = chooseContextResolver(
+                userContextResolvers, contextType, mt, context);
+        final ContextResolver<T> defaultRuntimeContextResolvers = chooseContextResolver(
+                defaultContextResolvers, contextType, mt, context);
+        if (userDefinedResolver != null
+                && defaultRuntimeContextResolvers != null) {
+            return new ContextResolver<T>() {
+
+                public T getContext(Class<?> arg0) {
+                    T o = userDefinedResolver.getContext(arg0);
+                    if (o != null) {
+                        return o;
+                    }
+                    return defaultRuntimeContextResolvers.getContext(arg0);
+                }
+            };
+        } else if (userDefinedResolver != null) {
+            return userDefinedResolver;
+        } else if (defaultRuntimeContextResolvers != null) {
+            return defaultRuntimeContextResolvers;
+        }
+        return null;
+    }
+
+    private <T> ContextResolver<T> chooseContextResolver(List<ProviderInfo<ContextResolver>> resolvers, Type contextType, final MediaType mediaType, final RESTContext context) {
+        final List<ProviderInfo<ContextResolver>> compatibleContextResolverInfo = new ArrayList<ProviderInfo<ContextResolver>>();
+        for (ProviderInfo<ContextResolver> cr : resolvers) {
+            boolean isProducesMediaTypeMatch = true;
+            if (cr.getProducesTypes() != null && mediaType != null) {
+                isProducesMediaTypeMatch = false;
+                for (MediaType mt : cr.getProducesTypes()) {
+                    if (mediaType.isCompatible(mt)) {
+                        isProducesMediaTypeMatch = true;
+                        break;
+                    }
+                }
+            }
+            if (isProducesMediaTypeMatch) {
+                Type[] types = cr.getProviderClass().getGenericInterfaces();
+                for (Type t : types) {
+                    if (t instanceof ParameterizedType) {
+                        ParameterizedType pt = (ParameterizedType) t;
+                        Type[] args = pt.getActualTypeArguments();
+                        for (int i = 0; i < args.length; i++) {
+                            if (contextType == args[i]) {
+                                compatibleContextResolverInfo.add(cr);
+                            }
+                            /*
+                             * should check if type widening is acceptable
+                             */
+                            //                            else if (contextType instanceof Class && args[i] instanceof Class) {
+                            //                                Class contextTypeClass = (Class) contextType;
+                            //                                Class argClass = (Class) args[i];
+                            //                                if (argClass.isAssignableFrom(contextTypeClass)) {
+                            //                                    InjectionUtils.injectContextFields(cr.getProvider(), cr,
+                            //                                        context);
+                            //                                    InjectionUtils.injectContextMethods(cr.getProvider(), cr,
+                            //                                        context);
+                            //                                    compatibleContextResolverInfo.add(cr);
+                            //                                }
+                            //                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (compatibleContextResolverInfo.size() == 1) {
+            LifecycleManager mgr = LifecycleManagerFactory
+                    .getLifeCycleManager(compatibleContextResolverInfo.get(0));
+            ContextResolver instance = (ContextResolver) mgr.createInstance(
+                    compatibleContextResolverInfo.get(0), context);
+            return instance;
+        }
+        if (compatibleContextResolverInfo.size() > 1) {
+            if (mediaType != null) {
+                Collections.sort(compatibleContextResolverInfo,
+                        new ProviderInfoProducesComparator<ContextResolver>(
+                                mediaType));
+            }
+            return new ContextResolver<T>() {
+                final List<ContextResolver<T>> contextResolvers = new ArrayList<ContextResolver<T>>();
+                {
+                    for (ProviderInfo<ContextResolver> pi : compatibleContextResolverInfo) {
+
+                        LifecycleManager mgr = LifecycleManagerFactory
+                                .getLifeCycleManager(pi);
+                        ContextResolver instance = (ContextResolver) mgr
+                                .createInstance(pi, context);
+                        contextResolvers.add(instance);
+                    }
+                }
+
+                public T getContext(Class<?> arg0) {
+                    for (ContextResolver<T> ct : contextResolvers) {
+                        T o = ct.getContext(arg0);
+                        if (o != null) {
+                            return o;
+                        }
+                    }
+                    return null;
+                }
+
+            };
+        }
+        return null;
+    }
+
+    public <T> ExceptionMapper createExceptionMapper(Class<T> exceptionType, RESTContext context) {
+        List<ProviderInfo<ExceptionMapper>> exceptionMappers = new ArrayList<ProviderInfo<ExceptionMapper>>();
+        exceptionMappers.addAll(userExceptionMappers);
+        exceptionMappers.addAll(defaultExceptionMappers);
+        return chooseExceptionMapper(exceptionType, context, exceptionMappers);
+    }
+
+    private int getDistanceFromClass(Class<?> superclass, Class<?> subclass) {
+        Class<?> currentClass = subclass;
+        int distance = 0;
+        while (!currentClass.equals(superclass)) {
+            ++distance;
+            currentClass = currentClass.getSuperclass();
+            if (currentClass == null) {
+                distance = -1;
+                // how did it reach here?
+                throw new WebApplicationException(500);
+            }
+        }
+        return distance;
+    }
+
+    private <T> ExceptionMapper chooseExceptionMapper(Class<T> exceptionType, RESTContext context, List<ProviderInfo<ExceptionMapper>> exceptionMappers) {
+        int minDistance = -1;
+        ProviderInfo<ExceptionMapper> providerInfo = null;
+
+        for (ProviderInfo<ExceptionMapper> em : exceptionMappers) {
+            Type t = em.getParameterizedType().get(
+                    ProviderInfo.Type.ExceptionMapper);
+
+            if (t instanceof Class) {
+                if (((Class<?>) t).isAssignableFrom(exceptionType)) {
+                    int distance = getDistanceFromClass((Class<?>) t,
+                            exceptionType);
+                    if (distance < minDistance || minDistance == -1) {
+                        minDistance = distance;
+                        providerInfo = em;
+                    }
+                }
+            } else if (t instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType) t;
+                if (pt.getRawType() instanceof Class) {
+                    Class<?> c = (Class<?>) pt.getRawType();
+                    if (c.isAssignableFrom(exceptionType)) {
+                        int distance = getDistanceFromClass(c, exceptionType);
+                        if (distance < minDistance || minDistance == -1) {
+                            minDistance = distance;
+                            providerInfo = em;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (providerInfo == null) {
+            return null;
+        }
+
+        LifecycleManager mgr = LifecycleManagerFactory
+                .getLifeCycleManager(providerInfo);
+        ExceptionMapper instance = (ExceptionMapper) mgr.createInstance(
+                providerInfo, context);
+        return instance;
+    }
+
+    public <T> MessageBodyReader<T> createMessageBodyReader(Class<T> bodyType, Type parameterType, Annotation[] parameterAnnotations, MediaType mediaType, RESTContext context) {
+        // Try user provided providers
+        MessageBodyReader<T> mr = chooseMessageReader(userMessageReaders,
+                bodyType, parameterType, parameterAnnotations, mediaType,
+                context);
+
+        //If none found try the default ones
+        if (mr == null) {
+            mr = chooseMessageReader(defaultMessageReaders, bodyType,
+                    parameterType, parameterAnnotations, mediaType, context);
+        }
+
+        return mr;
+    }
+
+    public <T> MessageBodyWriter<T> createMessageBodyWriter(Class<T> bodyType, Type parameterType, Annotation[] parameterAnnotations, MediaType mediaType, RESTContext context) {
+        if (log.isDebugEnabled()) {
+            log.debug("Attempting to load MessageBodyWriter with info: ");
+            log.debug("    Body Type: " + bodyType.getClass().getName());
+            log.debug("    Parameter Type: " + parameterType);
+            log.debug("    Annotations: " + parameterAnnotations);
+            log.debug("    Media Type: " + mediaType);
+        }
+
+        // Try user provided providers
+        MessageBodyProviderMatch<MessageBodyWriter> match = chooseMessageWriter(
+                userMessageWriters, bodyType, parameterType,
+                parameterAnnotations, mediaType, context);
+        MessageBodyWriter mw = (match == null) ? null : match.getWriter();
+        if (log.isDebugEnabled()) {
+            if (mw != null)
+                log.debug("MessageBodyWriter found from user list: "
+                        + mw.getClass().getName());
+            else
+                log.debug("Unable to find MessageBodyWriter from user list.");
+        }
+
+        // If none found try the default ones
+        if (match == null) {
+            match = chooseMessageWriter(defaultMessageWriters, bodyType,
+                    parameterType, parameterAnnotations, mediaType, context);
+        }
+
+        mw = (match == null) ? null : match.getWriter();
+        if (log.isDebugEnabled()) {
+            if (mw != null)
+                log.debug("MessageBodyWriter found from default list: "
+                        + mw.getClass().getName());
+            else
+                log
+                        .debug("Unable to find MessageBodyWriter from default list.");
+        }
+
+        if (match != null) {
+            /*
+             * this is a hacked way of returning the best response content type.
+             * did not want to change method signatures at the time to return essentially a tuple
+             */
+            context.setProperty(ContextConstants.RESPONSE_CONTENT_TYPE, match
+                    .getMediaType());
+        }
+        return mw;
+    }
+
+    private static void setProviders(List<ProviderInfo<MessageBodyReader>> readers, List<ProviderInfo<MessageBodyWriter>> writers, List<ProviderInfo<ContextResolver>> resolvers, List<ProviderInfo<ExceptionMapper>> excMappers, List<?> providers) {
+
+        for (Object o : providers) {
+            Class<?> classToTest = o.getClass();
+            // TODO: Reusing the same ProviderInfo object may not be the right thing
+            // to do here, but it solves problems created by injection of different
+            // thread local proxies
+            ProviderInfo info = null;
+
+            if (o instanceof ProviderInfo) {
+                info = (ProviderInfo) o;
+                classToTest = info.getProviderClass();
+            }
+
+            if (MessageBodyReader.class.isAssignableFrom(classToTest)) {
+                if (info == null) {
+                    info = new ProviderInfoImpl<MessageBodyReader>(
+                            (MessageBodyReader) o);
+                }
+                readers.add(info);
+            }
+
+            if (MessageBodyWriter.class.isAssignableFrom(classToTest)) {
+                if (info == null) {
+                    info = new ProviderInfoImpl<MessageBodyWriter>(
+                            (MessageBodyWriter) o);
+                }
+                writers.add(info);
+            }
+
+            if (ContextResolver.class.isAssignableFrom(classToTest)) {
+                if (info == null) {
+                    info = new ProviderInfoImpl<ContextResolver>(
+                            (ContextResolver) o);
+                }
+                resolvers.add(info);
+            }
+
+            if (ExceptionMapper.class.isAssignableFrom(classToTest)) {
+                if (info == null) {
+                    info = new ProviderInfoImpl<ExceptionMapper>(
+                            (ExceptionMapper) o);
+                }
+                excMappers.add(info);
+            }
+        }
+    }
+
+    /**
+     * Choose the first body reader provider that matches the requestedMimeType
+     * for a sorted list of Entity providers
+     * Returns null if none is found.
+     * @param <T>
+     * @param messageBodyReaders
+     * @param type
+     * @param requestedMimeType
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    private <T> MessageBodyReader<T> chooseMessageReader(List<ProviderInfo<MessageBodyReader>> readers, Class<T> type, Type genericType, Annotation[] annotations, final MediaType mediaType, RESTContext context) {
+        if (log.isDebugEnabled()) {
+            log.debug("chooseMessageReader, type= " + type.getName()
+                    + ", genericType= " + genericType + ", mediaType= "
+                    + (mediaType != null ? mediaType.toString() : "<null>"));
+        }
+
+        List<MessageBodyProviderMatch<MessageBodyReader>> possibleReaders = new ArrayList<MessageBodyProviderMatch<MessageBodyReader>>();
+        /*
+         * TODO possible performance improvement is not to call the
+         * MessageBodyReader.isReadable method in matchesReaderCriteria
+         * until the mime types are compared and the writers are sorted. The
+         * penalty for the isReadable method could be significant.
+         */
+        for (ProviderInfo<MessageBodyReader> ep : readers) {
+            List<MediaType> supportedMediaTypes = ep.getConsumesTypes();
+            List<MediaType> availableMimeTypes = JAXRSUtils.intersectMimeTypes(
+                    Collections.singletonList(mediaType), supportedMediaTypes);
+
+            if (availableMimeTypes.size() == 0) {
+                continue;
+            }
+
+            Type t = ep
+                    .getParameterizedType()
+                    .get(
+                            org.apache.cxf.jaxrs.model.ProviderInfo.Type.MessageBodyReader);
+            if (!isTypeCompatible(type, t)) {
+                continue;
+            }
+
+            LifecycleManager mgr = LifecycleManagerFactory
+                    .getLifeCycleManager(ep);
+            MessageBodyReader instance = (MessageBodyReader) mgr
+                    .createInstance(ep, context);
+
+            if (instance.isReadable(type, genericType, annotations, mediaType)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Found suitable MessageBodyReader instance: "
+                            + instance.getClass().getName());
+                }
+                possibleReaders
+                        .add(new MessageBodyProviderMatch<MessageBodyReader>(
+                                ep, instance, mediaType));
+            }
+        }
+
+        if (possibleReaders.size() > 0) {
+            Collections.sort(possibleReaders,
+                    new Comparator<MessageBodyProviderMatch>() {
+                        public int compare(MessageBodyProviderMatch object1, MessageBodyProviderMatch object2) {
+                            return new ProviderInfoConsumesComparator<MessageBodyReader>(
+                                    mediaType).compare(object1
+                                    .getProviderInfo(), object2
+                                    .getProviderInfo());
+                        }
+                    });
+            return possibleReaders.get(0).getWriter();
+        }
+        return null;
+    }
+
+    /**
+     * Choose the first body writer provider that matches the requestedMimeType
+     * for a sorted list of Entity providers
+     * Returns null if none is found.
+     * @param <T>
+     * @param messageBodyWriters
+     * @param type
+     * @param requestedMimeType
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    private <T> MessageBodyProviderMatch<MessageBodyWriter> chooseMessageWriter(List<ProviderInfo<MessageBodyWriter>> writers, Class<T> type, Type genericType, Annotation[] annotations, final MediaType mediaType, RESTContext context) {
+        if (log.isDebugEnabled()) {
+            log.debug("chooseMessageWriter, type= " + type.getName()
+                    + ", genericType= " + genericType + ", mediaType= "
+                    + (mediaType != null ? mediaType.toString() : "<null>"));
+        }
+
+        List<MessageBodyProviderMatch> possibleWriters = new ArrayList<MessageBodyProviderMatch>();
+        /*
+         * TODO possible performance improvement is not to call the
+         * MessageBodyWriter.isWritable method in matchesWriterCriterias
+         * until the mime types are compared and the writers are sorted. The
+         * penalty for the isWritable method could be significant.
+         */
+        for (ProviderInfo<MessageBodyWriter> ep : writers) {
+            List<MediaType> availableMimeTypes = JAXRSUtils
+                    .intersectMimeTypes(Collections.singletonList(mediaType),
+                            ep.getProducesTypes());
+            if (availableMimeTypes.size() == 0) {
+                continue;
+            }
+
+            Type t = ep
+                    .getParameterizedType()
+                    .get(
+                            org.apache.cxf.jaxrs.model.ProviderInfo.Type.MessageBodyWriter);
+            if (!isTypeCompatible(type, t)) {
+                continue;
+            }
+
+            LifecycleManager mgr = LifecycleManagerFactory
+                    .getLifeCycleManager(ep);
+            MessageBodyWriter instance = (MessageBodyWriter) mgr
+                    .createInstance(ep, context);
+            for (MediaType intersectedMediaType : availableMimeTypes) {
+                if (instance.isWriteable(type, genericType, annotations,
+                        mediaType)) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Found suitable MessageBodyWriter instance: "
+                                + instance.getClass().getName());
+                    }
+                    possibleWriters.add(new MessageBodyProviderMatch(ep,
+                            instance, intersectedMediaType));
+                }
+            }
+        }
+
+        if (possibleWriters.size() > 0) {
+            Collections.sort(possibleWriters,
+                    new Comparator<MessageBodyProviderMatch>() {
+                        public int compare(MessageBodyProviderMatch object1, MessageBodyProviderMatch object2) {
+                            return new ProviderInfoProducesComparator<MessageBodyWriter>(
+                                    mediaType).compare(object1
+                                    .getProviderInfo(), object2
+                                    .getProviderInfo());
+                        }
+                    });
+            return possibleWriters.get(0);
+        }
+        return null;
+    }
+
+    private static class MessageBodyProviderMatch<T> {
+        final private ProviderInfo<T> provider;
+        final private T instance;
+        final private MediaType mediaType;
+
+        public MessageBodyProviderMatch(ProviderInfo<T> provider, T instance, MediaType mediaType) {
+            this.provider = provider;
+            this.instance = instance;
+            this.mediaType = mediaType;
+        }
+
+        public ProviderInfo<T> getProviderInfo() {
+            return provider;
+        }
+
+        public T getWriter() {
+            return instance;
+        }
+
+        public MediaType getMediaType() {
+            return mediaType;
+        }
+    }
+
+    private final static boolean isTypeCompatible(Class<?> returnType, Type providerTypeArgument) {
+        if (returnType == providerTypeArgument) {
+            return true;
+        } else if (providerTypeArgument instanceof Class) {
+            Class<?> argsType = (Class<?>) providerTypeArgument;
+            if (argsType.isAssignableFrom(returnType)) {
+                return true;
+            }
+        } else if (providerTypeArgument instanceof ParameterizedType) {
+            Class<?> argsType = (Class<?>) ((ParameterizedType) providerTypeArgument)
+                    .getRawType();
+            if (argsType.isAssignableFrom(returnType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static class ProviderInfoProducesComparator<T> implements Comparator<ProviderInfo<T>> {
+
+        final private MediaType mediaType;
+
+        public ProviderInfoProducesComparator(MediaType mt) {
+            this.mediaType = mt;
+        }
+
+        public int compare(ProviderInfo<T> object1, ProviderInfo<T> object2) {
+            List<MediaType> pi1MediaTypes = object1.getProducesTypes();
+            List<MediaType> pi2MediaTypes = object2.getProducesTypes();
+
+            MediaType pi1MostSpecificCompatible = findMostSpecificCompatibleMediaType(
+                    mediaType, pi1MediaTypes);
+            MediaType pi2MostSpecificCompatible = findMostSpecificCompatibleMediaType(
+                    mediaType, pi2MediaTypes);
+
+            return JAXRSUtils.compareMediaTypes(pi1MostSpecificCompatible,
+                    pi2MostSpecificCompatible);
+        }
+    }
+
+    private static class ProviderInfoConsumesComparator<T> implements Comparator<ProviderInfo<T>> {
+
+        final private MediaType mediaType;
+
+        public ProviderInfoConsumesComparator(MediaType mt) {
+            this.mediaType = mt;
+        }
+
+        public int compare(ProviderInfo<T> object1, ProviderInfo<T> object2) {
+            List<MediaType> pi1MediaTypes = object1.getConsumesTypes();
+            List<MediaType> pi2MediaTypes = object2.getConsumesTypes();
+
+            MediaType pi1MostSpecificCompatible = findMostSpecificCompatibleMediaType(
+                    mediaType, pi1MediaTypes);
+            MediaType pi2MostSpecificCompatible = findMostSpecificCompatibleMediaType(
+                    mediaType, pi2MediaTypes);
+            return JAXRSUtils.compareMediaTypes(pi1MostSpecificCompatible,
+                    pi2MostSpecificCompatible);
+        }
+    }
+
+    private static MediaType findMostSpecificCompatibleMediaType(MediaType typeGiven, List<MediaType> availableTypes) {
+        if (typeGiven == null || availableTypes == null) {
+            return null;
+        }
+        MediaType mostSpecificCompatibleType = null;
+        for (MediaType mt : availableTypes) {
+            if (typeGiven.isCompatible(mt)) {
+                if (mostSpecificCompatibleType == null) {
+                    mostSpecificCompatibleType = mt;
+                } else {
+                    if (!mt.isWildcardType()
+                            && mostSpecificCompatibleType.isWildcardType()) {
+                        mostSpecificCompatibleType = mt;
+                    } else if (!mostSpecificCompatibleType.isWildcardType()
+                            && mostSpecificCompatibleType.isWildcardSubtype()
+                            && !mt.isWildcardType() && !mt.isWildcardSubtype()) {
+                        mostSpecificCompatibleType = mt;
+                    }
+                }
+            }
+        }
+        return mostSpecificCompatibleType;
+    }
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/SourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/SourceProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/SourceProvider.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,105 @@
+/*
+ * 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.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+
+import com.ibm.ws.jaxrs.i18n.Messages;
+
+@Provider
+@Produces(value = { "text/xml", "application/xml", "application/*+xml" })
+@Consumes(value = { "text/xml", "application/xml", "application/*+xml" })
+public class SourceProvider implements MessageBodyReader<Source>, MessageBodyWriter<Source> {
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return Source.class.isAssignableFrom(type);
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return DOMSource.class.equals(type) || StreamSource.class.equals(type)
+                || Source.class.equals(type);
+    }
+
+    public Source readFrom(Class<Source> source, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        if (DOMSource.class.equals(source)) {
+            Document doc = null;
+            DocumentBuilderFactory factory = DocumentBuilderFactory
+                    .newInstance();
+            DocumentBuilder builder;
+            try {
+                builder = factory.newDocumentBuilder();
+                doc = builder.parse(is);
+            } catch (Exception e) {
+                IOException ioex = new IOException(Messages
+                        .getMessage("sourceCreateFail"));
+                ioex.setStackTrace(e.getStackTrace());
+                throw ioex;
+            }
+
+            return new DOMSource(doc);
+        } else if (StreamSource.class.equals(source)
+                || Source.class.equals(source)) {
+            return new StreamSource(is);
+        }
+
+        throw new IOException("Unrecognized source");
+    }
+
+    public void writeTo(Source source, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+        StreamResult result = new StreamResult(os);
+        TransformerFactory tf = TransformerFactory.newInstance();
+        try {
+            Transformer t = tf.newTransformer();
+            t.transform(source, result);
+        } catch (TransformerException te) {
+            te.printStackTrace();
+        }
+    }
+
+    public long getSize(Source source, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return -1;
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/StringProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/StringProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/StringProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/StringProvider.java Tue Jun 23 05:41:49 2009
@@ -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.cxf.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+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 org.apache.cxf.helpers.IOUtils;
+
+@Provider
+public final class StringProvider implements MessageBodyWriter<String>, MessageBodyReader<String> {
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return type == String.class;
+    }
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return type == String.class;
+    }
+
+    public long getSize(String s, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return s.length();
+    }
+
+    public String readFrom(Class<String> clazz, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+        try {
+            return IOUtils.toString(is);
+        } catch (IOException e) {
+            throw new WebApplicationException(e);
+        }
+    }
+
+    public void writeTo(String obj, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
+            throws IOException {
+        try {
+            os.write(obj.getBytes());
+        } catch (IOException e) {
+            throw new WebApplicationException(e);
+        }
+    }
+
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeanStreamSerializer.java Tue Jun 23 05:41:49 2009
@@ -0,0 +1,133 @@
+/*
+ * 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();
+            }
+        }
+    }
+}

Added: incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java?rev=787557&view=auto
==============================================================================
--- incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java (added)
+++ incubator/wink/contrib/ibm-jaxrs/src/org/apache/cxf/jaxrs/provider/XMLBeansElementProvider.java Tue Jun 23 05:41:49 2009
@@ -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.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.HttpURLConnection;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+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.
+ */
+@Produces("application/xml")
+@Consumes("application/xml")
+@Provider
+public class XMLBeansElementProvider implements MessageBodyReader<XmlObject>, MessageBodyWriter<XmlObject> {
+
+    /** {@inheritDoc} */
+    public XmlObject readFrom(Class<XmlObject> type, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, String> headers, InputStream is)
+            throws IOException {
+
+        return parseXmlBean(type, is);
+    }
+
+    /** {@inheritDoc} */
+    public void writeTo(XmlObject t, Class<?> cls, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap<String, Object> headers, OutputStream entityStream)
+            throws IOException {
+
+        // May need to set some XMLOptions here
+        t.save(entityStream);
+    }
+
+    /** {@inheritDoc} */
+    public long getSize(XmlObject t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        // return length not known
+        return -1;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        return isXmlBean(type);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+        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;
+    }
+}



Mime
View raw message