You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by lr...@apache.org on 2011/02/16 18:43:57 UTC

svn commit: r1071325 [1/2] - in /incubator/wink/trunk: wink-client/src/main/java/org/apache/wink/client/ wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/ wink-common/src/main/java/org/apache/wink/common/internal/registry/ win...

Author: lresende
Date: Wed Feb 16 17:43:56 2011
New Revision: 1071325

URL: http://svn.apache.org/viewvc?rev=1071325&view=rev
Log:
WINK-334 - Applying patch from Raymong Feng to enhance support for java generics

Added:
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeFactory.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeParser.java   (with props)
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeReference.java   (with props)
Modified:
    incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/EntityType.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/AssetProvider.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/InjectableFactory.java
    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/registry/metadata/ProviderMetadataCollector.java
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/utils/GenericsUtils.java
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/utils/GenericsUtilsTest.java

Modified: incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/EntityType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/EntityType.java?rev=1071325&r1=1071324&r2=1071325&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/EntityType.java (original)
+++ incubator/wink/trunk/wink-client/src/main/java/org/apache/wink/client/EntityType.java Wed Feb 16 17:43:56 2011
@@ -65,7 +65,7 @@ public class EntityType<T> {
 					.getMessage("entityTypeMustBeParameterized")); //$NON-NLS-1$
 		}
 		this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
-		this.cls = (Class<T>) GenericsUtils.getClassType(type);
+		this.cls = (Class<T>) GenericsUtils.getClassType(type, this.getClass());
 	}
 
 	public Type getType() {

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/AssetProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/AssetProvider.java?rev=1071325&r1=1071324&r2=1071325&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/AssetProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/AssetProvider.java Wed Feb 16 17:43:56 2011
@@ -49,8 +49,8 @@ import org.apache.wink.common.annotation
 import org.apache.wink.common.annotations.Scope.ScopeType;
 import org.apache.wink.common.internal.i18n.Messages;
 import org.apache.wink.common.internal.registry.Injectable;
-import org.apache.wink.common.internal.registry.InjectableFactory;
 import org.apache.wink.common.internal.registry.Injectable.ParamType;
+import org.apache.wink.common.internal.registry.InjectableFactory;
 import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
 import org.apache.wink.common.internal.utils.AnnotationUtils;
 import org.apache.wink.common.internal.utils.GenericsUtils;
@@ -419,7 +419,7 @@ public class AssetProvider implements Me
         public ProducesMethod(Method method, MediaType mediaType) {
             super(method, mediaType);
             this.type = method.getGenericReturnType();
-            this.typeClass = GenericsUtils.getClassType(type);
+            this.typeClass = GenericsUtils.getClassType(type, method.getDeclaringClass());
         }
     }
 

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/InjectableFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/InjectableFactory.java?rev=1071325&r1=1071324&r2=1071325&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/InjectableFactory.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/InjectableFactory.java Wed Feb 16 17:43:56 2011
@@ -38,7 +38,7 @@ import javax.ws.rs.core.Context;
 
 import org.apache.wink.common.RuntimeContext;
 import org.apache.wink.common.internal.i18n.Messages;
-import org.apache.wink.common.internal.utils.GenericsUtils;
+import org.apache.wink.common.internal.type.TypeFactory;
 
 public class InjectableFactory {
 
@@ -75,7 +75,8 @@ public class InjectableFactory {
                              Member member,
                              boolean encoded,
                              String defaultValue) {
-        Class<?> classType = GenericsUtils.getClassType(genericType);
+        Class<?> classType = TypeFactory.type(genericType, member.getDeclaringClass()).getRawClass();
+        // Class<?> classType = GenericsUtils.getClassType(genericType);
 
         MatrixParam matrix = null;
         PathParam path = null;

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=1071325&r1=1071324&r2=1071325&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 Feb 16 17:43:56 2011
@@ -33,9 +33,9 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.Map.Entry;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
@@ -349,7 +349,7 @@ public class ProvidersRegistry {
             Type genericType =
                 GenericsUtils.getGenericInterfaceParamType(exceptionMapper.getClass(),
                                                            ExceptionMapper.class);
-            Class<?> classType = GenericsUtils.getClassType(genericType);
+            Class<?> classType = GenericsUtils.getClassType(genericType, null);
             if (classType.isAssignableFrom(type)) {
                 matchingMappers.add(exceptionMapper);
             }
@@ -368,8 +368,8 @@ public class ProvidersRegistry {
             Type second =
                 GenericsUtils.getGenericInterfaceParamType(matchingMappers.get(1).getClass(),
                                                            ExceptionMapper.class);
-            Class<?> firstClass = GenericsUtils.getClassType(first);
-            Class<?> secondClass = GenericsUtils.getClassType(second);
+            Class<?> firstClass = GenericsUtils.getClassType(first, null);
+            Class<?> secondClass = GenericsUtils.getClassType(second, null);
             if (firstClass == secondClass) {
                 // the first one has higher priority, so remove the second
                 // one for the same classes!
@@ -920,7 +920,7 @@ public class ProvidersRegistry {
                 this.isSystemProvider = isSystemProvider;
                 genericType =
                     GenericsUtils.getClassType(GenericsUtils.getGenericInterfaceParamType(of
-                        .getInstanceClass(), rawType));
+                        .getInstanceClass(), rawType), rawType);
             }
 
             @Override
@@ -1080,7 +1080,7 @@ public class ProvidersRegistry {
             if (t == null) {
                 this.genericType = Object.class;
             } else {
-                this.genericType = GenericsUtils.getClassType(t);
+                this.genericType = GenericsUtils.getClassType(t, providerClass);
             }
         }
 

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ProviderMetadataCollector.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ProviderMetadataCollector.java?rev=1071325&r1=1071324&r2=1071325&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ProviderMetadataCollector.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/metadata/ProviderMetadataCollector.java Wed Feb 16 17:43:56 2011
@@ -120,7 +120,7 @@ public class ProviderMetadataCollector e
         Context context = field.getAnnotation(Context.class);
         if (context != null) {
             return InjectableFactory.getInstance().createContextParam(GenericsUtils
-                                                                          .getClassType(fieldType),
+                                                                          .getClassType(fieldType, ((Member) field).getDeclaringClass()),
                                                                       field.getAnnotations(),
                                                                       (Member)field);
         }

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,230 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.Array;
+
+/**
+ * Array types represent Java arrays, both primitive and object valued.
+ * Further, Object-valued arrays can have element type of any other
+ * legal {@link JavaType}.
+ */
+public final class ArrayType extends TypeBase {
+    /**
+     * Type of elements in the array.
+     */
+    final JavaType _componentType;
+
+    /**
+     * We will also keep track of shareable instance of empty array,
+     * since it usually needs to be constructed any way; and because
+     * it is essentially immutable and thus can be shared.
+     */
+    final Object _emptyArray;
+
+    private ArrayType(JavaType componentType, Object emptyInstance) {
+        super(emptyInstance.getClass(), componentType.hashCode());
+        _componentType = componentType;
+        _emptyArray = emptyInstance;
+    }
+
+    public static ArrayType construct(JavaType componentType) {
+        /* This is bit messy: there is apparently no other way to
+         * reconstruct actual concrete/raw array class from component
+         * type, than to construct an instance, get class (same is
+         * true for GenericArracyType as well; hence we won't bother
+         * passing that in).
+         */
+        Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
+        return new ArrayType(componentType, emptyInstance);
+    }
+
+    // Since 1.7:
+    @Override
+    public ArrayType withTypeHandler(Object h) {
+        ArrayType newInstance = new ArrayType(_componentType, _emptyArray);
+        newInstance._typeHandler = h;
+        return newInstance;
+    }
+
+    // Since 1.7:
+    @Override
+    public ArrayType withContentTypeHandler(Object h) {
+        return new ArrayType(_componentType.withTypeHandler(h), _emptyArray);
+    }
+
+    @Override
+    protected String buildCanonicalName() {
+        return _class.getName();
+    }
+
+    /*
+    /**********************************************************
+    /* Methods for narrowing conversions
+    /**********************************************************
+     */
+
+    /**
+     * Handling of narrowing conversions for arrays is trickier: for now,
+     * it is not even allowed.
+     */
+    @Override
+    protected JavaType _narrow(Class<?> subclass) {
+        /* Ok: need a bit of indirection here. First, must replace component
+         * type (and check that it is compatible), then re-construct.
+         */
+        if (!subclass.isArray()) { // sanity check, should never occur
+            throw new IllegalArgumentException("Incompatible narrowing operation: trying to narrow " + toString()
+                + " to class "
+                + subclass.getName());
+        }
+        /* Hmmh. This is an awkward back reference... but seems like the
+         * only simple way to do it.
+         */
+        Class<?> newCompClass = subclass.getComponentType();
+        JavaType newCompType = TypeFactory.type(newCompClass);
+        return construct(newCompType);
+    }
+
+    /**
+     * For array types, both main type and content type can be modified;
+     * but ultimately they are interchangeable.
+     */
+    @Override
+    public JavaType narrowContentsBy(Class<?> contentClass) {
+        // Can do a quick check first:
+        if (contentClass == _componentType.getRawClass()) {
+            return this;
+        }
+        JavaType newComponentType = _componentType.narrowBy(contentClass);
+        return construct(newComponentType).copyHandlers(this);
+    }
+
+    /*
+    /**********************************************************
+    /* Overridden methods
+    /**********************************************************
+     */
+
+    @Override
+    public boolean isArrayType() {
+        return true;
+    }
+
+    /**
+     * For some odd reason, modifiers for array classes would
+     * claim they are abstract types. Not so, at least for our
+     * purposes.
+     */
+    @Override
+    public boolean isAbstract() {
+        return false;
+    }
+
+    /**
+     * For some odd reason, modifiers for array classes would
+     * claim they are abstract types. Not so, at least for our
+     * purposes.
+     */
+    @Override
+    public boolean isConcrete() {
+        return true;
+    }
+
+    @Override
+    public boolean hasGenericTypes() {
+        // arrays are not parameterized, but element type may be:
+        return _componentType.hasGenericTypes();
+    }
+
+    /**
+     * Not sure what symbolic name is used internally, if any;
+     * let's follow naming of Collection types here.
+     * Should not really matter since array types have no
+     * super types.
+     */
+    @Override
+    public String containedTypeName(int index) {
+        if (index == 0)
+            return "E";
+        return null;
+    }
+
+    /*
+    /**********************************************************
+    /* Public API
+    /**********************************************************
+     */
+
+    @Override
+    public boolean isContainerType() {
+        return true;
+    }
+
+    @Override
+    public JavaType getContentType() {
+        return _componentType;
+    }
+
+    @Override
+    public int containedTypeCount() {
+        return 1;
+    }
+
+    @Override
+    public JavaType containedType(int index) {
+        return (index == 0) ? _componentType : null;
+    }
+
+    @Override
+    public StringBuilder getGenericSignature(StringBuilder sb) {
+        sb.append('[');
+        return _componentType.getGenericSignature(sb);
+    }
+
+    @Override
+    public StringBuilder getErasedSignature(StringBuilder sb) {
+        sb.append('[');
+        return _componentType.getErasedSignature(sb);
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods
+    /**********************************************************
+     */
+
+    @Override
+    public String toString() {
+        return "[array type, component type: " + _componentType + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (o.getClass() != getClass())
+            return false;
+
+        ArrayType other = (ArrayType)o;
+        return _componentType.equals(other._componentType);
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ArrayType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,112 @@
+/*
+ * 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.type;
+
+/**
+ * Key class, used as an efficient and accurate key
+ * for locating per-class values
+ *<p>
+ * The reason for having a separate key class instead of
+ * directly using {@link Class} as key is mostly
+ * to allow for redefining <code>hashCode</code> method --
+ * for some strange reason, {@link Class} does not
+ * redefine {@link Object#hashCode} and thus uses identity
+ * hash, which is pretty slow. This makes key access using
+ * {@link Class} unnecessarily slow.
+ *<p>
+ * Note: since class is not strictly immutable, caller must
+ * know what it is doing, if changing field values.
+ */
+public final class ClassKey implements Comparable<ClassKey> {
+    String _className;
+
+    Class<?> _class;
+
+    /**
+     * Let's cache hash code straight away, since we are
+     * almost certain to need it.
+     */
+    int _hashCode;
+
+    public ClassKey() {
+        _class = null;
+        _className = null;
+        _hashCode = 0;
+    }
+
+    public ClassKey(Class<?> clz) {
+        _class = clz;
+        _className = clz.getName();
+        _hashCode = _className.hashCode();
+    }
+
+    public void reset(Class<?> clz) {
+        _class = clz;
+        _className = clz.getName();
+        _hashCode = _className.hashCode();
+    }
+
+    /*
+    /**********************************************************
+    /* Comparable
+    /**********************************************************
+     */
+
+    public int compareTo(ClassKey other) {
+        // Just need to sort by name, ok to collide (unless used in TreeMap/Set!)
+        return _className.compareTo(other._className);
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods
+    /**********************************************************
+     */
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (o.getClass() != getClass())
+            return false;
+        ClassKey other = (ClassKey)o;
+
+        /* Is it possible to have different Class object for same name + class loader combo?
+         * Let's assume answer is no: if this is wrong, will need to uncomment following functionality
+         */
+        /*
+        return (other._className.equals(_className))
+            && (other._class.getClassLoader() == _class.getClassLoader());
+        */
+        return other._class == _class;
+    }
+
+    @Override
+    public int hashCode() {
+        return _hashCode;
+    }
+
+    @Override
+    public String toString() {
+        return _className;
+    }
+
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/ClassKey.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,167 @@
+/*
+ * 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.type;
+
+/**
+ * Type that represents Java Collection types (Lists, Sets).
+ */
+public final class CollectionType extends TypeBase {
+    /**
+     * Type of elements in collection
+     */
+    final JavaType _elementType;
+
+    /*
+    /**********************************************************
+    /* Life-cycle
+    /**********************************************************
+     */
+
+    private CollectionType(Class<?> collT, JavaType elemT) {
+        super(collT, elemT.hashCode());
+        _elementType = elemT;
+    }
+
+    @Override
+    protected JavaType _narrow(Class<?> subclass) {
+        return new CollectionType(subclass, _elementType);
+    }
+
+    @Override
+    public JavaType narrowContentsBy(Class<?> contentClass) {
+        // Can do a quick check first:
+        if (contentClass == _elementType.getRawClass()) {
+            return this;
+        }
+        JavaType newElementType = _elementType.narrowBy(contentClass);
+        return new CollectionType(_class, newElementType).copyHandlers(this);
+    }
+
+    public static CollectionType construct(Class<?> rawType, JavaType elemT) {
+        // nominally component types will be just Object.class
+        return new CollectionType(rawType, elemT);
+    }
+
+    // Since 1.7:
+    @Override
+    public CollectionType withTypeHandler(Object h) {
+        CollectionType newInstance = new CollectionType(_class, _elementType);
+        newInstance._typeHandler = h;
+        return newInstance;
+    }
+
+    // Since 1.7:
+    @Override
+    public CollectionType withContentTypeHandler(Object h) {
+        return new CollectionType(_class, _elementType.withTypeHandler(h));
+    }
+
+    @Override
+    protected String buildCanonicalName() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(_class.getName());
+        if (_elementType != null) {
+            sb.append('<');
+            sb.append(_elementType.toCanonical());
+            sb.append('>');
+        }
+        return sb.toString();
+    }
+
+    /*
+    /**********************************************************
+    /* Public API
+    /**********************************************************
+     */
+
+    @Override
+    public JavaType getContentType() {
+        return _elementType;
+    }
+
+    @Override
+    public int containedTypeCount() {
+        return 1;
+    }
+
+    @Override
+    public JavaType containedType(int index) {
+        return (index == 0) ? _elementType : null;
+    }
+
+    /**
+     * Not sure if we should count on this, but type names
+     * for core interfaces use "E" for element type
+     */
+    @Override
+    public String containedTypeName(int index) {
+        if (index == 0)
+            return "E";
+        return null;
+    }
+
+    @Override
+    public StringBuilder getErasedSignature(StringBuilder sb) {
+        return _classSignature(_class, sb, true);
+    }
+
+    @Override
+    public StringBuilder getGenericSignature(StringBuilder sb) {
+        _classSignature(_class, sb, false);
+        sb.append('<');
+        _elementType.getGenericSignature(sb);
+        sb.append(">;");
+        return sb;
+    }
+
+    /*
+    /**********************************************************
+    /* Extended API
+    /**********************************************************
+     */
+
+    @Override
+    public boolean isContainerType() {
+        return true;
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods
+    /**********************************************************
+     */
+
+    @Override
+    public String toString() {
+        return "[collection type; class " + _class.getName() + ", contains " + _elementType + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (o.getClass() != getClass())
+            return false;
+
+        CollectionType other = (CollectionType)o;
+        return (_class == other._class) && _elementType.equals(other._elementType);
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/CollectionType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,98 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * Simple replacement for {@link java.lang.Class} (and/or various Type subtypes)
+ * that is used as part of single-path extends/implements chain to express
+ * specific relationship between one subtype and one supertype. This is needed
+ * for resolving type parameters. Instances are doubly-linked so that chain
+ * can be traversed in both directions
+ * 
+ * @since 1.6
+ */
+public class HierarchicType {
+    /**
+     * Type which will be either plain {@link java.lang.Class} or
+     * {@link java.lang.reflect.ParameterizedType}.
+     */
+    protected final Type _actualType;
+
+    protected final Class<?> _rawClass;
+
+    protected final ParameterizedType _genericType;
+
+    protected HierarchicType _superType;
+
+    protected HierarchicType _subType;
+
+    public HierarchicType(Type type) {
+        this._actualType = type;
+        if (type instanceof Class<?>) {
+            _rawClass = (Class<?>)type;
+            _genericType = null;
+        } else if (type instanceof ParameterizedType) {
+            _genericType = (ParameterizedType)type;
+            _rawClass = (Class<?>)_genericType.getRawType();
+        } else { // should never happen... can't extend GenericArrayType?
+            throw new IllegalArgumentException("Type " + type.getClass().getName()
+                + " can not be used to construct HierarchicType");
+        }
+    }
+
+    public void setSuperType(HierarchicType sup) {
+        _superType = sup;
+    }
+
+    public HierarchicType getSuperType() {
+        return _superType;
+    }
+
+    public void setSubType(HierarchicType sub) {
+        _subType = sub;
+    }
+
+    public HierarchicType getSubType() {
+        return _subType;
+    }
+
+    public boolean isGeneric() {
+        return _genericType != null;
+    }
+
+    public ParameterizedType asGeneric() {
+        return _genericType;
+    }
+
+    public Class<?> getRawClass() {
+        return _rawClass;
+    }
+
+    @Override
+    public String toString() {
+        if (_genericType != null) {
+            return _genericType.toString();
+        }
+        return _rawClass.getName();
+    }
+
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/HierarchicType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,484 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Base class for type token classes used both to contain information
+ * and as keys for deserializers.
+ *<p>
+ * Instances can (only) be constructed by
+ * {@link org.apache.tuscany.sca.common.java.type.TypeFactory}.
+ */
+public abstract class JavaType {
+    /**
+     * This is the nominal type-erased Class that would be close to the
+     * type represented (but not exactly type, due to type erasure: type
+     * instance may have more information on this).
+     * May be an interface or abstract class, so instantiation
+     * may not be possible.
+     */
+    protected final Class<?> _class;
+
+    protected final int _hashCode;
+
+    /**
+     * Optional handler (codec) that can be attached to indicate 
+     * what to use for handling (serializing, deserializing) values of
+     * this specific type.
+     *<p>
+     * Note: untyped (i.e. caller has to cast) because it is used for
+     * different kinds of handlers, with unrelated types.
+     *
+     * @since 1.3
+     */
+    protected Object _valueHandler;
+
+    /**
+     * Optional handler that can be attached to indicate how to handle
+     * additional type metadata associated with this type.
+     *<p>
+     * Note: untyped (i.e. caller has to cast) because it is used for
+     * different kinds of handlers, with unrelated types.
+     *
+     * @since 1.5
+     */
+    protected Object _typeHandler;
+
+    /*
+    /**********************************************************
+    /* Life-cycle
+    /**********************************************************
+     */
+
+    protected JavaType(Class<?> clz, int hash) {
+        _class = clz;
+        String name = clz.getName();
+        _hashCode = name.hashCode() + hash;
+    }
+
+    /**
+     * "Copy method" that will construct a new instance that is identical to
+     * this instance, except that it will have specified type handler assigned.
+     * 
+     * @return Newly created type instance
+     * 
+     * @since 1.7
+     */
+    public abstract JavaType withTypeHandler(Object h);
+
+    /**
+     * "Copy method" that will construct a new instance that is identical to
+     * this instance, except that its content type will have specified
+     * type handler assigned.
+     * 
+     * @return Newly created type instance
+     * 
+     * @since 1.7
+     */
+    public abstract JavaType withContentTypeHandler(Object h);
+
+    /**
+     * Method that can be called to do a "narrowing" conversions; that is,
+     * to return a type with a raw class that is assignable to the raw
+     * class of this type. If this is not possible, an
+     * {@link IllegalArgumentException} is thrown.
+     * If class is same as the current raw class, instance itself is
+     * returned.
+     */
+    public final JavaType narrowBy(Class<?> subclass) {
+        // First: if same raw class, just return this instance
+        if (subclass == _class) {
+            return this;
+        }
+        // Otherwise, ensure compatibility
+        _assertSubclass(subclass, _class);
+        JavaType result = _narrow(subclass);
+        if (_valueHandler != null) {
+            result.setValueHandler(_valueHandler);
+        }
+        if (_typeHandler != null) {
+            result = result.withTypeHandler(_typeHandler);
+        }
+        return result;
+    }
+
+    /**
+     * More efficient version of {@link #narrowBy}, called by
+     * internal framework in cases where compatibility checks
+     * are to be skipped.
+     *
+     * @since 1.5
+     */
+    public final JavaType forcedNarrowBy(Class<?> subclass) {
+        if (subclass == _class) { // can still optimize for simple case
+            return this;
+        }
+        JavaType result = _narrow(subclass);
+        if (_valueHandler != null) {
+            result.setValueHandler(_valueHandler);
+        }
+        if (_typeHandler != null) {
+            result = result.withTypeHandler(_typeHandler);
+        }
+        return result;
+    }
+
+    /**
+     * Method that can be called to do a "widening" conversions; that is,
+     * to return a type with a raw class that could be assigned from this
+     * type.
+     * If such conversion is not possible, an
+     * {@link IllegalArgumentException} is thrown.
+     * If class is same as the current raw class, instance itself is
+     * returned.
+     */
+    public final JavaType widenBy(Class<?> superclass) {
+        // First: if same raw class, just return this instance
+        if (superclass == _class) {
+            return this;
+        }
+        // Otherwise, ensure compatibility
+        _assertSubclass(_class, superclass);
+        return _widen(superclass);
+    }
+
+    protected abstract JavaType _narrow(Class<?> subclass);
+
+    /**
+     *<p>
+     * Default implementation is just to call {@link #_narrow}, since
+     * underlying type construction is usually identical
+     */
+    protected JavaType _widen(Class<?> superclass) {
+        return _narrow(superclass);
+    }
+
+    public abstract JavaType narrowContentsBy(Class<?> contentClass);
+
+    /**
+     * Method for assigning handler to associate with this type; or
+     * if null passed, to remove such assignment
+     * 
+     * @since 1.3
+     */
+    public void setValueHandler(Object h) {
+        // sanity check, should be assigned just once
+        if (h != null && _valueHandler != null) {
+            throw new IllegalStateException("Trying to reset value handler for type [" + toString()
+                + "]; old handler of type "
+                + _valueHandler.getClass().getName()
+                + ", new handler of type "
+                + h.getClass().getName());
+        }
+        _valueHandler = h;
+    }
+
+    /**
+     * Method for assigning type handler to associate with this type; or
+     * if null passed, to remove such assignment
+     * 
+     * @since 1.5
+     * 
+     * @deprecated Used {@link #withTypeHandler} instead -- this method is dangerous as
+     *   it changes state, whereas all other functionality is stateless
+     */
+    @Deprecated
+    public void setTypeHandler(Object h) {
+        // sanity check, should be assigned just once
+        /* 03-Nov-2010: NOTE - some care has to be taken to ensure that types are not reused
+         *   between requests; one case I had to fix was that of passing root type by ObjectWriter
+         *   and ObjectReader (must clone/copy types!)
+         */
+        if (h != null && _typeHandler != null) {
+            throw new IllegalStateException("Trying to reset type handler for type [" + toString()
+                + "]; old handler of type "
+                + _typeHandler.getClass().getName()
+                + ", new handler of type "
+                + h.getClass().getName());
+        }
+        _typeHandler = h;
+    }
+
+    /*
+    /**********************************************************
+    /* Public API
+    /**********************************************************
+     */
+
+    public final Class<?> getRawClass() {
+        return _class;
+    }
+
+    /**
+     * Method that can be used to check whether this type has
+     * specified Class as its type erasure. Put another way, returns
+     * true if instantiation of this Type is given (type-erased) Class.
+     */
+    public final boolean hasRawClass(Class<?> clz) {
+        return _class == clz;
+    }
+
+    /**
+     * @return True if type represented is a container type; this includes
+     *    array, Map and Collection types.
+     */
+    public abstract boolean isContainerType();
+
+    public boolean isAbstract() {
+        return Modifier.isAbstract(_class.getModifiers());
+    }
+
+    /**
+     * @since 1.3
+     */
+    public boolean isConcrete() {
+        int mod = _class.getModifiers();
+        if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) {
+            return true;
+        }
+        /* 19-Feb-2010, tatus: Holy mackarel; primitive types
+         *    have 'abstract' flag set...
+         */
+        if (_class.isPrimitive()) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isThrowable() {
+        return Throwable.class.isAssignableFrom(_class);
+    }
+
+    public boolean isArrayType() {
+        return false;
+    }
+
+    public final boolean isEnumType() {
+        return _class.isEnum();
+    }
+
+    public final boolean isInterface() {
+        return _class.isInterface();
+    }
+
+    public final boolean isPrimitive() {
+        return _class.isPrimitive();
+    }
+
+    public final boolean isFinal() {
+        return Modifier.isFinal(_class.getModifiers());
+    }
+
+    /**
+     * Method that can be used to find out if the type directly declares generic
+     * parameters (for its direct super-class and/or super-interfaces).
+     * 
+     * @since 1.6
+     */
+    public boolean hasGenericTypes() {
+        return containedTypeCount() > 0;
+    }
+
+    /**
+     * Method for accessing key type for this type, assuming type
+     * has such a concept (only Map types do)
+     */
+    public JavaType getKeyType() {
+        return null;
+    }
+
+    /**
+     * Method for accessing content type of this type, if type has
+     * such a thing: simple types do not, structured types do
+     * (like arrays, Collections and Maps)
+     */
+    public JavaType getContentType() {
+        return null;
+    }
+
+    /**
+     * Method for checking how many contained types this type
+     * has. Contained types are usually generic types, so that
+     * generic Maps have 2 contained types.
+     * 
+     * @since 1.5
+     */
+    public int containedTypeCount() {
+        return 0;
+    }
+
+    /**
+     * Method for accessing definitions of contained ("child")
+     * types.
+     * 
+     * @param index Index of contained type to return
+     * 
+     * @return Contained type at index, or null if no such type
+     *    exists (no exception thrown)
+     * 
+     * @since 1.5
+     */
+    public JavaType containedType(int index) {
+        return null;
+    }
+
+    /**
+     * Method for accessing name of type variable in indicated
+     * position. If no name is bound, will use placeholders (derived
+     * from 0-based index); if no type variable or argument exists
+     * with given index, null is returned.
+     * 
+     * @param index Index of contained type to return
+     * 
+     * @return Contained type at index, or null if no such type
+     *    exists (no exception thrown)
+     * 
+     * @since 1.5
+     */
+    public String containedTypeName(int index) {
+        return null;
+    }
+
+    /**
+     * Method for accessing value handler associated with this type, if any
+     * 
+     * @since 1.3
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getValueHandler() {
+        return (T)_valueHandler;
+    }
+
+    /**
+     * Method for accessing type handler associated with this type, if any
+     * 
+     * @since 1.5
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getTypeHandler() {
+        return (T)_typeHandler;
+    }
+
+    /**
+     * Method that can be used to serialize type into form from which
+     * it can be fully deserialized from at a later point (using
+     * <code>TypeFactory</code> from mapper package).
+     * For simple types this is same as calling
+     * {@link Class#getName}, but for structured types it may additionally
+     * contain type information about contents.
+     * 
+     * @since 1.5
+     */
+    public abstract String toCanonical();
+
+    /*
+    /**********************************************************
+    /* Support for producing signatures (1.6+)
+    /**********************************************************
+     */
+
+    /**
+     * Method for accessing signature that contains generic
+     * type information, in form compatible with JVM 1.5
+     * as per JLS. It is a superset of {@link #getErasedSignature},
+     * in that generic information can be automatically removed
+     * if necessary (just remove outermost
+     * angle brackets along with content inside)
+     * 
+     * @since 1.6
+     */
+    public String getGenericSignature() {
+        StringBuilder sb = new StringBuilder(40);
+        getGenericSignature(sb);
+        return sb.toString();
+    }
+
+    /**
+     * 
+     * @param sb StringBuilder to append signature to
+     * 
+     * @return StringBuilder that was passed in; returned to allow
+     * call chaining
+     * 
+     * @since 1.6
+     */
+    public abstract StringBuilder getGenericSignature(StringBuilder sb);
+
+    /**
+     * Method for accessing signature without generic
+     * type information, in form compatible with all versions
+     * of JVM, and specifically used for type descriptions
+     * when generating byte code.
+     * 
+     * @since 1.6
+     */
+    public String getErasedSignature() {
+        StringBuilder sb = new StringBuilder(40);
+        getErasedSignature(sb);
+        return sb.toString();
+    }
+
+    /**
+     * Method for accessing signature without generic
+     * type information, in form compatible with all versions
+     * of JVM, and specifically used for type descriptions
+     * when generating byte code.
+     * 
+     * @param sb StringBuilder to append signature to
+     * 
+     * @return StringBuilder that was passed in; returned to allow
+     * call chaining
+     * 
+     * @since 1.6
+     */
+    public abstract StringBuilder getErasedSignature(StringBuilder sb);
+
+    /*
+    /**********************************************************
+    /* Helper methods
+    /**********************************************************
+     */
+
+    protected void _assertSubclass(Class<?> subclass, Class<?> superClass) {
+        if (!_class.isAssignableFrom(subclass)) {
+            throw new IllegalArgumentException("Class " + subclass.getName()
+                + " is not assignable to "
+                + _class.getName());
+        }
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods; let's make them abstract to force override
+    /**********************************************************
+     */
+
+    @Override
+    public abstract String toString();
+
+    @Override
+    public abstract boolean equals(Object o);
+
+    @Override
+    public final int hashCode() {
+        return _hashCode;
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/JavaType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,191 @@
+/*
+ * 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.type;
+
+/**
+ * Type that represents Java Map types.
+ */
+public final class MapType extends TypeBase {
+    /**
+     * Type of keys of Map.
+     */
+    final JavaType _keyType;
+
+    /**
+     * Type of values of Map.
+     */
+    final JavaType _valueType;
+
+    /*
+    /**********************************************************
+    /* Life-cycle
+    /**********************************************************
+     */
+
+    private MapType(Class<?> mapType, JavaType keyT, JavaType valueT) {
+        super(mapType, keyT.hashCode() ^ valueT.hashCode());
+        _keyType = keyT;
+        _valueType = valueT;
+    }
+
+    public static MapType construct(Class<?> rawType, JavaType keyT, JavaType valueT) {
+        // nominally component types will be just Object.class
+        return new MapType(rawType, keyT, valueT);
+    }
+
+    @Override
+    protected JavaType _narrow(Class<?> subclass) {
+        return new MapType(subclass, _keyType, _valueType);
+    }
+
+    @Override
+    public JavaType narrowContentsBy(Class<?> contentClass) {
+        // Can do a quick check first:
+        if (contentClass == _valueType.getRawClass()) {
+            return this;
+        }
+        JavaType newValueType = _valueType.narrowBy(contentClass);
+        return new MapType(_class, _keyType, newValueType).copyHandlers(this);
+    }
+
+    public JavaType narrowKey(Class<?> keySubclass) {
+        // Can do a quick check first:
+        if (keySubclass == _keyType.getRawClass()) {
+            return this;
+        }
+        JavaType newKeyType = _keyType.narrowBy(keySubclass);
+        return new MapType(_class, newKeyType, _valueType).copyHandlers(this);
+    }
+
+    // Since 1.7:
+    @Override
+    public MapType withTypeHandler(Object h) {
+        MapType newInstance = new MapType(_class, _keyType, _valueType);
+        newInstance._typeHandler = h;
+        return newInstance;
+    }
+
+    // Since 1.7:
+    @Override
+    public MapType withContentTypeHandler(Object h) {
+        return new MapType(_class, _keyType, _valueType.withTypeHandler(h));
+    }
+
+    @Override
+    protected String buildCanonicalName() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(_class.getName());
+        if (_keyType != null) {
+            sb.append('<');
+            sb.append(_keyType.toCanonical());
+            sb.append(',');
+            sb.append(_valueType.toCanonical());
+            sb.append('>');
+        }
+        return sb.toString();
+    }
+
+    /*
+    /**********************************************************
+    /* Public API
+    /**********************************************************
+     */
+
+    @Override
+    public boolean isContainerType() {
+        return true;
+    }
+
+    @Override
+    public JavaType getKeyType() {
+        return _keyType;
+    }
+
+    @Override
+    public JavaType getContentType() {
+        return _valueType;
+    }
+
+    @Override
+    public int containedTypeCount() {
+        return 2;
+    }
+
+    @Override
+    public JavaType containedType(int index) {
+        if (index == 0)
+            return _keyType;
+        if (index == 1)
+            return _valueType;
+        return null;
+    }
+
+    /**
+     * Not sure if we should count on this, but type names
+     * for core interfaces are "K" and "V" respectively.
+     * For now let's assume this should work.
+     */
+    @Override
+    public String containedTypeName(int index) {
+        if (index == 0)
+            return "K";
+        if (index == 1)
+            return "V";
+        return null;
+    }
+
+    @Override
+    public StringBuilder getErasedSignature(StringBuilder sb) {
+        return _classSignature(_class, sb, true);
+    }
+
+    @Override
+    public StringBuilder getGenericSignature(StringBuilder sb) {
+        _classSignature(_class, sb, false);
+        sb.append('<');
+        _keyType.getGenericSignature(sb);
+        _valueType.getGenericSignature(sb);
+        sb.append(">;");
+        return sb;
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods
+    /**********************************************************
+     */
+
+    @Override
+    public String toString() {
+        return "[map type; class " + _class.getName() + ", " + _keyType + " -> " + _valueType + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (o.getClass() != getClass())
+            return false;
+
+        MapType other = (MapType)o;
+        return (_class == other._class) && _keyType.equals(other._keyType) && _valueType.equals(other._valueType);
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/MapType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,232 @@
+/*
+ * 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.type;
+
+/*
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+*/
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Simple types are defined as anything other than one of recognized
+ * container types (arrays, Collections, Maps). For our needs we
+ * need not know anything further, since we have no way of dealing
+ * with generic types other than Collections and Maps.
+ */
+public final class SimpleType extends TypeBase {
+    /**
+     * Generic type arguments for this type.
+     */
+    protected final JavaType[] _typeParameters;
+
+    /**
+     * Names of generic type arguments for this type; will
+     * match values in {@link #_typeParameters}
+     */
+    protected final String[] _typeNames;
+
+    /*
+    /**********************************************************
+    /* Life-cycle
+    /**********************************************************
+     */
+
+    protected SimpleType(Class<?> cls) {
+        this(cls, null, null);
+    }
+
+    protected SimpleType(Class<?> cls, String[] typeNames, JavaType[] typeParams) {
+        super(cls, 0);
+        if (typeNames == null || typeNames.length == 0) {
+            _typeNames = null;
+            _typeParameters = null;
+        } else {
+            _typeNames = typeNames;
+            _typeParameters = typeParams;
+        }
+    }
+
+    @Override
+    protected JavaType _narrow(Class<?> subclass) {
+        // Should we check that there is a sub-class relationship?
+        return new SimpleType(subclass, _typeNames, _typeParameters);
+    }
+
+    @Override
+    public JavaType narrowContentsBy(Class<?> subclass) {
+        // should never get called
+        throw new IllegalArgumentException("Internal error: SimpleType.narrowContentsBy() should never be called");
+    }
+
+    public static SimpleType construct(Class<?> cls) {
+        /* Let's add sanity checks, just to ensure no
+         * Map/Collection entries are constructed
+         */
+        if (Map.class.isAssignableFrom(cls)) {
+            throw new IllegalArgumentException("Can not construct SimpleType for a Map (class: " + cls.getName() + ")");
+        }
+        if (Collection.class.isAssignableFrom(cls)) {
+            throw new IllegalArgumentException("Can not construct SimpleType for a Collection (class: " + cls.getName()
+                + ")");
+        }
+        // ... and while we are at it, not array types either
+        if (cls.isArray()) {
+            throw new IllegalArgumentException("Can not construct SimpleType for an array (class: " + cls.getName()
+                + ")");
+        }
+        return new SimpleType(cls);
+    }
+
+    // Since 1.7:
+    @Override
+    public SimpleType withTypeHandler(Object h) {
+        SimpleType newInstance = new SimpleType(_class, _typeNames, _typeParameters);
+        newInstance._typeHandler = h;
+        return newInstance;
+    }
+
+    // Since 1.7:
+    @Override
+    public JavaType withContentTypeHandler(Object h) {
+        // no content type, so:
+        throw new IllegalArgumentException("Simple types have no content types; can not call withContenTypeHandler()");
+    }
+
+    @Override
+    protected String buildCanonicalName() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(_class.getName());
+        if (_typeParameters != null && _typeParameters.length > 0) {
+            sb.append('<');
+            boolean first = true;
+            for (JavaType t : _typeParameters) {
+                if (first) {
+                    first = false;
+                } else {
+                    sb.append(',');
+                }
+                sb.append(t.toCanonical());
+            }
+            sb.append('>');
+        }
+        return sb.toString();
+    }
+
+    /*
+    /**********************************************************
+    /* Public API
+    /**********************************************************
+     */
+
+    @Override
+    public boolean isContainerType() {
+        return false;
+    }
+
+    @Override
+    public int containedTypeCount() {
+        return (_typeParameters == null) ? 0 : _typeParameters.length;
+    }
+
+    @Override
+    public JavaType containedType(int index) {
+        if (index < 0 || _typeParameters == null || index >= _typeParameters.length) {
+            return null;
+        }
+        return _typeParameters[index];
+    }
+
+    @Override
+    public String containedTypeName(int index) {
+        if (index < 0 || _typeNames == null || index >= _typeNames.length) {
+            return null;
+        }
+        return _typeNames[index];
+    }
+
+    @Override
+    public StringBuilder getErasedSignature(StringBuilder sb) {
+        return _classSignature(_class, sb, true);
+    }
+
+    @Override
+    public StringBuilder getGenericSignature(StringBuilder sb) {
+        _classSignature(_class, sb, false);
+        if (_typeParameters != null) {
+            sb.append('<');
+            for (JavaType param : _typeParameters) {
+                sb = param.getGenericSignature(sb);
+            }
+            sb.append('>');
+        }
+        sb.append(';');
+        return sb;
+    }
+
+    /*
+    /**********************************************************
+    /* Standard methods
+    /**********************************************************
+     */
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(40);
+        sb.append("[simple type, class ").append(buildCanonicalName()).append(']');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (o == null)
+            return false;
+        if (o.getClass() != getClass())
+            return false;
+
+        SimpleType other = (SimpleType)o;
+
+        // Classes must be identical... 
+        if (other._class != this._class)
+            return false;
+
+        // And finally, generic bindings, if any
+        JavaType[] p1 = _typeParameters;
+        JavaType[] p2 = other._typeParameters;
+        if (p1 == null) {
+            return (p2 == null) || p2.length == 0;
+        }
+        if (p2 == null)
+            return false;
+
+        if (p1.length != p2.length)
+            return false;
+        for (int i = 0, len = p1.length; i < len; ++i) {
+            if (!p1[i].equals(p2[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/SimpleType.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.wink.common.internal.type;
+
+public abstract class TypeBase extends JavaType {
+    /**
+     * Lazily initialized external representation of the type
+     */
+    volatile String _canonicalName;
+
+    protected TypeBase(Class<?> raw, int hash) {
+        super(raw, hash);
+    }
+
+    @Override
+    public String toCanonical() {
+        String str = _canonicalName;
+        if (str == null) {
+            str = buildCanonicalName();
+        }
+        return str;
+    }
+
+    protected abstract String buildCanonicalName();
+
+    protected final JavaType copyHandlers(JavaType fromType) {
+        _valueHandler = fromType.getValueHandler();
+        _typeHandler = fromType.getTypeHandler();
+        return this;
+    }
+
+    @Override
+    public abstract StringBuilder getGenericSignature(StringBuilder sb);
+
+    @Override
+    public abstract StringBuilder getErasedSignature(StringBuilder sb);
+
+    /*
+    /**********************************************************
+    /* Methods for sub-classes to use
+    /**********************************************************
+     */
+
+    /**
+     * @param trailingSemicolon Whether to add trailing semicolon for non-primitive
+     *   (reference) types or not
+     */
+    protected static StringBuilder _classSignature(Class<?> cls, StringBuilder sb, boolean trailingSemicolon) {
+        if (cls.isPrimitive()) {
+            if (cls == Boolean.TYPE) {
+                sb.append('Z');
+            } else if (cls == Byte.TYPE) {
+                sb.append('B');
+            } else if (cls == Short.TYPE) {
+                sb.append('S');
+            } else if (cls == Character.TYPE) {
+                sb.append('C');
+            } else if (cls == Integer.TYPE) {
+                sb.append('I');
+            } else if (cls == Long.TYPE) {
+                sb.append('J');
+            } else if (cls == Float.TYPE) {
+                sb.append('F');
+            } else if (cls == Double.TYPE) {
+                sb.append('D');
+            } else if (cls == Void.TYPE) {
+                sb.append('V');
+            } else {
+                throw new IllegalStateException("Unrecognized primitive type: " + cls.getName());
+            }
+        } else {
+            sb.append('L');
+            String name = cls.getName();
+            for (int i = 0, len = name.length(); i < len; ++i) {
+                char c = name.charAt(i);
+                if (c == '.')
+                    c = '/';
+                sb.append(c);
+            }
+            if (trailingSemicolon) {
+                sb.append(';');
+            }
+        }
+        return sb;
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBase.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java?rev=1071325&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java Wed Feb 16 17:43:56 2011
@@ -0,0 +1,225 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Helper class used for resolving type parameters for given class
+ * 
+ * @since 1.5
+ */
+public class TypeBindings {
+    /**
+     * Marker to use for (temporarily) unbound references.
+     */
+    public final static JavaType UNBOUND = new SimpleType(Object.class);
+
+    /**
+     * Context type used for resolving all types, if specified. May be null,
+     * in which case {@link #_contextClass} is used instead.
+     */
+    protected final JavaType _contextType;
+
+    /**
+     * Specific class to use for resolving all types, for methods and fields
+     * class and its superclasses and -interfaces contain.
+     */
+    protected final Class<?> _contextClass;
+
+    /**
+     * Lazily-instantiated bindings of resolved type parameters
+     */
+    protected Map<String, JavaType> _bindings;
+
+    /**
+     * Also: we may temporarily want to mark certain named types
+     * as resolved (but without exact type); if so, we'll just store
+     * names here.
+     */
+    protected HashSet<String> _placeholders;
+
+    public TypeBindings(Class<?> cc) {
+        _contextClass = cc;
+        _contextType = null;
+    }
+
+    public TypeBindings(JavaType type) {
+        _contextType = type;
+        _contextClass = type.getRawClass();
+    }
+
+    public int getBindingCount() {
+        if (_bindings == null) {
+            _resolve();
+        }
+        return _bindings.size();
+    }
+
+    public JavaType findType(String name) {
+        if (_bindings == null) {
+            _resolve();
+        }
+        JavaType t = _bindings.get(name);
+        if (t == null) {
+            if (_placeholders != null && _placeholders.contains(name)) {
+                t = UNBOUND;
+            } else {
+                // Should we throw an exception or just return null?
+                throw new IllegalArgumentException("Type variable '" + name
+                    + "' can not be resolved (with context of class "
+                    + _contextClass.getName()
+                    + ")");
+                //t = UNBOUND;                
+            }
+        }
+        return t;
+    }
+
+    /*
+    /*******************************************************************8
+    /* Internal methods
+    /*******************************************************************8
+     */
+
+    protected void _resolve() {
+        _resolveBindings(_contextClass);
+
+        // finally: may have root level type info too
+        if (_contextType != null) {
+            int count = _contextType.containedTypeCount();
+            if (count > 0) {
+                if (_bindings == null) {
+                    _bindings = new HashMap<String, JavaType>();
+                }
+                for (int i = 0; i < count; ++i) {
+                    String name = _contextType.containedTypeName(i);
+                    JavaType type = _contextType.containedType(i);
+                    _bindings.put(name, type);
+                }
+            }
+        }
+
+        // nothing bound? mark with empty map to prevent further calls
+        if (_bindings == null) {
+            _bindings = Collections.emptyMap();
+        }
+    }
+
+    public void _addPlaceholder(String name) {
+        if (_placeholders == null) {
+            _placeholders = new HashSet<String>();
+        }
+        _placeholders.add(name);
+    }
+
+    protected void _resolveBindings(Type t) {
+        if (t == null)
+            return;
+
+        Class<?> raw;
+        if (t instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType)t;
+            Type[] args = pt.getActualTypeArguments();
+            if (args != null && args.length > 0) {
+                Class<?> rawType = (Class<?>)pt.getRawType();
+                TypeVariable<?>[] vars = rawType.getTypeParameters();
+                if (vars.length != args.length) {
+                    throw new IllegalArgumentException("Strange parametrized type (in class " + rawType.getName()
+                        + "): number of type arguments != number of type parameters ("
+                        + args.length
+                        + " vs "
+                        + vars.length
+                        + ")");
+                }
+                for (int i = 0, len = args.length; i < len; ++i) {
+                    TypeVariable<?> var = vars[i];
+                    String name = var.getName();
+                    if (_bindings == null) {
+                        _bindings = new HashMap<String, JavaType>();
+                    } else {
+                        /* 24-Mar-2010, tatu: Better ensure that we do not overwrite something
+                         *  collected earlier (since we descend towards super-classes):
+                         */
+                        if (_bindings.containsKey(name))
+                            continue;
+                    }
+                    // first: add a placeholder to prevent infinite loops
+                    _addPlaceholder(name);
+                    // then resolve type
+                    _bindings.put(name, TypeFactory.instance._fromType(args[i], this));
+                }
+            }
+            raw = (Class<?>)pt.getRawType();
+        } else if (t instanceof Class<?>) {
+            raw = (Class<?>)t;
+            /* 24-Mar-2010, tatu: Can not have true generics definitions, but can
+             *   have lower bounds ("<T extends BeanBase>") in declaration itself
+             */
+            TypeVariable<?>[] vars = raw.getTypeParameters();
+            if (vars != null && vars.length > 0) {
+                for (TypeVariable<?> var : vars) {
+                    String name = var.getName();
+                    Type varType = var.getBounds()[0];
+                    if (varType != null) {
+                        if (_bindings == null) {
+                            _bindings = new HashMap<String, JavaType>();
+                        } else { // and no overwriting...
+                            if (_bindings.containsKey(name))
+                                continue;
+                        }
+                        _addPlaceholder(name); // to prevent infinite loops
+                        _bindings.put(name, TypeFactory.instance._fromType(varType, this));
+                    }
+                }
+            }
+        } else { // probably can't be any of these... so let's skip for now
+            //if (type instanceof GenericArrayType) {
+            //if (type instanceof TypeVariable<?>) {
+            // if (type instanceof WildcardType) {
+            return;
+        }
+        // but even if it's not a parameterized type, its super types may be:
+        _resolveBindings(raw.getGenericSuperclass());
+        for (Type intType : raw.getGenericInterfaces()) {
+            _resolveBindings(intType);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (_bindings == null) {
+            _resolve();
+        }
+        StringBuilder sb = new StringBuilder("[TypeBindings for ");
+        if (_contextType != null) {
+            sb.append(_contextType.toString());
+        } else {
+            sb.append(_contextClass.getName());
+        }
+        sb.append(": ").append(_bindings).append("]");
+        return sb.toString();
+    }
+}

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/type/TypeBindings.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date