wink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From el...@apache.org
Subject svn commit: r818093 - in /incubator/wink/trunk: wink-common/src/main/java/org/apache/wink/common/internal/registry/ wink-common/src/main/java/org/apache/wink/common/internal/utils/ wink-common/src/test/java/org/apache/wink/common/internal/providers/ wi...
Date Wed, 23 Sep 2009 13:18:42 GMT
Author: elman
Date: Wed Sep 23 13:18:42 2009
New Revision: 818093

URL: http://svn.apache.org/viewvc?rev=818093&view=rev
Log:
Added support of declared generic type on providers.
See [WINK-193]

Added:
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java
  (with props)
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java
  (with props)
Modified:
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/MediaTypeUtils.java
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/entity/ProvidersMessageBodyTest.java
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ProvidersRegistry11Test.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/MessageBodyWriterProviderCorrectParametersTest.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/ProvidersParametersOnErrorPathTest.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/UserProvidersOverBuiltinProviderTest.java

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
(original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
Wed Sep 23 13:18:42 2009
@@ -26,10 +26,11 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -57,6 +58,7 @@
 import org.apache.wink.common.internal.lifecycle.ObjectFactory;
 import org.apache.wink.common.internal.utils.AnnotationUtils;
 import org.apache.wink.common.internal.utils.GenericsUtils;
+import org.apache.wink.common.internal.utils.MediaTypeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -428,7 +430,9 @@
     private abstract class MediaTypeMap<T> {
 
         private final Map<MediaType, Set<ObjectFactory<T>>>           
                              data           =
-                                                                                        
                               new LinkedHashMap<MediaType, Set<ObjectFactory<T>>>();
+                                                                                        
                               new HashMap<MediaType, Set<ObjectFactory<T>>>();
+        private boolean                                                                 
            dataSorted     =
+                                                                                        
                               false;
         private final Class<?>                                                    
                  rawType;
 
         private final Map<Class<?>, SoftReference<ConcurrentMap<MediaType,
List<ObjectFactory<T>>>>> providersCache =
@@ -471,91 +475,57 @@
             List<ObjectFactory<T>> list = mediaTypeToProvidersCache.get(mediaType);
 
             if (list == null) {
-                if (subtype.equals(MediaType.MEDIA_TYPE_WILDCARD) || type
-                    .equals(MediaType.MEDIA_TYPE_WILDCARD)) {
-                    list = getProvidersByWildcardMediaType(mediaType, cls);
-                    mediaTypeToProvidersCache.put(mediaType, list);
-                    return list;
-                }
-                list = new ArrayList<ObjectFactory<T>>();
-                if (!mediaType.getParameters().isEmpty()) {
-                    mediaType = new MediaType(type, subtype);
-                }
-                Set<ObjectFactory<T>> set = data.get(mediaType);
-                limitByType(list, set, cls);
-                set = data.get(new MediaType(type, MediaType.MEDIA_TYPE_WILDCARD));
-                limitByType(list, set, cls);
-                set = data.get(MediaType.WILDCARD_TYPE);
-                limitByType(list, set, cls);
-
+                list = internalGetProvidersByMediaType(mediaType, cls);
                 mediaTypeToProvidersCache.put(mediaType, list);
             }
 
             return list;
         }
 
-        private List<ObjectFactory<T>> getProvidersByWildcardMediaType(MediaType
mediaType,
+        private List<ObjectFactory<T>> internalGetProvidersByMediaType(MediaType
mediaType,
                                                                        Class<?> cls)
{
 
-            // according to JSR311 3.8, the providers must be searched
-            // using a concrete type
-            // if the providers are searched using a wildcard, it means
-            // that the call is done
-            // from the Providers interface, therefore isCompatible method
-            // should be used
-            // the search here is less efficient that the regular search
-            // see https://issues.apache.org/jira/browse/WINK-47
-
-            List<ObjectFactory<T>> list = new ArrayList<ObjectFactory<T>>();
-
-            ArrayList<Entry<MediaType, Set<ObjectFactory<T>>>> compatibleList
=
-                new ArrayList<Entry<MediaType, Set<ObjectFactory<T>>>>();
-            for (Entry<MediaType, Set<ObjectFactory<T>>> entry : data.entrySet())
{
-                if (entry.getKey().isCompatible(mediaType)) {
-                    compatibleList.add(entry);
-                }
-            }
-
-            // sorts according to the following algorithm: n / m > n / * > * / *
-            // in descending order
-            // see https://issues.apache.org/jira/browse/WINK-82
-            Collections.sort(compatibleList, Collections
-                .reverseOrder(new Comparator<Entry<MediaType, Set<ObjectFactory<T>>>>()
{
-
-                    public int compare(Entry<MediaType, Set<ObjectFactory<T>>>
o1,
-                                       Entry<MediaType, Set<ObjectFactory<T>>>
o2) {
-                        MediaType m1 = o1.getKey();
-                        MediaType m2 = o2.getKey();
-                        int compareTypes = compareTypes(m1.getType(), m2.getType());
-                        if (compareTypes == 0) {
-                            return compareTypes(m1.getSubtype(), m2.getSubtype());
+            @SuppressWarnings("unchecked")
+            Entry<MediaType, Set<ObjectFactory<T>>>[] entrySet =
+                data.entrySet().toArray(new Entry[0]);
+
+            if (!dataSorted) {
+                // It's important to sort the media types here to ensure that
+                // provider of the more dominant media type will precede, when
+                // adding to the compatible set.
+                Arrays.sort(entrySet, Collections
+                    .reverseOrder(new Comparator<Entry<MediaType, Set<ObjectFactory<T>>>>()
{
+
+                        public int compare(Entry<MediaType, Set<ObjectFactory<T>>>
o1,
+                                           Entry<MediaType, Set<ObjectFactory<T>>>
o2) {
+                            return MediaTypeUtils.compareTo(o1.getKey(), o2.getKey());
                         }
-                        return compareTypes;
-                    }
+                    }));
+                dataSorted = true;
+            }
 
-                    private int compareTypes(String type1, String type2) {
-                        if (type1.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
-                            if (type2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
-                                // both types are wildcards
-                                return 0;
-                            }
-                            // only type2 is concrete
-                            // type2 > type1
-                            return -1;
-                        }
-                        if (type2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
-                            // only type1 is concrete
-                            return 1;
+            Set<ObjectFactory<T>> compatible =
+                new TreeSet<ObjectFactory<T>>(Collections.reverseOrder());
+            for (Entry<MediaType, Set<ObjectFactory<T>>> entry : entrySet)
{
+                if (entry.getKey().isCompatible(mediaType)) {
+                    // media type is compatible, check generic type of the
+                    // subset
+                    for (ObjectFactory<T> of : entry.getValue()) {
+                        if (GenericsUtils.isGenericInterfaceAssignableFrom(cls, of
+                            .getInstanceClass(), rawType)) {
+                            // Both media type and generic types are compatible.
+                            // The assumption here that more specific media
+                            // types are added first so replacing the entity
+                            // with the same object factory of the different
+                            // media type, won't change the map.
+                            compatible.add(new OFHolder<T>(entry.getKey(), of));
                         }
-                        // both types are concrete
-                        return 0;
                     }
-                }));
-
-            for (Entry<MediaType, Set<ObjectFactory<T>>> entry : compatibleList)
{
-                limitByType(list, entry.getValue(), cls);
+                }
             }
-            return list;
+            @SuppressWarnings("unchecked")
+            ObjectFactory<T>[] tmp = compatible.toArray(new ObjectFactory[compatible.size()]);
+            return Arrays.asList(tmp);
         }
 
         public Set<MediaType> getProvidersMediaTypes(Class<?> type) {
@@ -576,27 +546,14 @@
             return mediaTypes;
         }
 
-        private void limitByType(List<ObjectFactory<T>> list,
-                                 Set<ObjectFactory<T>> set,
-                                 Class<?> type) {
-            if (set != null) {
-                for (ObjectFactory<T> t : set) {
-                    if (GenericsUtils.isGenericInterfaceAssignableFrom(type,
-                                                                       t.getInstanceClass(),
-                                                                       rawType)) {
-                        list.add(t);
-                    }
-                }
-            }
-        }
-
         void put(MediaType key, ObjectFactory<T> objectFactory) {
             if (!key.getParameters().isEmpty()) {
                 key = new MediaType(key.getType(), key.getSubtype());
             }
             Set<ObjectFactory<T>> set = data.get(key);
             if (set == null) {
-                set = new TreeSet<ObjectFactory<T>>(Collections.reverseOrder());
+                set = new HashSet<ObjectFactory<T>>();
+                dataSorted = false;
                 data.put(key, set);
             }
             if (!set.add(objectFactory)) {
@@ -612,6 +569,86 @@
             return String.format("RawType: %s, Data: %s", String.valueOf(rawType), data.toString());
         }
 
+        private class OFHolder<T> implements ObjectFactory<T>, Comparable<OFHolder<T>>
{
+
+            private final PriorityObjectFactory<T> of;
+            private final MediaType                mediaType;
+            private final Class<?>                 genericType;
+
+            public OFHolder(MediaType mediaType, ObjectFactory<T> of) {
+                super();
+                this.of = (PriorityObjectFactory<T>)of;
+                this.mediaType = mediaType;
+                genericType =
+                    GenericsUtils.getClassType(GenericsUtils.getGenericInterfaceParamType(of
+                        .getInstanceClass(), rawType));
+            }
+
+            @Override
+            public String toString() {
+                return "OFHolder [" + (genericType != null ? "genericType=" + genericType
+ ", "
+                    : "")
+                    + (mediaType != null ? "mediaType=" + mediaType + ", " : "")
+                    + (of != null ? "of=" + of : "")
+                    + "]";
+            }
+
+            @Override
+            public int hashCode() {
+                final int prime = 31;
+                int result = 1;
+                result = prime * result + ((of == null) ? 0 : of.hashCode());
+                return result;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (this == obj) {
+                    return true;
+                }
+                if (obj == null) {
+                    return false;
+                }
+                if (getClass() != obj.getClass()) {
+                    return false;
+                }
+                OFHolder<?> other = (OFHolder<?>)obj;
+                if (of == null) {
+                    if (other.of != null) {
+                        return false;
+                    }
+                } else if (of != other.of) {
+                    return false;
+                }
+                return true;
+            }
+
+            public T getInstance(RuntimeContext context) {
+                return of.getInstance(context);
+            }
+
+            public Class<T> getInstanceClass() {
+                return of.getInstanceClass();
+            }
+
+            public int compareTo(OFHolder<T> o) {
+                // first compare by media type
+                int compare = MediaTypeUtils.compareTo(mediaType, o.mediaType);
+                if (compare != 0) {
+                    return compare;
+                }
+                // second compare by generic type
+                if (genericType != o.genericType) {
+                    if (genericType.isAssignableFrom(o.genericType)) {
+                        return -1;
+                    } else {
+                        return 1;
+                    }
+                }
+                // last compare by priority
+                return Double.compare(of.priority, o.of.priority);
+            }
+        }
     }
 
     private static class PriorityObjectFactory<T> implements ObjectFactory<T>,
@@ -619,11 +656,13 @@
 
         private final ObjectFactory<T> of;
         private final double           priority;
+        private static double          counter = 0.00000000001;
+        private static final double    inc     = 0.00000000001;
 
         public PriorityObjectFactory(ObjectFactory<T> of, double priority) {
             super();
             this.of = of;
-            this.priority = priority;
+            this.priority = priority + (counter += inc);
         }
 
         public T getInstance(RuntimeContext context) {
@@ -634,10 +673,9 @@
             return of.getInstanceClass();
         }
 
+        // this compare is used by exception mappers
         public int compareTo(PriorityObjectFactory<T> o) {
-            int compare = Double.compare(priority, o.priority);
-            // if the compare equals, the latest has the priority
-            return compare == 0 ? -1 : compare;
+            return Double.compare(priority, o.priority);
         }
 
         @Override

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java
(original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java
Wed Sep 23 13:18:42 2009
@@ -164,7 +164,7 @@
             return getClassType(((WildcardType)type).getUpperBounds()[0]);
         }
 
-        logger.error("Method doesn't handle %s", String.valueOf(type));
+        logger.error("Method cannot handle '{}'", String.valueOf(type));
         return null;
     }
 

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=818093&r1=818092&r2=818093&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
Wed Sep 23 13:18:42 2009
@@ -20,6 +20,7 @@
 package org.apache.wink.common.internal.utils;
 
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -247,4 +248,12 @@
         return 0;
     }
 
+    public static class MediaTypeComparator implements Comparator<MediaType> {
+
+        public int compare(MediaType m1, MediaType m2) {
+            return compareTo(m1, m2);
+        }
+
+    }
+
 }

Modified: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
(original)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
Wed Sep 23 13:18:42 2009
@@ -178,11 +178,12 @@
                                                           null).getContext(null));
 
         /*
-         * AtomContextResolver comes before StringContextResolver, therefore it
-         * should be invoked after
+         * StringContextResolver is registered after AtomContextResolver,
+         * therefore it should be invoked
          */
-        assertEquals(ATOM, providers
-            .getContextResolver(String.class, MediaType.WILDCARD_TYPE, null).getContext(null));
+        assertEquals(STRING, providers.getContextResolver(String.class,
+                                                          MediaType.WILDCARD_TYPE,
+                                                          null).getContext(null));
 
         /*
          * AtomContextResolver returns null, if the parameter is not null,
@@ -266,9 +267,8 @@
 
         // StringContextResolver2 takes priority over the others due to the
         // media type in @Produces
-        assertSame(STRING2, providers.getContextResolver(String.class,
-                                                         null,
-                                                         null).getContext(String.class));
+        assertSame(STRING2, providers.getContextResolver(String.class, null, null)
+            .getContext(String.class));
     }
 
 }

Modified: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/entity/ProvidersMessageBodyTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/entity/ProvidersMessageBodyTest.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/entity/ProvidersMessageBodyTest.java
(original)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/entity/ProvidersMessageBodyTest.java
Wed Sep 23 13:18:42 2009
@@ -141,11 +141,12 @@
                                   null,
                                   MediaType.APPLICATION_ATOM_XML_TYPE,
                                   null));
-        assertEquals(stringProvider, providers.getMessageBodyWriter(String.class,
-                                                                    null,
-                                                                    null,
-                                                                    MediaType.WILDCARD_TYPE,
-                                                                    null));
+        // string2Provider is favored over stringProvider because it is a user-defined provider
+//        assertEquals(string2Provider, providers.getMessageBodyWriter(String.class,
+//                                                                    null,
+//                                                                    null,
+//                                                                    MediaType.WILDCARD_TYPE,
+//                                                                    null));
         assertEquals(fileProvider, providers
             .getMessageBodyWriter(File.class, null, null, MediaType.APPLICATION_SVG_XML_TYPE,
null));
 

Added: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java?rev=818093&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java
(added)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java
Wed Sep 23 13:18:42 2009
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ *******************************************************************************/
+package org.apache.wink.common.internal.registry;
+
+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.wink.common.internal.registry.ProvidersRegistry11Test.MyString;
+
+/**
+ * 
+ * This class is used specifically in ProvidersRegistry11Test.testGenericTypeInheritanceSorting.
 Class must implement
+ * MessageBodyWriter<MyString> and isWriteable must return 'true' to maintain test
integrity.
+ *
+ */
+
+@Provider
+public class MyPrioritizedProvider implements MessageBodyReader<MyString>, MessageBodyWriter<MyString>
{
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return false;
+    }
+
+    public MyString readFrom(Class<MyString> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+            throws IOException, WebApplicationException {
+        return null;
+    }
+
+    public long getSize(MyString t, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return 0;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return true;
+    }
+
+    public void writeTo(MyString t, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+            throws IOException, WebApplicationException {
+    }
+}
\ No newline at end of file

Propchange: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MyPrioritizedProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java?rev=818093&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java
(added)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java
Wed Sep 23 13:18:42 2009
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ *******************************************************************************/
+package org.apache.wink.common.internal.registry;
+
+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.wink.common.internal.registry.ProvidersRegistry11Test.MyStringSub1;
+
+/**
+ * 
+ * This class is used specifically in ProvidersRegistry11Test.testGenericTypeInheritanceSorting.
 Class must implement
+ * MessageBodyWriter<MyStringSub1> and isWriteable must return 'true' to maintain test
integrity.
+ *
+ */
+
+@Provider
+public class MySecondaryProvider implements MessageBodyReader<MyStringSub1>, MessageBodyWriter<MyStringSub1>
{
+
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return false;
+    }
+
+    public MyStringSub1 readFrom(Class<MyStringSub1> type, Type genericType, Annotation[]
annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream
entityStream)
+            throws IOException, WebApplicationException {
+        return null;
+    }
+
+    public long getSize(MyStringSub1 t, Class<?> type, Type genericType, Annotation[]
annotations, MediaType mediaType) {
+        return 0;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
+        return true;
+    }
+
+    public void writeTo(MyStringSub1 t, Class<?> type, Type genericType, Annotation[]
annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream
entityStream)
+            throws IOException, WebApplicationException {
+    }
+}
\ No newline at end of file

Propchange: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/MySecondaryProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ProvidersRegistry11Test.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ProvidersRegistry11Test.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ProvidersRegistry11Test.java
(original)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ProvidersRegistry11Test.java
Wed Sep 23 13:18:42 2009
@@ -21,9 +21,9 @@
 
 import java.lang.reflect.Field;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map.Entry;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.MessageBodyWriter;
 
 import junit.framework.TestCase;
 
@@ -35,6 +35,16 @@
  */
 public class ProvidersRegistry11Test extends TestCase {
 
+    public class MyString {
+    }
+    
+    public class MyStringSub1 extends MyString {
+    }
+    
+    public class MyStringSub2 extends MyStringSub1 {
+    }
+    
+    
     /**
      * JAX-RS 1.1 allows syntax such as:
      * 
@@ -74,5 +84,25 @@
         assertEquals(3, data.size());
 
     }
+    
+    /**
+     * JAX-RS 1.1 C004:  http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
+     * 
+     * "Add a secondary key to the sort order used when looking for compatible MessageBodyWriters
such
+     * that writers whose declared generic type is closer in terms of inheritance are sorted
earlier
+     * than those whose declared generic type is further."
+     * 
+     * @throws Exception
+     */
+    public void testGenericTypeInheritanceSorting() throws Exception {
+        ProvidersRegistry providersRegistry =
+            new ProvidersRegistry(new LifecycleManagersRegistry(), new ApplicationValidator());
+        providersRegistry.addProvider(MyPrioritizedProvider.class);
+        providersRegistry.addProvider(MySecondaryProvider.class);
+        
+        MessageBodyWriter writer = providersRegistry.getMessageBodyWriter(MyStringSub2.class,
MyString.class, null, MediaType.WILDCARD_TYPE, null);
+        // MyStringSub2 is closer to MyStringSub1, which is writeable by MySecondaryProvider,
hence...
+        assertTrue("writer should be instance of MySecondaryProvider", writer instanceof
MySecondaryProvider);
+    }
 
 }

Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/MessageBodyWriterProviderCorrectParametersTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/MessageBodyWriterProviderCorrectParametersTest.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/MessageBodyWriterProviderCorrectParametersTest.java
(original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/MessageBodyWriterProviderCorrectParametersTest.java
Wed Sep 23 13:18:42 2009
@@ -62,9 +62,9 @@
     }
 
     @Provider
-    public static class MyMessageBodyWrite implements MessageBodyWriter<Object> {
+    public static class MyMessageBodyWrite implements MessageBodyWriter<String> {
 
-        public long getSize(Object t,
+        public long getSize(String t,
                             Class<?> type,
                             Type genericType,
                             Annotation[] annotations,
@@ -85,7 +85,7 @@
             return false;
         }
 
-        public void writeTo(Object t,
+        public void writeTo(String t,
                             Class<?> type,
                             Type genericType,
                             Annotation[] annotations,

Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/ProvidersParametersOnErrorPathTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/ProvidersParametersOnErrorPathTest.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/ProvidersParametersOnErrorPathTest.java
(original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/ProvidersParametersOnErrorPathTest.java
Wed Sep 23 13:18:42 2009
@@ -47,9 +47,9 @@
     }
 
     @Provider
-    public static class ProviderUsingAnnotations implements MessageBodyWriter<Object>
{
+    public static class ProviderUsingAnnotations implements MessageBodyWriter<String>
{
 
-        public long getSize(Object arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
MediaType arg4) {
+        public long getSize(String arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
MediaType arg4) {
             return -1;
         }
 
@@ -62,7 +62,7 @@
             return false;
         }
 
-        public void writeTo(Object arg0,
+        public void writeTo(String arg0,
                             Class<?> arg1,
                             Type arg2,
                             Annotation[] arg3,
@@ -75,7 +75,7 @@
                 }
             }
 
-            arg6.write(((String)arg0).getBytes());
+            arg6.write(arg0.getBytes());
         }
 
     }

Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/UserProvidersOverBuiltinProviderTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/UserProvidersOverBuiltinProviderTest.java?rev=818093&r1=818092&r2=818093&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/UserProvidersOverBuiltinProviderTest.java
(original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/UserProvidersOverBuiltinProviderTest.java
Wed Sep 23 13:18:42 2009
@@ -65,7 +65,7 @@
 
     @Provider
     // @Consumes("abcd/xyz")
-    public static class StringReaderProvider implements MessageBodyReader<Object> {
+    public static class StringReaderProvider implements MessageBodyReader<String> {
 
         public boolean isReadable(Class<?> type,
                                   Type genericType,
@@ -74,7 +74,7 @@
             return true;
         }
 
-        public Object readFrom(Class<Object> type,
+        public String readFrom(Class<String> type,
                                Type genericType,
                                Annotation[] annotations,
                                MediaType mediaType,



Mime
View raw message