wink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b...@apache.org
Subject svn commit: r935425 - in /incubator/wink/trunk: wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/ wink-common/src/main/java/org/apache/wink/common...
Date Sun, 18 Apr 2010 22:31:14 GMT
Author: bluk
Date: Sun Apr 18 22:31:14 2010
New Revision: 935425

URL: http://svn.apache.org/viewvc?rev=935425&view=rev
Log:
Change mediatype with a charset for text providers

This takes into account the Accept-Charset
whenever possible.

See [WINK-270]

Modified:
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/FormatedExceptionProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ReaderProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/StringProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBCollectionProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBElementXmlProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/AcceptCharsetHeaderDelegate.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/utils/ProviderUtils.java
    incubator/wink/trunk/wink-providers/wink-jettison-provider/src/main/java/org/apache/wink/providers/jettison/JettisonJAXBElementProvider.java
    incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonArrayProvider.java
    incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonJAXBProvider.java
    incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonProvider.java

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/FormatedExceptionProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/FormatedExceptionProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/FormatedExceptionProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/FormatedExceptionProvider.java Sun Apr 18 22:31:14 2010
@@ -37,7 +37,9 @@ import javax.ws.rs.ext.MessageBodyWriter
 import javax.ws.rs.ext.Provider;
 import javax.ws.rs.ext.Providers;
 
+import org.apache.wink.common.internal.i18n.Messages;
 import org.apache.wink.common.internal.utils.ExceptionHelper;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.apache.wink.common.model.synd.SyndContent;
 import org.apache.wink.common.model.synd.SyndEntry;
 import org.apache.wink.common.model.synd.SyndText;
@@ -65,7 +67,8 @@ public class FormatedExceptionProvider i
                                Type genericType,
                                Annotation[] annotations,
                                MediaType mediaType) {
-        // do not check for non-null writer here; writeTo will handle this situation
+        // do not check for non-null writer here; writeTo will handle this
+        // situation
         return Throwable.class.isAssignableFrom(type);
     }
 
@@ -80,7 +83,7 @@ public class FormatedExceptionProvider i
         SyndEntry se = new SyndEntry();
         Class<?> rawType = se.getClass();
         Type genType = rawType;
-        String defaultErrorMessage = "An error has occurred while processing a request";
+        String defaultErrorMessage = Messages.getMessage("errorOccurredProcessingRequest"); //$NON-NLS-1$
 
         // Check if SyndEntry supports response MediaType
         @SuppressWarnings("unchecked")
@@ -111,6 +114,7 @@ public class FormatedExceptionProvider i
                                       entityStream);
         } else {
             localizedMessage = "<error>" + localizedMessage + "</error>"; //$NON-NLS-1$ //$NON-NLS-2$
+            mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
             entityStream.write(localizedMessage.getBytes(ProviderUtils.getCharset(mediaType)));
         }
     }

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ReaderProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ReaderProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ReaderProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ReaderProvider.java Sun Apr 18 22:31:14 2010
@@ -39,6 +39,8 @@ import javax.ws.rs.ext.MessageBodyReader
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.ws.rs.ext.Provider;
 
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
+
 @Provider
 @Produces("*/*")
 @Consumes("*/*")
@@ -82,6 +84,7 @@ public final class ReaderProvider implem
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException {
         try {
+            mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
             writeTo(t, new OutputStreamWriter(entityStream, getCharset(mediaType)));
         } finally {
             t.close();

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/StringProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/StringProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/StringProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/StringProvider.java Sun Apr 18 22:31:14 2010
@@ -32,12 +32,16 @@ import java.nio.charset.Charset;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
 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.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.apache.wink.common.utils.ProviderUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -71,8 +75,16 @@ public class StringProvider implements M
                         Type genericType,
                         Annotation[] annotations,
                         MediaType mediaType) {
-        String charSet = ProviderUtils.getCharset(mediaType);
-        if (charSet != null && !"UTF-8".equals(charSet)) { //$NON-NLS-1$
+        RuntimeContext context = RuntimeContextTLS.getRuntimeContext();
+        HttpHeaders requestHeaders = null;
+        if (context != null) {
+            requestHeaders = context.getHttpHeaders();
+        }
+        String charSet = ProviderUtils.getCharset(mediaType, requestHeaders);
+        if (charSet == null) {
+            return -1;
+        }
+        if (!"UTF-8".equals(charSet)) { //$NON-NLS-1$
             try {
                 return t.getBytes(charSet).length;
             } catch (UnsupportedEncodingException e) {
@@ -97,11 +109,7 @@ public class StringProvider implements M
                         MediaType mediaType,
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException, WebApplicationException {
-
-        ProviderUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
-
-        logger.debug("Writing {} to stream using {}", t, getClass().getName()); //$NON-NLS-1$
-
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
         Charset charset = Charset.forName(ProviderUtils.getCharset(mediaType));
         OutputStreamWriter writer = new OutputStreamWriter(entityStream, charset);
         BufferedWriter bw = new BufferedWriter(writer);

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBCollectionProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBCollectionProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBCollectionProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBCollectionProvider.java Sun Apr 18 22:31:14 2010
@@ -1,273 +1,273 @@
-/*******************************************************************************
- * 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.wink.common.internal.providers.entity.xml;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-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.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-
-import org.apache.wink.common.internal.i18n.Messages;
-import org.apache.wink.common.internal.utils.GenericsUtils;
-import org.apache.wink.common.utils.ProviderUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractJAXBCollectionProvider extends AbstractJAXBProvider {
-    private static final String JAXB_DEFAULT_NAMESPACE = "##default";                                           //$NON-NLS-1$
-    private static final String JAXB_DEFAULT_NAME      = "##default";                                           //$NON-NLS-1$
-    private static final Logger logger                 =
-                                                           LoggerFactory
-                                                               .getLogger(AbstractJAXBCollectionProvider.class);
-
-    public Object read(Class<?> type,
-                       Type genericType,
-                       Annotation[] annotations,
-                       MediaType mediaType,
-                       MultivaluedMap<String, String> httpHeaders,
-                       InputStream entityStream) throws IOException, WebApplicationException {
-        try {
-            XMLInputFactory xmif = XMLInputFactory.newInstance();
-            XMLStreamReader xsr = xmif.createXMLStreamReader(entityStream);
-            Class<?> theType = getParameterizedTypeClass(type, genericType, true);
-            JAXBContext context = getContext(theType, mediaType);
-            Unmarshaller unmarshaller = getJAXBUnmarshaller(type, context, mediaType);
-
-            int nextEvent = xsr.next();
-            while (nextEvent != XMLStreamReader.START_ELEMENT)
-                nextEvent = xsr.next();
-
-            List<Object> elementList = new ArrayList<Object>();
-            nextEvent = xsr.next();
-            while (nextEvent != XMLStreamReader.END_DOCUMENT) {
-                switch (nextEvent) {
-                    case XMLStreamReader.START_ELEMENT:
-                        if (getParameterizedTypeClass(type, genericType, false) == JAXBElement.class) {
-                            elementList.add(unmarshaller.unmarshal(xsr, theType));
-                        } else if (theType.isAnnotationPresent(XmlRootElement.class)) {
-                            elementList.add(unmarshaller.unmarshal(xsr));
-                        } else {
-                            elementList.add(unmarshaller.unmarshal(xsr, theType).getValue());
-                        }
-                        nextEvent = xsr.getEventType();
-                        break;
-                    default:
-                        nextEvent = xsr.next();
-                }
-            }
-
-            Object ret = null;
-            if (type.isArray())
-                ret = convertListToArray(theType, elementList);
-            else if (type == Set.class)
-                ret = new HashSet<Object>(elementList);
-            else
-                ret = elementList;
-
-            releaseJAXBUnmarshaller(context, unmarshaller);
-            return ret;
-        } catch (XMLStreamException e) {
-            logger.error(Messages.getMessage("jaxbFailToUnmarshal", type.getName()), e); // TODO //$NON-NLS-1$
-            // change
-            // message
-            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
-        } catch (JAXBException e) {
-            logger.error(Messages.getMessage("jaxbFailToUnmarshal", type.getName()), e); //$NON-NLS-1$
-            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
-        }
-    }
-
-    public void write(Object t,
-                      Class<?> type,
-                      Type genericType,
-                      Annotation[] annotations,
-                      MediaType mediaType,
-                      MultivaluedMap<String, Object> httpHeaders,
-                      OutputStream entityStream) throws IOException, WebApplicationException {
-
-        ProviderUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
-
-        try {
-            Class<?> theType = getParameterizedTypeClass(type, genericType, false);
-            Object[] elementArray = type.isArray() ? (Object[])t : ((Collection<?>)t).toArray();
-            QName qname = null;
-            boolean isJAXBElement = false;
-            if (elementArray.length > 0 && elementArray[0] instanceof JAXBElement<?>) {
-                JAXBElement<?> jaxbElement = (JAXBElement<?>)elementArray[0];
-                qname = jaxbElement.getName();
-                isJAXBElement = true;
-            } else {
-                qname = getJaxbQName(theType);
-            }
-
-            if (qname != null) {
-                writeStartTag(qname, entityStream, mediaType);
-            }
-
-            Marshaller marshaller = null;
-            JAXBContext context = null;
-            for (Object o : elementArray) {
-                if (marshaller == null) {
-                    Class<?> oType =
-                        isJAXBElement ? ((JAXBElement<?>)o).getDeclaredType() : o.getClass();
-                    context = getContext(oType, mediaType);
-                    marshaller = getJAXBMarshaller(oType, context, mediaType);
-                    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
-                    Charset charSet = getCharSet(mediaType);
-                    marshaller.setProperty(Marshaller.JAXB_ENCODING, charSet.name());
-                }
-                Object entityToMarshal = getEntityToMarshal(o, theType);
-                if (qname == null) {
-                    if (entityToMarshal instanceof JAXBElement<?>)
-                        qname = ((JAXBElement<?>)entityToMarshal).getName();
-                    else
-                        qname =
-                            new QName(entityToMarshal.getClass().getPackage().getName(),
-                                      entityToMarshal.getClass().getSimpleName());
-                    writeStartTag(qname, entityStream, mediaType);
-                }
-                marshaller.marshal(entityToMarshal, entityStream);
-                releaseJAXBMarshaller(context, marshaller);
-            }
-
-            writeEndTag(qname, entityStream);
-        } catch (JAXBException e) {
-            logger.error(Messages.getMessage("jaxbFailToMarshal", type.getName()), e); //$NON-NLS-1$
-            throw new WebApplicationException(e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected static <T> Object convertListToArray(Class<T> type, List<Object> elementList) {
-        T[] ret = (T[])Array.newInstance(type, elementList.size());
-        for (int i = 0; i < elementList.size(); ++i)
-            ret[i] = (T)elementList.get(i);
-        return ret;
-    }
-
-    protected static void writeStartTag(QName qname, OutputStream entityStream, MediaType m)
-        throws IOException {
-        String startTag = null;
-        Charset charSet = getCharSet(m);
-        startTag = "<?xml version=\"1.0\" encoding=\"" + charSet.name() + "\" standalone=\"yes\"?>"; //$NON-NLS-1$ //$NON-NLS-2$
-        entityStream.write(startTag.getBytes());
-        // if (qname.getNamespaceURI().length() > 0)
-        // startTag = "<" + qname.getLocalPart() + "s xmlns=\"" +
-        // qname.getNamespaceURI() + "\">";
-        // else
-        startTag = "<" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
-        entityStream.write(startTag.getBytes());
-    }
-
-    protected static Charset getCharSet(MediaType m) {
-        String charSetString = m.getParameters().get("charset"); //$NON-NLS-1$
-        Charset charSet =
-            charSetString == null ? Charset.forName("UTF-8") : Charset.forName(charSetString); //$NON-NLS-1$
-        return charSet;
-    }
-
-    protected static void writeEndTag(QName qname, OutputStream entityStream) throws IOException {
-        String endTag = null;
-        if (qname.getNamespaceURI().length() > 0)
-            endTag = "</" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
-        else
-            endTag = "</" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
-        entityStream.write(endTag.getBytes());
-    }
-
-    public static Class<?> getParameterizedTypeClass(Class<?> type,
-                                                     Type genericType,
-                                                     boolean recurse) {
-        if (Collection.class.isAssignableFrom(type)) {
-            if (genericType instanceof ParameterizedType) {
-                ParameterizedType parameterizedType = (ParameterizedType)genericType;
-                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
-                if (!(actualTypeArguments[0] instanceof ParameterizedType)) {
-                    return (Class<?>)actualTypeArguments[0];
-                } else {
-                    parameterizedType = (ParameterizedType)actualTypeArguments[0];
-                    if (recurse)
-                        return getParameterizedTypeClass(type, parameterizedType, recurse);
-                    else
-                        return (Class<?>)parameterizedType.getRawType();
-                }
-            } else {
-                return GenericsUtils.getGenericParamType(genericType);
-            }
-        } else if (type.isArray()) {
-            return type.getComponentType();
-        }
-        return null;
-    }
-
-    protected static QName getJaxbQName(Class<?> cls) {
-        XmlRootElement root = cls.getAnnotation(XmlRootElement.class);
-        if (root != null) {
-            String namespace = getNamespace(root.namespace());
-            String name = getLocalName(root.name(), cls.getSimpleName());
-            return new QName(namespace, name);
-        }
-        return null;
-    }
-
-    protected static String getLocalName(String name, String clsName) {
-        if (JAXB_DEFAULT_NAME.equals(name)) {
-            name = clsName;
-            if (name.length() > 1) {
-                name = name.substring(0, 1).toLowerCase() + name.substring(1);
-            } else {
-                name = name.toLowerCase();
-            }
-        }
-        return name;
-    }
-
-    protected static String getNamespace(String namespace) {
-        if (JAXB_DEFAULT_NAMESPACE.equals(namespace)) {
-            return ""; //$NON-NLS-1$
-        }
-        return namespace;
-    }
-}
+/*******************************************************************************
+ * 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.wink.common.internal.providers.entity.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+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.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.wink.common.internal.i18n.Messages;
+import org.apache.wink.common.internal.utils.GenericsUtils;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractJAXBCollectionProvider extends AbstractJAXBProvider {
+    private static final String JAXB_DEFAULT_NAMESPACE = "##default"; //$NON-NLS-1$
+    private static final String JAXB_DEFAULT_NAME      = "##default"; //$NON-NLS-1$
+    private static final Logger logger                 =
+                                                           LoggerFactory
+                                                               .getLogger(AbstractJAXBCollectionProvider.class);
+
+    public Object read(Class<?> type,
+                       Type genericType,
+                       Annotation[] annotations,
+                       MediaType mediaType,
+                       MultivaluedMap<String, String> httpHeaders,
+                       InputStream entityStream) throws IOException, WebApplicationException {
+        try {
+            XMLInputFactory xmif = XMLInputFactory.newInstance();
+            XMLStreamReader xsr = xmif.createXMLStreamReader(entityStream);
+            Class<?> theType = getParameterizedTypeClass(type, genericType, true);
+            JAXBContext context = getContext(theType, mediaType);
+            Unmarshaller unmarshaller = getJAXBUnmarshaller(type, context, mediaType);
+
+            int nextEvent = xsr.next();
+            while (nextEvent != XMLStreamReader.START_ELEMENT)
+                nextEvent = xsr.next();
+
+            List<Object> elementList = new ArrayList<Object>();
+            nextEvent = xsr.next();
+            while (nextEvent != XMLStreamReader.END_DOCUMENT) {
+                switch (nextEvent) {
+                    case XMLStreamReader.START_ELEMENT:
+                        if (getParameterizedTypeClass(type, genericType, false) == JAXBElement.class) {
+                            elementList.add(unmarshaller.unmarshal(xsr, theType));
+                        } else if (theType.isAnnotationPresent(XmlRootElement.class)) {
+                            elementList.add(unmarshaller.unmarshal(xsr));
+                        } else {
+                            elementList.add(unmarshaller.unmarshal(xsr, theType).getValue());
+                        }
+                        nextEvent = xsr.getEventType();
+                        break;
+                    default:
+                        nextEvent = xsr.next();
+                }
+            }
+
+            Object ret = null;
+            if (type.isArray())
+                ret = convertListToArray(theType, elementList);
+            else if (type == Set.class)
+                ret = new HashSet<Object>(elementList);
+            else
+                ret = elementList;
+
+            releaseJAXBUnmarshaller(context, unmarshaller);
+            return ret;
+        } catch (XMLStreamException e) {
+            logger.error(Messages.getMessage("jaxbFailToUnmarshal", type.getName()), e); // TODO //$NON-NLS-1$
+            // change
+            // message
+            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
+        } catch (JAXBException e) {
+            logger.error(Messages.getMessage("jaxbFailToUnmarshal", type.getName()), e); //$NON-NLS-1$
+            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
+        }
+    }
+
+    public void write(Object t,
+                      Class<?> type,
+                      Type genericType,
+                      Annotation[] annotations,
+                      MediaType mediaType,
+                      MultivaluedMap<String, Object> httpHeaders,
+                      OutputStream entityStream) throws IOException, WebApplicationException {
+
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+
+        try {
+            Class<?> theType = getParameterizedTypeClass(type, genericType, false);
+            Object[] elementArray = type.isArray() ? (Object[])t : ((Collection<?>)t).toArray();
+            QName qname = null;
+            boolean isJAXBElement = false;
+            if (elementArray.length > 0 && elementArray[0] instanceof JAXBElement<?>) {
+                JAXBElement<?> jaxbElement = (JAXBElement<?>)elementArray[0];
+                qname = jaxbElement.getName();
+                isJAXBElement = true;
+            } else {
+                qname = getJaxbQName(theType);
+            }
+
+            if (qname != null) {
+                writeStartTag(qname, entityStream, mediaType);
+            }
+
+            Marshaller marshaller = null;
+            JAXBContext context = null;
+            for (Object o : elementArray) {
+                if(marshaller == null) {
+                    Class<?> oType =
+                        isJAXBElement ? ((JAXBElement<?>)o).getDeclaredType() : o.getClass();
+                        context = getContext(oType, mediaType);
+                        marshaller = getJAXBMarshaller(oType, context, mediaType);
+                        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
+                        Charset charSet = getCharSet(mediaType);
+                        marshaller.setProperty(Marshaller.JAXB_ENCODING, charSet.name());
+                }
+                Object entityToMarshal = getEntityToMarshal(o, theType);
+                if (qname == null) {
+                    if (entityToMarshal instanceof JAXBElement<?>)
+                        qname = ((JAXBElement<?>)entityToMarshal).getName();
+                    else
+                        qname =
+                            new QName(entityToMarshal.getClass().getPackage().getName(),
+                                      entityToMarshal.getClass().getSimpleName());
+                    writeStartTag(qname, entityStream, mediaType);
+                }
+                marshaller.marshal(entityToMarshal, entityStream);
+                releaseJAXBMarshaller(context, marshaller);
+            }
+
+            writeEndTag(qname, entityStream);
+        } catch (JAXBException e) {
+            logger.error(Messages.getMessage("jaxbFailToMarshal", type.getName()), e); //$NON-NLS-1$
+            throw new WebApplicationException(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static <T> Object convertListToArray(Class<T> type, List<Object> elementList) {
+        T[] ret = (T[])Array.newInstance(type, elementList.size());
+        for (int i = 0; i < elementList.size(); ++i)
+            ret[i] = (T)elementList.get(i);
+        return ret;
+    }
+
+    protected static void writeStartTag(QName qname, OutputStream entityStream, MediaType m)
+        throws IOException {
+        String startTag = null;
+        Charset charSet = getCharSet(m);
+        startTag = "<?xml version=\"1.0\" encoding=\"" + charSet.name() + "\" standalone=\"yes\"?>"; //$NON-NLS-1$ //$NON-NLS-2$
+        entityStream.write(startTag.getBytes());
+        // if (qname.getNamespaceURI().length() > 0)
+        // startTag = "<" + qname.getLocalPart() + "s xmlns=\"" +
+        // qname.getNamespaceURI() + "\">";
+        // else
+        startTag = "<" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
+        entityStream.write(startTag.getBytes());
+    }
+
+    protected static Charset getCharSet(MediaType m) {
+        String charSetString = m.getParameters().get("charset"); //$NON-NLS-1$
+        Charset charSet =
+            charSetString == null ? Charset.forName("UTF-8") : Charset.forName(charSetString); //$NON-NLS-1$
+        return charSet;
+    }
+
+    protected static void writeEndTag(QName qname, OutputStream entityStream) throws IOException {
+        String endTag = null;
+        if (qname.getNamespaceURI().length() > 0)
+            endTag = "</" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
+        else
+            endTag = "</" + qname.getLocalPart() + "s>"; //$NON-NLS-1$ //$NON-NLS-2$
+        entityStream.write(endTag.getBytes());
+    }
+
+    public static Class<?> getParameterizedTypeClass(Class<?> type,
+                                                        Type genericType,
+                                                        boolean recurse) {
+        if (Collection.class.isAssignableFrom(type)) {
+            if (genericType instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType)genericType;
+                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+                if (!(actualTypeArguments[0] instanceof ParameterizedType)) {
+                    return (Class<?>)actualTypeArguments[0];
+                } else {
+                    parameterizedType = (ParameterizedType)actualTypeArguments[0];
+                    if (recurse)
+                        return getParameterizedTypeClass(type, parameterizedType, recurse);
+                    else
+                        return (Class<?>)parameterizedType.getRawType();
+                }
+            } else {
+                return GenericsUtils.getGenericParamType(genericType);
+            }
+        } else if (type.isArray()) {
+            return type.getComponentType();
+        }
+        return null;
+    }
+
+    protected static QName getJaxbQName(Class<?> cls) {
+        XmlRootElement root = cls.getAnnotation(XmlRootElement.class);
+        if (root != null) {
+            String namespace = getNamespace(root.namespace());
+            String name = getLocalName(root.name(), cls.getSimpleName());
+            return new QName(namespace, name);
+        }
+        return null;
+    }
+
+    protected static String getLocalName(String name, String clsName) {
+        if (JAXB_DEFAULT_NAME.equals(name)) {
+            name = clsName;
+            if (name.length() > 1) {
+                name = name.substring(0, 1).toLowerCase() + name.substring(1);
+            } else {
+                name = name.toLowerCase();
+            }
+        }
+        return name;
+    }
+
+    protected static String getNamespace(String namespace) {
+        if (JAXB_DEFAULT_NAMESPACE.equals(namespace)) {
+            return ""; //$NON-NLS-1$
+        }
+        return namespace;
+    }
+}

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBElementXmlProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBElementXmlProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBElementXmlProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBElementXmlProvider.java Sun Apr 18 22:31:14 2010
@@ -27,10 +27,13 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
@@ -46,6 +49,7 @@ import javax.xml.transform.stream.Stream
 
 import org.apache.wink.common.internal.i18n.Messages;
 import org.apache.wink.common.internal.model.ModelUtils;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.apache.wink.common.utils.ProviderUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -122,7 +126,7 @@ public class JAXBElementXmlProvider exte
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException, WebApplicationException {
 
-        ProviderUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
 
         try {
             Class<?> declaredType = t.getDeclaredType();

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java Sun Apr 18 22:31:14 2010
@@ -43,7 +43,7 @@ import javax.xml.bind.annotation.XmlRoot
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.wink.common.internal.i18n.Messages;
-import org.apache.wink.common.utils.ProviderUtils;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,11 +76,16 @@ public class JAXBXmlProvider extends Abs
             if (type.isAnnotationPresent(XmlRootElement.class)) {
                 unmarshaledResource = unmarshaller.unmarshal(entityStream);
                 if (unmarshaledResource instanceof JAXBElement) {
-                    // this can happen if the JAXBContext object used to create the unmarshaller
-                    // was created using the package name string instead of a class object and the
-                    // ObjectFactory has a creator method for the desired object that returns
-                    // JAXBElement.  But we know better; the 'type' param passed in here had the
-                    // XmlRootElement on it, so we know the desired return object type is NOT
+                    // this can happen if the JAXBContext object used to create
+                    // the unmarshaller
+                    // was created using the package name string instead of a
+                    // class object and the
+                    // ObjectFactory has a creator method for the desired object
+                    // that returns
+                    // JAXBElement. But we know better; the 'type' param passed
+                    // in here had the
+                    // XmlRootElement on it, so we know the desired return
+                    // object type is NOT
                     // JAXBElement, thus:
                     unmarshaledResource = ((JAXBElement)unmarshaledResource).getValue();
                 }
@@ -119,8 +124,8 @@ public class JAXBXmlProvider extends Abs
                         MediaType mediaType,
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException, WebApplicationException {
-        
-        ProviderUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
 
         try {
             if (isJAXBObject(type)) {

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/AcceptCharsetHeaderDelegate.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/AcceptCharsetHeaderDelegate.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/AcceptCharsetHeaderDelegate.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/header/AcceptCharsetHeaderDelegate.java Sun Apr 18 22:31:14 2010
@@ -34,7 +34,7 @@ public class AcceptCharsetHeaderDelegate
         List<String> banned = new LinkedList<String>();
         boolean anyAllowed = (value == null);
 
-        // parse the Accept-Encoding header
+        // parse the Accept-Charset header
         List<AcceptCharset.ValuedCharset> vCharsets = parseAcceptCharset(value);
 
         for (AcceptCharset.ValuedCharset qCharset : vCharsets) {

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java Sun Apr 18 22:31:14 2010
@@ -21,27 +21,36 @@ package org.apache.wink.common.internal.
 
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
+import java.util.Map;
 import java.util.Set;
 
+import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 
+import org.apache.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
 import org.apache.wink.common.internal.uri.UriEncoder;
+import org.apache.wink.common.utils.ProviderUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MediaTypeUtils {
 
-    public static final String         ATOM_SERVICE_DOCUMENT         = "application/atomsvc+xml"; //$NON-NLS-1$
-    public static final MediaType      ATOM_SERVICE_DOCUMENT_TYPE    =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "atomsvc+xml"); //$NON-NLS-1$
-    public static final String         ATOM_CATEGORIES_DOCUMENT      = "application/atomcat+xml"; //$NON-NLS-1$
-    public static final MediaType      ATOM_CATEGORIES_DOCUMENT_TYPE =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "atomcat+xml"); //$NON-NLS-1$
+    private static final Logger        logger                        =
+                                                                         LoggerFactory
+                                                                             .getLogger(MediaTypeUtils.class);
+
+    public static final String         ATOM_SERVICE_DOCUMENT         = "application/atomsvc+xml";                   //$NON-NLS-1$
+    public static final MediaType      ATOM_SERVICE_DOCUMENT_TYPE    = new MediaType("application", //$NON-NLS-1$
+                                                                                     "atomsvc+xml");                //$NON-NLS-1$
+    public static final String         ATOM_CATEGORIES_DOCUMENT      = "application/atomcat+xml";                   //$NON-NLS-1$
+    public static final MediaType      ATOM_CATEGORIES_DOCUMENT_TYPE = new MediaType("application", //$NON-NLS-1$
+                                                                                     "atomcat+xml");                //$NON-NLS-1$
     public static final String         ATOM_ENTRY                    =
-                                                                         "application/atom+xml;type=entry"; //$NON-NLS-1$
+                                                                         "application/atom+xml;type=entry";         //$NON-NLS-1$
     public static final MediaType      ATOM_ENTRY_TYPE               =
                                                                          new MediaType(
                                                                                        "application", //$NON-NLS-1$
@@ -51,99 +60,80 @@ public class MediaTypeUtils {
                                                                                                          "entry")); //$NON-NLS-1$
 
     public static final String         ATOM_FEED                     =
-                                                                         "application/atom+xml;type=feed"; //$NON-NLS-1$
+                                                                         "application/atom+xml;type=feed";          //$NON-NLS-1$
     public static final MediaType      ATOM_FEED_TYPE                =
                                                                          new MediaType(
                                                                                        "application", //$NON-NLS-1$
                                                                                        "atom+xml", //$NON-NLS-1$
                                                                                        Collections
                                                                                            .singletonMap("type", //$NON-NLS-1$
-                                                                                                         "feed")); //$NON-NLS-1$
+                                                                                                         "feed"));  //$NON-NLS-1$
 
-    public static final MediaType      IMAGE_X_ICON                  =
-                                                                         new MediaType("image", //$NON-NLS-1$
-                                                                                       "x-icon"); //$NON-NLS-1$
-    public static final MediaType      IMAGE_PNG                     =
-                                                                         new MediaType("image", //$NON-NLS-1$
-                                                                                       "png"); //$NON-NLS-1$
+    public static final MediaType      IMAGE_X_ICON                  = new MediaType("image", //$NON-NLS-1$
+                                                                                     "x-icon");                     //$NON-NLS-1$
+    public static final MediaType      IMAGE_PNG                     = new MediaType("image", //$NON-NLS-1$
+                                                                                     "png");                        //$NON-NLS-1$
     public static final MediaType      IMAGE_VND                     =
                                                                          new MediaType("image", //$NON-NLS-1$
-                                                                                       "vnd.microsoft.icon"); //$NON-NLS-1$
-    public static final String         IMAGE_JPEG                    = "image/jpeg"; //$NON-NLS-1$
-    public static final MediaType      IMAGE_JPEG_TYPE               =
-                                                                         new MediaType("image", //$NON-NLS-1$
-                                                                                       "jpeg"); //$NON-NLS-1$
+                                                                                       "vnd.microsoft.icon");       //$NON-NLS-1$
+    public static final String         IMAGE_JPEG                    = "image/jpeg";                                //$NON-NLS-1$
+    public static final MediaType      IMAGE_JPEG_TYPE               = new MediaType("image", //$NON-NLS-1$
+                                                                                     "jpeg");                       //$NON-NLS-1$
 
-    public static final String         UNKNOWN                       = "x-internal/unknown"; //$NON-NLS-1$
+    public static final String         UNKNOWN                       = "x-internal/unknown";                        //$NON-NLS-1$
 
-    public static final MediaType      UNKNOWN_TYPE                  =
-                                                                         new MediaType(
-                                                                                       "x-internal", //$NON-NLS-1$
-                                                                                       "unknown"); //$NON-NLS-1$
+    public static final MediaType      UNKNOWN_TYPE                  = new MediaType("x-internal", //$NON-NLS-1$
+                                                                                     "unknown");                    //$NON-NLS-1$
 
     public static final String         OPENSEARCH                    =
-                                                                         "application/opensearchdescription+xml"; //$NON-NLS-1$
+                                                                         "application/opensearchdescription+xml";   //$NON-NLS-1$
     public static final MediaType      OPENSEARCH_TYPE               =
                                                                          new MediaType(
                                                                                        "application", //$NON-NLS-1$
                                                                                        "opensearchdescription+xml"); //$NON-NLS-1$
 
-    public static final String         JAVASCRIPT                    = "application/javascript"; //$NON-NLS-1$
+    public static final String         JAVASCRIPT                    = "application/javascript";                    //$NON-NLS-1$
 
-    public static final MediaType      JAVASCRIPT_TYPE               =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "javascript"); //$NON-NLS-1$
+    public static final MediaType      JAVASCRIPT_TYPE               = new MediaType("application", //$NON-NLS-1$
+                                                                                     "javascript");                 //$NON-NLS-1$
 
-    public static final String         ECMASCRIPT                    = "application/ecmascript"; //$NON-NLS-1$
-    public static final MediaType      ECMASCRIPT_TYPE               =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "ecmascript"); //$NON-NLS-1$
+    public static final String         ECMASCRIPT                    = "application/ecmascript";                    //$NON-NLS-1$
+    public static final MediaType      ECMASCRIPT_TYPE               = new MediaType("application", //$NON-NLS-1$
+                                                                                     "ecmascript");                 //$NON-NLS-1$
+
+    public static final String         TEXT_ECMASCRIPT               = "text/ecmascript";                           //$NON-NLS-1$
+    public static final MediaType      TEXT_ECMASCRIPT_TYPE          = new MediaType("text", //$NON-NLS-1$
+                                                                                     "ecmascript");                 //$NON-NLS-1$
+    public static final String         TEXT_JAVASCRIPT               = "text/javascript";                           //$NON-NLS-1$
+
+    public static final MediaType      TEXT_JAVASCRIPT_TYPE          = new MediaType("text", //$NON-NLS-1$
+                                                                                     "javascript");                 //$NON-NLS-1$
+
+    public static final MediaType      CSV                           = new MediaType("text", "csv");                //$NON-NLS-1$ //$NON-NLS-2$
+    public static final String         PDF                           = "application/pdf";                           //$NON-NLS-1$
+    public static final MediaType      PDF_TYPE                      = new MediaType("application", //$NON-NLS-1$
+                                                                                     "pdf");                        //$NON-NLS-1$
+    public static final String         ZIP                           = "application/zip";                           //$NON-NLS-1$
+    public static final MediaType      ZIP_TYPE                      = new MediaType("application", //$NON-NLS-1$
+                                                                                     "zip");                        //$NON-NLS-1$
 
-    public static final String         TEXT_ECMASCRIPT               = "text/ecmascript"; //$NON-NLS-1$
-    public static final MediaType      TEXT_ECMASCRIPT_TYPE          =
-                                                                         new MediaType("text", //$NON-NLS-1$
-                                                                                       "ecmascript"); //$NON-NLS-1$
-    public static final String         TEXT_JAVASCRIPT               = "text/javascript"; //$NON-NLS-1$
-
-    public static final MediaType      TEXT_JAVASCRIPT_TYPE          =
-                                                                         new MediaType("text", //$NON-NLS-1$
-                                                                                       "javascript"); //$NON-NLS-1$
-
-    public static final MediaType      CSV                           = new MediaType("text", "csv"); //$NON-NLS-1$ //$NON-NLS-2$
-    public static final String         PDF                           = "application/pdf"; //$NON-NLS-1$
-    public static final MediaType      PDF_TYPE                      =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "pdf"); //$NON-NLS-1$
-    public static final String         ZIP                           = "application/zip"; //$NON-NLS-1$
-    public static final MediaType      ZIP_TYPE                      =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "zip"); //$NON-NLS-1$
-
-    public static final MediaType      MS_WORD                       =
-                                                                         new MediaType(
-                                                                                       "application", //$NON-NLS-1$
-                                                                                       "msword"); //$NON-NLS-1$
+    public static final MediaType      MS_WORD                       = new MediaType("application", //$NON-NLS-1$
+                                                                                     "msword");                     //$NON-NLS-1$
     public static final MediaType      MS_EXCEL                      =
                                                                          new MediaType(
                                                                                        "application", //$NON-NLS-1$
-                                                                                       "vnd.ms-excel"); //$NON-NLS-1$
+                                                                                       "vnd.ms-excel");             //$NON-NLS-1$
     public static final MediaType      MS_PPT                        =
                                                                          new MediaType(
                                                                                        "application", //$NON-NLS-1$
-                                                                                       "vnd.ms-powerpoint"); //$NON-NLS-1$
-    public static final String         MULTIPART_MIXED               = "multipart/mixed"; //$NON-NLS-1$
-    public static final MediaType      MULTIPART_MIXED_TYPE          =
-                                                                         new MediaType("multipart", //$NON-NLS-1$
-                                                                                       "mixed"); //$NON-NLS-1$
-
-    public static final String         MULTIPART_FORM_DATA           = "multipart/form-data"; //$NON-NLS-1$
-    public static final MediaType      MULTIPART_FORM_DATA_TYPE      =
-                                                                         new MediaType("multipart", //$NON-NLS-1$
-                                                                                       "form-data"); //$NON-NLS-1$
+                                                                                       "vnd.ms-powerpoint");        //$NON-NLS-1$
+    public static final String         MULTIPART_MIXED               = "multipart/mixed";                           //$NON-NLS-1$
+    public static final MediaType      MULTIPART_MIXED_TYPE          = new MediaType("multipart", //$NON-NLS-1$
+                                                                                     "mixed");                      //$NON-NLS-1$
+
+    public static final String         MULTIPART_FORM_DATA           = "multipart/form-data";                       //$NON-NLS-1$
+    public static final MediaType      MULTIPART_FORM_DATA_TYPE      = new MediaType("multipart", //$NON-NLS-1$
+                                                                                     "form-data");                  //$NON-NLS-1$
 
     public static final Set<MediaType> JSON_TYPES                    = createJsonTypes();
 
@@ -256,4 +246,48 @@ public class MediaTypeUtils {
 
     }
 
+    /**
+     * Given a set of response HTTP headers and a chosen media type, the method
+     * determines the best acceptable charset encoding to use.
+     * 
+     * @param httpHeaders the response HTTP headers, a Content-Type will be set
+     *            if one does not exist and if the media type does not have a
+     *            charset.
+     * @param mediaType the current media type
+     * @return the chosen media type
+     */
+    public static MediaType setDefaultCharsetOnMediaTypeHeader(MultivaluedMap<String, Object> httpHeaders,
+                                                               MediaType mediaType) {
+        logger.debug("setDefaultCharsetOnMediaTypeHeader({}, {}) entry", httpHeaders, mediaType); //$NON-NLS-1$
+
+        if (httpHeaders != null && httpHeaders.get(HttpHeaders.CONTENT_TYPE) == null) {
+            // only correct the MediaType if the MediaType was not explicitly
+            // set
+            logger
+                .debug("Media Type not explicitly set on Response so going to correct charset parameter if necessary"); //$NON-NLS-1$
+            if (ProviderUtils.getCharsetOrNull(mediaType) == null) { //$NON-NLS-1$
+                try {
+                    Map<String, String> params =
+                        new HashMap<String, String>(mediaType.getParameters());
+
+                    RuntimeContext context = RuntimeContextTLS.getRuntimeContext();
+                    HttpHeaders requestHeaders = null;
+                    if (context != null) {
+                        requestHeaders = context.getHttpHeaders();
+                    }
+                    params.put("charset", ProviderUtils.getCharset(mediaType, requestHeaders)); //$NON-NLS-1$ $NON-NLS-2$
+                    mediaType = new MediaType(mediaType.getType(), mediaType.getSubtype(), params);
+                    httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, mediaType); //$NON-NLS-1$
+                    logger
+                        .debug("Changed media type to be {} in Content-Type HttpHeader", mediaType); //$NON-NLS-1$
+                } catch (Exception e) {
+                    logger.debug("Caught exception while trying to set the charset", e); //$NON-NLS-1$
+                }
+            }
+        }
+
+        logger.debug("setDefaultCharsetOnMediaTypeHeader() exit"); //$NON-NLS-1$
+        return mediaType;
+    }
+
 }

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/utils/ProviderUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/utils/ProviderUtils.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/utils/ProviderUtils.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/utils/ProviderUtils.java Sun Apr 18 22:31:14 2010
@@ -32,8 +32,7 @@ import java.io.Writer;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.List;
 
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
@@ -43,22 +42,81 @@ import javax.ws.rs.ext.MessageBodyWriter
 import javax.ws.rs.ext.Providers;
 
 import org.apache.wink.common.internal.MultivaluedMapImpl;
+import org.apache.wink.common.internal.http.AcceptCharset;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class ProviderUtils {
-    
-    private static final Logger logger = LoggerFactory.getLogger(ProviderUtils.class);
+    private static final Logger logger          = LoggerFactory.getLogger(ProviderUtils.class);
+
+    private static final String DEFAULT_CHARSET = "UTF-8";
 
     public static String getCharsetOrNull(MediaType m) {
         String name = (m == null) ? null : m.getParameters().get("charset"); //$NON-NLS-1$
         return (name == null) ? null : name;
     }
 
-    
     public static String getCharset(MediaType m) {
+        return getCharset(m, null);
+    }
+
+    /**
+     * Returns the charset on the chosen media type or, if no charset parameter
+     * exists on the chosen media type, the most acceptable charset based on the
+     * request headers.
+     * 
+     * @param m the chosen media type
+     * @param requestHeaders the request headers to inspect
+     * @return the charset
+     */
+    public static String getCharset(MediaType m, HttpHeaders requestHeaders) {
+        logger.debug("getCharset({}, {})", m, requestHeaders);
         String name = (m == null) ? null : m.getParameters().get("charset"); //$NON-NLS-1$
-        return (name == null) ? "UTF-8" : name; //$NON-NLS-1$
+        if (name != null) {
+            logger.debug("getCharset() returning {} since parameter was set", name);
+            return name;
+        }
+        if (requestHeaders == null) {
+            logger
+                .debug("getCharset() returning {} since requestHeaders was null", DEFAULT_CHARSET);
+            return DEFAULT_CHARSET; //$NON-NLS-1$
+        }
+        AcceptCharset charsets = null;
+        List<String> acceptableCharsets =
+            requestHeaders.getRequestHeader(HttpHeaders.ACCEPT_CHARSET);
+        if (acceptableCharsets == null || acceptableCharsets.isEmpty()) {
+            // HTTP spec says that no Accept-Charset header indicates that any
+            // charset is acceptable so we'll stick with UTF-8 by default.
+            logger.debug("getCharset() returning {} since no Accept-Charset header",
+                         DEFAULT_CHARSET);
+            return DEFAULT_CHARSET; //$NON-NLS-1$
+        }
+
+        StringBuilder acceptCharsetsTemp = new StringBuilder();
+        acceptCharsetsTemp.append(acceptableCharsets.get(0));
+        for (int c = 1; c < acceptableCharsets.size(); ++c) {
+            acceptCharsetsTemp.append(","); //$NON-NLS-1$
+            acceptCharsetsTemp.append(acceptableCharsets.get(c));
+        }
+        String acceptCharsets = acceptCharsetsTemp.toString();
+        logger.debug("acceptCharsets combined value is {}", acceptCharsets);
+        charsets = AcceptCharset.valueOf(acceptCharsets);
+
+        List<String> orderedCharsets = charsets.getAcceptableCharsets();
+        logger.debug("orderedCharsets is {}", orderedCharsets);
+        if (!orderedCharsets.isEmpty()) {
+            String charset = orderedCharsets.get(0);
+            logger.debug("getCharset() returning {} since highest Accept-Charset value", charset);
+            return charset;
+        }
+        // At this point, it's either any charset is allowed (i.e. wildcard "*"
+        // has a higher quality value than any other charset sent in the
+        // Accept-Charset header), or we only have banned charsets. If there are
+        // any banned charsets, then technically we should pick a non-banned
+        // charset.
+        logger.debug("getCharset() returning {} since no explicit charset required",
+                     DEFAULT_CHARSET);
+        return DEFAULT_CHARSET; //$NON-NLS-1$
     }
 
     public static Reader createReader(InputStream stream, MediaType mediaType) {
@@ -178,23 +236,4 @@ public class ProviderUtils {
         }
         return reader.readFrom(type, genericType, new Annotation[0], mediaType, httpHeaders, is);
     }
-    
-    public static void setDefaultCharsetOnMediaTypeHeader(MultivaluedMap<String, Object> httpHeaders, MediaType mediaType) {
-        if (httpHeaders != null && httpHeaders.get(HttpHeaders.CONTENT_TYPE) == null) {
-            // only correct the MediaType if the MediaType was not explicitly set
-            logger.debug("Media Type not explicitly set on Response so going to correct charset parameter if necessary"); //$NON-NLS-1$
-            if (getCharsetOrNull(mediaType) == null) { //$NON-NLS-1$
-                try {
-                    Map<String, String> params = new HashMap<String, String>(mediaType.getParameters());
-                    params.put("charset", "UTF-8"); //$NON-NLS-1$ $NON-NLS-2$
-                    httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, new MediaType(mediaType
-                            .getType(), mediaType.getSubtype(), params)); //$NON-NLS-1$
-                    logger.debug("Added charset=UTF-8 parameter to Content-Type HttpHeader"); //$NON-NLS-1$
-                } catch (Exception e) {
-                    logger.debug("Caught exception while trying to set the charset", e); //$NON-NLS-1$
-                }
-            }
-        }
-
-    }
 }

Modified: incubator/wink/trunk/wink-providers/wink-jettison-provider/src/main/java/org/apache/wink/providers/jettison/JettisonJAXBElementProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-providers/wink-jettison-provider/src/main/java/org/apache/wink/providers/jettison/JettisonJAXBElementProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-providers/wink-jettison-provider/src/main/java/org/apache/wink/providers/jettison/JettisonJAXBElementProvider.java (original)
+++ incubator/wink/trunk/wink-providers/wink-jettison-provider/src/main/java/org/apache/wink/providers/jettison/JettisonJAXBElementProvider.java Sun Apr 18 22:31:14 2010
@@ -26,6 +26,7 @@ import java.io.OutputStreamWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.nio.charset.Charset;
 import java.util.HashMap;
 
 import javax.ws.rs.Consumes;
@@ -50,6 +51,7 @@ import javax.xml.transform.stream.Stream
 
 import org.apache.wink.common.internal.i18n.Messages;
 import org.apache.wink.common.internal.providers.entity.xml.AbstractJAXBProvider;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.apache.wink.common.utils.ProviderUtils;
 import org.codehaus.jettison.badgerfish.BadgerFishXMLInputFactory;
 import org.codehaus.jettison.badgerfish.BadgerFishXMLStreamWriter;
@@ -180,11 +182,13 @@ public class JettisonJAXBElementProvider
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException, WebApplicationException {
         try {
+            mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+
             Class<?> declaredType = t.getDeclaredType();
             JAXBContext context = getContext(declaredType, mediaType);
             Marshaller marshaller = getJAXBMarshaller(declaredType, context, mediaType);
-            OutputStreamWriter writer =
-                new OutputStreamWriter(entityStream, ProviderUtils.getCharset(mediaType));
+            Charset charset = Charset.forName(ProviderUtils.getCharset(mediaType));
+            OutputStreamWriter writer = new OutputStreamWriter(entityStream, charset);
 
             XMLStreamWriter xsw = null;
             if (isBadgerFishConventionUsed) {

Modified: incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonArrayProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonArrayProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonArrayProvider.java (original)
+++ incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonArrayProvider.java Sun Apr 18 22:31:14 2010
@@ -25,6 +25,7 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.nio.charset.Charset;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
@@ -82,6 +83,8 @@ public class JsonArrayProvider implement
                         MediaType mediaType,
                         MultivaluedMap<String, Object> httpHeaders,
                         OutputStream entityStream) throws IOException, WebApplicationException {
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+
         String jsonString = null;
         try {
             jsonString = t.toString(2);
@@ -97,8 +100,9 @@ public class JsonArrayProvider implement
         } catch (Exception e) {
             logger.debug("Could not get the URI callback param", e);
         }
-        OutputStreamWriter writer =
-            new OutputStreamWriter(entityStream, ProviderUtils.getCharset(mediaType));
+
+        Charset charset = Charset.forName(ProviderUtils.getCharset(mediaType));
+        OutputStreamWriter writer = new OutputStreamWriter(entityStream, charset);
         if (callbackParam != null) {
             writer.write(callbackParam);
             writer.write("(");

Modified: incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonJAXBProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonJAXBProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonJAXBProvider.java (original)
+++ incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonJAXBProvider.java Sun Apr 18 22:31:14 2010
@@ -98,6 +98,8 @@ public class JsonJAXBProvider implements
                         OutputStream entityStream) throws IOException, WebApplicationException {
 
         try {
+            mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+
             @SuppressWarnings("unchecked")
             MessageBodyWriter<Object> jaxbWriter =
                 (MessageBodyWriter<Object>)providers

Modified: incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonProvider.java?rev=935425&r1=935424&r2=935425&view=diff
==============================================================================
--- incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonProvider.java (original)
+++ incubator/wink/trunk/wink-providers/wink-json-provider/src/main/java/org/apache/wink/providers/json/JsonProvider.java Sun Apr 18 22:31:14 2010
@@ -26,6 +26,7 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.nio.charset.Charset;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
@@ -97,8 +98,10 @@ public class JsonProvider implements Mes
         } catch (Exception e) {
             logger.debug("Could not get the URI callback param", e); //$NON-NLS-1$
         }
+        mediaType = MediaTypeUtils.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType);
+        Charset charset = Charset.forName(ProviderUtils.getCharset(mediaType));
         OutputStreamWriter writer =
-            new OutputStreamWriter(entityStream, ProviderUtils.getCharset(mediaType));
+            new OutputStreamWriter(entityStream, charset);
         if (callbackParam != null) {
             writer.write(callbackParam);
             writer.write("("); //$NON-NLS-1$



Mime
View raw message