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