You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by th...@apache.org on 2014/12/07 03:29:36 UTC
[38/45] tapestry-5 git commit: First pass creating the BeanModel and
Commons packages. Lots of stuff moved around,
but no actual code changes so far
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
deleted file mode 100644
index 81d1f77..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2006, 2007, 2010, 2011 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc;
-
-import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.ioc.services.MasterObjectProvider;
-
-import java.lang.annotation.Annotation;
-
-/**
- * Defines an object which can provide access to services defined within a {@link org.apache.tapestry5.ioc.Registry}, or
- * to objects or object instances available by other means. Services are accessed via service id, or
- * (when appropriate)
- * by just service interface. The Registry itself implements this interface, as does
- * {@link org.apache.tapestry5.ioc.ServiceResources}.
- */
-public interface ObjectLocator
-{
- /**
- * Obtains a service via its unique service id. Returns the service's proxy. The service proxy
- * implements the same
- * interface as the actual service, and is used to instantiate the actual service only as needed
- * (this is
- * transparent to the application).
- *
- * @param <T>
- * @param serviceId unique Service id used to locate the service object (may contain <em>symbols</em>,
- * which
- * will be expanded), case is ignored
- * @param serviceInterface the interface implemented by the service (or an interface extended by the service
- * interface)
- * @return the service instance
- * @throws RuntimeException if the service is not defined, or if an error occurs instantiating it
- */
- <T> T getService(String serviceId, Class<T> serviceInterface);
-
- /**
- * Locates a service given a service interface and (optionally) some marker annotation types. A single service must implement the service
- * interface (which * can be hard to guarantee) and by marked by all the marker types. The search takes into account inheritance of the service interface
- * (not the service <em>implementation</em>), which may result in a failure due to extra
- * matches.
- *
- * @param serviceInterface the interface the service implements
- * @return the service's proxy
- * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
- * services directly implement, or extend from, the service interface
- * @see org.apache.tapestry5.ioc.annotations.Marker
- */
- <T> T getService(Class<T> serviceInterface);
-
- /**
- * Locates a service given a service interface and (optionally) some marker annotation types. A single service must implement the service
- * interface (which * can be hard to guarantee) and by marked by all the marker types. The search takes into account inheritance of the service interface
- * (not the service <em>implementation</em>), which may result in a failure due to extra
- * matches. The ability to specify marker annotation types was added in 5.3
- *
- * @param serviceInterface the interface the service implements
- * @param markerTypes Markers used to select a specific service that implements the interface
- * @return the service's proxy
- * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
- * services directly implement, or extend from, the service interface
- * @see org.apache.tapestry5.ioc.annotations.Marker
- * @since 5.3
- */
- <T> T getService(Class<T> serviceInterface, Class<? extends Annotation>... markerTypes);
-
- /**
- * Obtains an object indirectly, using the {@link org.apache.tapestry5.ioc.services.MasterObjectProvider} service.
- *
- * @param objectType the type of object to be returned
- * @param annotationProvider provides access to annotations on the field or parameter for which a value is to
- * be
- * obtained, which may be utilized in selecting an appropriate object, use
- * <strong>null</strong> when annotations are not available (in which case, selection
- * will
- * be based only on the object type)
- * @param <T>
- * @return the requested object
- * @see ObjectProvider
- */
- <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider);
-
- /**
- * Autobuilds a class by finding the public constructor with the most parameters. Services and other resources or
- * dependencies will be injected into the parameters of the constructor and into private fields marked with the
- * {@link Inject} annotation. There are two cases: constructing a service implementation, and constructing
- * an arbitrary object. In the former case, many <em>service resources</em> are also available for injection, not
- * just dependencies or objects provided via
- * {@link MasterObjectProvider#provide(Class, AnnotationProvider, ObjectLocator, boolean)}.
- *
- * @param <T>
- * @param clazz the type of object to instantiate
- * @return the instantiated instance
- * @throws RuntimeException if the autobuild fails
- * @see MasterObjectProvider
- */
- <T> T autobuild(Class<T> clazz);
-
- /**
- * Preferred version of {@link #autobuild(Class)} that tracks the operation using
- * {@link OperationTracker#invoke(String, Invokable)}.
- *
- * @param <T>
- * @param description description used with {@link OperationTracker}
- * @param clazz the type of object to instantiate
- * @return the instantiated instance
- * @throws RuntimeException if the autobuild fails
- * @see MasterObjectProvider
- * @since 5.2.0
- */
- <T> T autobuild(String description, Class<T> clazz);
-
- /**
- * Creates a proxy. The proxy will defer invocation of {@link #autobuild(Class)} until
- * just-in-time (that is, first method invocation). In a limited number of cases, it is necessary to use such a
- * proxy to prevent service construction cycles, particularly when contributing (directly or indirectly) to the
- * {@link org.apache.tapestry5.ioc.services.MasterObjectProvider} (which is itself at the heart
- * of autobuilding).
- * <p/>
- * If the class file for the class is a file on the file system (not a file packaged in a JAR), then the proxy will
- * <em>autoreload</em>: changing the class file will result in the new class being reloaded and re-instantiated
- * (with dependencies).
- *
- * @param <T>
- * @param interfaceClass the interface implemented by the proxy
- * @param implementationClass a concrete class that implements the interface
- * @return a proxy
- * @see #autobuild(Class)
- */
- <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass);
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Resource.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Resource.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Resource.java
deleted file mode 100644
index b81c1c5..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Resource.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Licensed 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.tapestry5.ioc;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Locale;
-
-/**
- * Represents a resource on the server that may be used for server side processing, or may be exposed to the client
- * side. Generally, this represents an abstraction on top of files on the class path and files stored in the web
- * application context.
- * <p/>
- * Resources are often used as map keys; they should be immutable and should implement hashCode() and equals().
- */
-public interface Resource
-{
-
- /**
- * Returns true if the resource exists; if a stream to the content of the file may be opened. A resource exists
- * if {@link #toURL()} returns a non-null value. Starting in release 5.3.4, the result of this is cached.
- * <p/>
- * Starting in 5.4, some "virtual resources", may return true even though {@link #toURL()} returns null.
- *
- * @return true if the resource exists, false if it does not
- */
- boolean exists();
-
-
- /**
- * Returns true if the resource is virtual, meaning this is no underlying file. Many operations are unsupported
- * on virtual resources, including {@link #toURL()}, {@link #forLocale(java.util.Locale)},
- * {@link #withExtension(String)}, {@link #getFile()}, {@link #getFolder()}, {@link #getPath()}}; these
- * operations will throw an {@link java.lang.UnsupportedOperationException}.
- *
- * @since 5.4
- */
- boolean isVirtual();
-
- /**
- * Opens a stream to the content of the resource, or returns null if the resource does not exist. The native
- * input stream supplied by the resource is wrapped in a {@link java.io.BufferedInputStream}.
- *
- * @return an open, buffered stream to the content, if available
- */
- InputStream openStream() throws IOException;
-
- /**
- * Returns the URL for the resource, or null if it does not exist. This value is lazily computed; starting in 5.3.4, subclasses may cache
- * the result. Starting in 5.4, some "virtual resources" may return null.
- */
- URL toURL();
-
- /**
- * Returns a localized version of the resource. May return null if no such resource exists. Starting in release
- * 5.3.4, the result of this method is cached internally.
- */
- Resource forLocale(Locale locale);
-
- /**
- * Returns a Resource based on a relative path, relative to the folder containing the resource. Understands the "."
- * (current folder) and ".." (parent folder) conventions, and treats multiple sequential slashes as a single slash.
- * <p/>
- * Virtual resources (resources fabricated at runtime) return themselves.
- */
- Resource forFile(String relativePath);
-
- /**
- * Returns a new Resource with the extension changed (or, if the resource does not have an extension, the extension
- * is added). The new Resource may not exist (that is, {@link #toURL()} may return null.
- *
- * @param extension
- * to apply to the resource, such as "html" or "properties"
- * @return the new resource
- */
- Resource withExtension(String extension);
-
- /**
- * Returns the portion of the path up to the last forward slash; this is the directory or folder portion of the
- * Resource.
- */
- String getFolder();
-
- /**
- * Returns the file portion of the Resource path, everything that follows the final forward slash.
- * <p/>
- * Starting in 5.4, certain kinds of "virtual resources" may return null here.
- */
- String getFile();
-
- /**
- * Return the path (the combination of folder and file).
- * <p/>
- * Starting in 5.4, certain "virtual resources", may return an arbitrary value here.
- */
- String getPath();
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/UsesConfiguration.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/UsesConfiguration.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/UsesConfiguration.java
deleted file mode 100644
index 2e03557..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/UsesConfiguration.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2008, 2009 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.annotations;
-
-import java.lang.annotation.*;
-
-
-/**
- * A documentation-only interface placed on service interfaces for services which have an {@linkplain
- * org.apache.tapestry5.ioc.Configuration unordered configuration}, to identify the type of contribution.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-@Documented
-@UseWith(AnnotationUseContext.SERVICE)
-public @interface UsesConfiguration
-{
- /**
- * The type of object which may be contributed into the service's configuration.
- */
- Class value();
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/NullAnnotationProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/NullAnnotationProvider.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/NullAnnotationProvider.java
deleted file mode 100644
index 716b7c6..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/NullAnnotationProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.internal;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-
-import java.lang.annotation.Annotation;
-
-/**
- * A null implementation of {@link AnnotationProvider}, used when there is not appropriate source of annotations.
- */
-public class NullAnnotationProvider implements AnnotationProvider
-{
- /**
- * Always returns null.
- */
- @Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
- {
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
deleted file mode 100644
index 6711b1a..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2006, 2007, 2012 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.internal.util;
-
-import org.apache.tapestry5.ioc.util.CaseInsensitiveMap;
-import org.apache.tapestry5.ioc.util.Stack;
-
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Static factory methods to ease the creation of new collection types (when using generics). Most of these method
- * leverage the compiler's ability to match generic types by return value. Typical usage (with a static import):
- * <p/>
- * <pre>
- * Map<Foo, Bar> map = newMap();
- * </pre>
- * <p/>
- * <p/>
- * This is a replacement for:
- * <p/>
- * <pre>
- * Map<Foo, Bar> map = new HashMap<Foo, Bar>();
- * </pre>
- */
-public final class CollectionFactory
-{
- /**
- * Constructs and returns a generic {@link HashMap} instance.
- */
- public static <K, V> Map<K, V> newMap()
- {
- return new HashMap<K, V>();
- }
-
- /**
- * Constructs and returns a generic {@link java.util.HashSet} instance.
- */
- public static <T> Set<T> newSet()
- {
- return new HashSet<T>();
- }
-
- /**
- * Contructs a new {@link HashSet} and initializes it using the provided collection.
- */
- public static <T, V extends T> Set<T> newSet(Collection<V> values)
- {
- return new HashSet<T>(values);
- }
-
- public static <T, V extends T> Set<T> newSet(V... values)
- {
- // Was a call to newSet(), but Sun JDK can't handle that. Fucking generics.
- return new HashSet<T>(Arrays.asList(values));
- }
-
- /**
- * Constructs a new {@link java.util.HashMap} instance by copying an existing Map instance.
- */
- public static <K, V> Map<K, V> newMap(Map<? extends K, ? extends V> map)
- {
- return new HashMap<K, V>(map);
- }
-
- /**
- * Constructs a new concurrent map, which is safe to access via multiple threads.
- */
- public static <K, V> ConcurrentMap<K, V> newConcurrentMap()
- {
- return new ConcurrentHashMap<K, V>();
- }
-
- /**
- * Contructs and returns a new generic {@link java.util.ArrayList} instance.
- */
- public static <T> List<T> newList()
- {
- return new ArrayList<T>();
- }
-
- /**
- * Creates a new, fully modifiable list from an initial set of elements.
- */
- public static <T, V extends T> List<T> newList(V... elements)
- {
- // Was call to newList(), but Sun JDK can't handle that.
- return new ArrayList<T>(Arrays.asList(elements));
- }
-
- /**
- * Useful for queues.
- */
- public static <T> LinkedList<T> newLinkedList()
- {
- return new LinkedList<T>();
- }
-
- /**
- * Constructs and returns a new {@link java.util.ArrayList} as a copy of the provided collection.
- */
- public static <T, V extends T> List<T> newList(Collection<V> list)
- {
- return new ArrayList<T>(list);
- }
-
- /**
- * Constructs and returns a new {@link java.util.concurrent.CopyOnWriteArrayList}.
- */
- public static <T> List<T> newThreadSafeList()
- {
- return new CopyOnWriteArrayList<T>();
- }
-
- public static <T> Stack<T> newStack()
- {
- return new Stack<T>();
- }
-
- public static <V> Map<String, V> newCaseInsensitiveMap()
- {
- return new CaseInsensitiveMap<V>();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/GenericsUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/GenericsUtils.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/GenericsUtils.java
deleted file mode 100644
index 1a6dd80..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/GenericsUtils.java
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright 2008, 2010 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.internal.util;
-
-import java.lang.reflect.*;
-import java.util.LinkedList;
-
-/**
- * Static methods related to the use of JDK 1.5 generics.
- */
-@SuppressWarnings("unchecked")
-public class GenericsUtils
-{
- /**
- * Analyzes the method in the context of containingClass and returns the Class that is represented by
- * the method's generic return type. Any parameter information in the generic return type is lost. If you want
- * to preserve the type parameters of the return type consider using
- * {@link #extractActualType(java.lang.reflect.Type, java.lang.reflect.Method)}.
- *
- * @param containingClass class which either contains or inherited the method
- * @param method method from which to extract the return type
- * @return the class represented by the methods generic return type, resolved based on the context .
- * @see #extractActualType(java.lang.reflect.Type, java.lang.reflect.Method)
- * @see #resolve(java.lang.reflect.Type,java.lang.reflect.Type)
- * @see #asClass(java.lang.reflect.Type)
- */
- public static Class<?> extractGenericReturnType(Class<?> containingClass, Method method)
- {
- return asClass(resolve(method.getGenericReturnType(), containingClass));
- }
-
-
- /**
- * Analyzes the field in the context of containingClass and returns the Class that is represented by
- * the field's generic type. Any parameter information in the generic type is lost, if you want
- * to preserve the type parameters of the return type consider using
- * {@link #getTypeVariableIndex(java.lang.reflect.TypeVariable)}.
- *
- * @param containingClass class which either contains or inherited the field
- * @param field field from which to extract the type
- * @return the class represented by the field's generic type, resolved based on the containingClass.
- * @see #extractActualType(java.lang.reflect.Type, java.lang.reflect.Field)
- * @see #resolve(java.lang.reflect.Type,java.lang.reflect.Type)
- * @see #asClass(java.lang.reflect.Type)
- */
- public static Class extractGenericFieldType(Class containingClass, Field field)
- {
- return asClass(resolve(field.getGenericType(), containingClass));
- }
-
- /**
- * Analyzes the method in the context of containingClass and returns the Class that is represented by
- * the method's generic return type. Any parameter information in the generic return type is lost.
- *
- * @param containingType Type which is/represents the class that either contains or inherited the method
- * @param method method from which to extract the generic return type
- * @return the generic type represented by the methods generic return type, resolved based on the containingType.
- * @see #resolve(java.lang.reflect.Type,java.lang.reflect.Type)
- */
- public static Type extractActualType(Type containingType, Method method)
- {
- return resolve(method.getGenericReturnType(), containingType);
- }
-
- /**
- * Analyzes the method in the context of containingClass and returns the Class that is represented by
- * the method's generic return type. Any parameter information in the generic return type is lost.
- *
- * @param containingType Type which is/represents the class that either contains or inherited the field
- * @param field field from which to extract the generic return type
- * @return the generic type represented by the methods generic return type, resolved based on the containingType.
- * @see #resolve(java.lang.reflect.Type,java.lang.reflect.Type)
- */
- public static Type extractActualType(Type containingType, Field field)
- {
- return resolve(field.getGenericType(), containingType);
- }
-
- /**
- * Resolves the type parameter based on the context of the containingType.
- * <p/>
- * {@link java.lang.reflect.TypeVariable} will be unwrapped to the type argument resolved form the class
- * hierarchy. This may be something other than a simple Class if the type argument is a ParameterizedType for
- * instance (e.g. List<E>; List<Map<Long, String>>, E would be returned as a ParameterizedType with the raw
- * type Map and type arguments Long and String.
- * <p/>
- *
- * @param type
- * the generic type (ParameterizedType, GenericArrayType, WildcardType, TypeVariable) to be resolved
- * @param containingType
- * the type which his
- * @return
- * the type resolved to the best of our ability.
- * @since 5.2.?
- */
- public static Type resolve(final Type type, final Type containingType)
- {
- // The type isn't generic. (String, Long, etc)
- if (type instanceof Class)
- return type;
-
- // List<T>, List<String>, List<T extends Number>
- if (type instanceof ParameterizedType)
- return resolve((ParameterizedType) type, containingType);
-
- // T[], List<String>[], List<T>[]
- if (type instanceof GenericArrayType)
- return resolve((GenericArrayType) type, containingType);
-
- // List<? extends T>, List<? extends Object & Comparable & Serializable>
- if (type instanceof WildcardType)
- return resolve((WildcardType) type, containingType);
-
- // T
- if (type instanceof TypeVariable)
- return resolve((TypeVariable) type, containingType);
-
- // I'm leaning towards an exception here.
- return type;
- }
-
-
- /**
- * Determines if the suspected super type is assignable from the suspected sub type.
- *
- * @param suspectedSuperType
- * e.g. GenericDAO<Pet, String>
- * @param suspectedSubType
- * e.g. PetDAO extends GenericDAO<Pet,String>
- * @return
- * true if (sourceType)targetClass is a valid cast
- */
- public static boolean isAssignableFrom(Type suspectedSuperType, Type suspectedSubType)
- {
- final Class suspectedSuperClass = asClass(suspectedSuperType);
- final Class suspectedSubClass = asClass(suspectedSubType);
-
- // The raw types need to be compatible.
- if (!suspectedSuperClass.isAssignableFrom(suspectedSubClass))
- {
- return false;
- }
-
- // From this point we know that the raw types are assignable.
- // We need to figure out what the generic parameters in the targetClass are
- // as they pertain to the sourceType.
-
- if (suspectedSuperType instanceof WildcardType)
- {
- // ? extends Number
- // needs to match all the bounds (there will only be upper bounds or lower bounds
- for (Type t : ((WildcardType) suspectedSuperType).getUpperBounds())
- {
- if (!isAssignableFrom(t, suspectedSubType)) return false;
- }
- for (Type t : ((WildcardType) suspectedSuperType).getLowerBounds())
- {
- if (!isAssignableFrom(suspectedSubType, t)) return false;
- }
- return true;
- }
-
- Type curType = suspectedSubType;
- Class curClass;
-
- while (curType != null && !curType.equals(Object.class))
- {
- curClass = asClass(curType);
-
- if (curClass.equals(suspectedSuperClass))
- {
- final Type resolved = resolve(curType, suspectedSubType);
-
- if (suspectedSuperType instanceof Class)
- {
- if ( resolved instanceof Class )
- return suspectedSuperType.equals(resolved);
-
- // They may represent the same class, but the suspectedSuperType is not parameterized. The parameter
- // types default to Object so they must be a match.
- // e.g. Pair p = new StringLongPair();
- // Pair p = new Pair<? extends Number, String>
-
- return true;
- }
-
- if (suspectedSuperType instanceof ParameterizedType)
- {
- if (resolved instanceof ParameterizedType)
- {
- final Type[] type1Arguments = ((ParameterizedType) suspectedSuperType).getActualTypeArguments();
- final Type[] type2Arguments = ((ParameterizedType) resolved).getActualTypeArguments();
- if (type1Arguments.length != type2Arguments.length) return false;
-
- for (int i = 0; i < type1Arguments.length; ++i)
- {
- if (!isAssignableFrom(type1Arguments[i], type2Arguments[i])) return false;
- }
- return true;
- }
- }
- else if (suspectedSuperType instanceof GenericArrayType)
- {
- if (resolved instanceof GenericArrayType)
- {
- return isAssignableFrom(
- ((GenericArrayType) suspectedSuperType).getGenericComponentType(),
- ((GenericArrayType) resolved).getGenericComponentType()
- );
- }
- }
-
- return false;
- }
-
- final Type[] types = curClass.getGenericInterfaces();
- for (Type t : types)
- {
- final Type resolved = resolve(t, suspectedSubType);
- if (isAssignableFrom(suspectedSuperType, resolved))
- return true;
- }
-
- curType = curClass.getGenericSuperclass();
- }
- return false;
- }
-
- /**
- * Get the class represented by the reflected type.
- * This method is lossy; You cannot recover the type information from the class that is returned.
- * <p/>
- * {@code TypeVariable} the first bound is returned. If your type variable extends multiple interfaces that information
- * is lost.
- * <p/>
- * {@code WildcardType} the first lower bound is returned. If the wildcard is defined with upper bounds
- * then {@code Object} is returned.
- *
- * @param actualType
- * a Class, ParameterizedType, GenericArrayType
- * @return the un-parameterized class associated with the type.
- */
- public static Class asClass(Type actualType)
- {
- if (actualType instanceof Class) return (Class) actualType;
-
- if (actualType instanceof ParameterizedType)
- {
- final Type rawType = ((ParameterizedType) actualType).getRawType();
- // The sun implementation returns getRawType as Class<?>, but there is room in the interface for it to be
- // some other Type. We'll assume it's a Class.
- // TODO: consider logging or throwing our own exception for that day when "something else" causes some confusion
- return (Class) rawType;
- }
-
- if (actualType instanceof GenericArrayType)
- {
- final Type type = ((GenericArrayType) actualType).getGenericComponentType();
- return Array.newInstance(asClass(type), 0).getClass();
- }
-
- if (actualType instanceof TypeVariable)
- {
- // Support for List<T extends Number>
- // There is always at least one bound. If no bound is specified in the source then it will be Object.class
- return asClass(((TypeVariable) actualType).getBounds()[0]);
- }
-
- if (actualType instanceof WildcardType)
- {
- final WildcardType wildcardType = (WildcardType) actualType;
- final Type[] bounds = wildcardType.getLowerBounds();
- if (bounds != null && bounds.length > 0)
- {
- return asClass(bounds[0]);
- }
- // If there is no lower bounds then the only thing that makes sense is Object.
- return Object.class;
- }
-
- throw new RuntimeException(String.format("Unable to convert %s to Class.", actualType));
- }
-
- /**
- * Convert the type into a string. The string representation approximates the code that would be used to define the
- * type.
- *
- * @param type - the type.
- * @return a string representation of the type, similar to how it was declared.
- */
- public static String toString(Type type)
- {
- if ( type instanceof ParameterizedType ) return toString((ParameterizedType)type);
- if ( type instanceof WildcardType ) return toString((WildcardType)type);
- if ( type instanceof GenericArrayType) return toString((GenericArrayType)type);
- if ( type instanceof Class )
- {
- final Class theClass = (Class) type;
- return (theClass.isArray() ? theClass.getName() + "[]" : theClass.getName());
- }
- return type.toString();
- }
-
- /**
- * Method to resolve a TypeVariable to its most
- * <a href="http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#112582">reifiable</a> form.
- * <p/>
- * <p/>
- * How to resolve a TypeVariable:<br/>
- * All of the TypeVariables defined by a generic class will be given a Type by any class that extends it. The Type
- * given may or may not be reifiable; it may be another TypeVariable for instance.
- * <p/>
- * Consider <br/>
- * <i>class Pair>A,B> { A getA(){...}; ...}</i><br/>
- * <i>class StringLongPair extends Pair>String, Long> { }</i><br/>
- * <p/>
- * To resolve the actual return type of Pair.getA() you must first resolve the TypeVariable "A".
- * We can do that by first finding the index of "A" in the Pair.class.getTypeParameters() array of TypeVariables.
- * <p/>
- * To get to the Type provided by StringLongPair you access the generics information by calling
- * StringLongPair.class.getGenericSuperclass; this will be a ParameterizedType. ParameterizedType gives you access
- * to the actual type arguments provided to Pair by StringLongPair. The array is in the same order as the array in
- * Pair.class.getTypeParameters so you can use the index we discovered earlier to extract the Type; String.class.
- * <p/>
- * When extracting Types we only have to consider the superclass hierarchy and not the interfaces implemented by
- * the class. When a class implements a generic interface it must provide types for the interface and any generic
- * methods implemented from the interface will be re-defined by the class with its generic type variables.
- *
- * @param typeVariable - the type variable to resolve.
- * @param containingType - the shallowest class in the class hierarchy (furthest from Object) where typeVariable is defined.
- * @return a Type that has had all possible TypeVariables resolved that have been defined between the type variable
- * declaration and the containingType.
- */
- private static Type resolve(TypeVariable typeVariable, Type containingType)
- {
- // The generic declaration is either a Class, Method or Constructor
- final GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
-
- if (!(genericDeclaration instanceof Class))
- {
- // It's a method or constructor. The best we can do here is try to resolve the bounds
- // e.g. <T extends E> T getT(T param){} where E is defined by the class.
- final Type bounds0 = typeVariable.getBounds()[0];
- return resolve(bounds0, containingType);
- }
-
- final Class typeVariableOwner = (Class) genericDeclaration;
-
- // find the typeOwner in the containingType's hierarchy
- final LinkedList<Type> stack = new LinkedList<Type>();
-
- // If you pass a List<Long> as the containingType then the TypeVariable is going to be resolved by the
- // containingType and not the super class.
- if (containingType instanceof ParameterizedType)
- {
- stack.add(containingType);
- }
-
- Class theClass = asClass(containingType);
- Type genericSuperclass = theClass.getGenericSuperclass();
- while (genericSuperclass != null && // true for interfaces with no superclass
- !theClass.equals(Object.class) &&
- !theClass.equals(typeVariableOwner))
- {
- stack.addFirst(genericSuperclass);
- theClass = asClass(genericSuperclass);
- genericSuperclass = theClass.getGenericSuperclass();
- }
-
- int i = getTypeVariableIndex(typeVariable);
- Type resolved = typeVariable;
- for (Type t : stack)
- {
- if (t instanceof ParameterizedType)
- {
- resolved = ((ParameterizedType) t).getActualTypeArguments()[i];
- if (resolved instanceof Class) return resolved;
- if (resolved instanceof TypeVariable)
- {
- // Need to look at the next class in the hierarchy
- i = getTypeVariableIndex((TypeVariable) resolved);
- continue;
- }
- return resolve(resolved, containingType);
- }
- }
-
- // the only way we get here is if resolved is still a TypeVariable, otherwise an
- // exception is thrown or a value is returned.
- return ((TypeVariable) resolved).getBounds()[0];
- }
-
- /**
- * @param type - something like List<T>[] or List<? extends T>[] or T[]
- * @param containingType - the shallowest type in the hierarchy where type is defined.
- * @return either the passed type if no changes required or a copy with a best effort resolve of the component type.
- */
- private static GenericArrayType resolve(GenericArrayType type, Type containingType)
- {
- final Type componentType = type.getGenericComponentType();
-
- if (!(componentType instanceof Class))
- {
- final Type resolved = resolve(componentType, containingType);
- return create(resolved);
- }
-
- return type;
- }
-
- /**
- * @param type - something like List<T>, List<T extends Number>
- * @param containingType - the shallowest type in the hierarchy where type is defined.
- * @return the passed type if nothing to resolve or a copy of the type with the type arguments resolved.
- */
- private static ParameterizedType resolve(ParameterizedType type, Type containingType)
- {
- // Use a copy because we're going to modify it.
- final Type[] types = type.getActualTypeArguments().clone();
-
- boolean modified = resolve(types, containingType);
- return modified ? create(type.getRawType(), type.getOwnerType(), types) : type;
- }
-
- /**
- * @param type - something like List<? super T>, List<<? extends T>, List<? extends T & Comparable<? super T>>
- * @param containingType - the shallowest type in the hierarchy where type is defined.
- * @return the passed type if nothing to resolve or a copy of the type with the upper and lower bounds resolved.
- */
- private static WildcardType resolve(WildcardType type, Type containingType)
- {
- // Use a copy because we're going to modify them.
- final Type[] upper = type.getUpperBounds().clone();
- final Type[] lower = type.getLowerBounds().clone();
-
- boolean modified = resolve(upper, containingType);
- modified = modified || resolve(lower, containingType);
-
- return modified ? create(upper, lower) : type;
- }
-
- /**
- * @param types - Array of types to resolve. The unresolved type is replaced in the array with the resolved type.
- * @param containingType - the shallowest type in the hierarchy where type is defined.
- * @return true if any of the types were resolved.
- */
- private static boolean resolve(Type[] types, Type containingType)
- {
- boolean modified = false;
- for (int i = 0; i < types.length; ++i)
- {
- Type t = types[i];
- if (!(t instanceof Class))
- {
- modified = true;
- final Type resolved = resolve(t, containingType);
- if (!resolved.equals(t))
- {
- types[i] = resolved;
- modified = true;
- }
- }
- }
- return modified;
- }
-
- /**
- * @param rawType - the un-parameterized type.
- * @param ownerType - the outer class or null if the class is not defined within another class.
- * @param typeArguments - type arguments.
- * @return a copy of the type with the typeArguments replaced.
- */
- static ParameterizedType create(final Type rawType, final Type ownerType, final Type[] typeArguments)
- {
- return new ParameterizedType()
- {
- @Override
- public Type[] getActualTypeArguments()
- {
- return typeArguments;
- }
-
- @Override
- public Type getRawType()
- {
- return rawType;
- }
-
- @Override
- public Type getOwnerType()
- {
- return ownerType;
- }
-
- @Override
- public String toString()
- {
- return GenericsUtils.toString(this);
- }
- };
- }
-
- static GenericArrayType create(final Type componentType)
- {
- return new GenericArrayType()
- {
- @Override
- public Type getGenericComponentType()
- {
- return componentType;
- }
-
- @Override
- public String toString()
- {
- return GenericsUtils.toString(this);
- }
- };
- }
-
- /**
- * @param upperBounds - e.g. ? extends Number
- * @param lowerBounds - e.g. ? super Long
- * @return An new copy of the type with the upper and lower bounds replaced.
- */
- static WildcardType create(final Type[] upperBounds, final Type[] lowerBounds)
- {
-
- return new WildcardType()
- {
- @Override
- public Type[] getUpperBounds()
- {
- return upperBounds;
- }
-
- @Override
- public Type[] getLowerBounds()
- {
- return lowerBounds;
- }
-
- @Override
- public String toString()
- {
- return GenericsUtils.toString(this);
- }
- };
- }
-
- static String toString(ParameterizedType pt)
- {
- String s = toString(pt.getActualTypeArguments());
- return String.format("%s<%s>", toString(pt.getRawType()), s);
- }
-
- static String toString(GenericArrayType gat)
- {
- return String.format("%s[]", toString(gat.getGenericComponentType()));
- }
-
- static String toString(WildcardType wt)
- {
- final boolean isSuper = wt.getLowerBounds().length > 0;
- return String.format("? %s %s",
- isSuper ? "super" : "extends",
- isSuper ? toString(wt.getLowerBounds()) : toString(wt.getLowerBounds()));
- }
-
- static String toString(Type[] types)
- {
- StringBuilder sb = new StringBuilder();
- for ( Type t : types )
- {
- sb.append(toString(t)).append(", ");
- }
- return sb.substring(0, sb.length() - 2);// drop last ,
- }
-
- /**
- * Find the index of the TypeVariable in the classes parameters. The offset can be used on a subclass to find
- * the actual type.
- *
- * @param typeVariable - the type variable in question.
- * @return the index of the type variable in its declaring class/method/constructor's type parameters.
- */
- private static int getTypeVariableIndex(final TypeVariable typeVariable)
- {
- // the label from the class (the T in List<T>, the K or V in Map<K,V>, etc)
- final String typeVarName = typeVariable.getName();
- final TypeVariable[] typeParameters = typeVariable.getGenericDeclaration().getTypeParameters();
- for (int typeArgumentIndex = 0; typeArgumentIndex < typeParameters.length; typeArgumentIndex++)
- {
- // The .equals for TypeVariable may not be compatible, a name check should be sufficient.
- if (typeParameters[typeArgumentIndex].getName().equals(typeVarName))
- return typeArgumentIndex;
- }
-
- // The only way this could happen is if the TypeVariable is hand built incorrectly, or it's corrupted.
- throw new RuntimeException(
- String.format("%s does not have a TypeVariable matching %s", typeVariable.getGenericDeclaration(), typeVariable));
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
deleted file mode 100644
index ef217cb..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.internal.util;
-
-import org.apache.tapestry5.ioc.Locatable;
-import org.apache.tapestry5.ioc.Location;
-
-/**
- * Exception class used as a replacement for {@link java.lang.RuntimeException} when the exception is related to a
- * particular location.
- */
-public class TapestryException extends RuntimeException implements Locatable
-{
- private static final long serialVersionUID = 6396903640977182682L;
-
- private transient final Location location;
-
- /**
- * @param message a message (may be null)
- * @param location implements {@link Location} or {@link Locatable}
- * @param cause if not null, the root cause of the exception
- */
- public TapestryException(String message, Object location, Throwable cause)
- {
- this(message, InternalUtils.locationOf(location), cause);
- }
-
- /**
- * @param message a message (may be null)
- * @param cause if not null, the root cause of the exception, also used to set the location
- */
- public TapestryException(String message, Throwable cause)
- {
- this(message, cause, cause);
- }
-
- /**
- * @param message a message (may be null)
- * @param location location to associated with the exception, or null if not known
- * @param cause if not null, the root cause of the exception
- */
- public TapestryException(String message, Location location, Throwable cause)
- {
- super(message, cause);
-
- this.location = location;
- }
-
- @Override
- public Location getLocation()
- {
- return location;
- }
-
- @Override
- public String toString()
- {
- if (location == null) return super.toString();
-
- return String.format("%s [at %s]", super.toString(), location);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassPropertyAdapter.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassPropertyAdapter.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassPropertyAdapter.java
deleted file mode 100644
index 6159ed3..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassPropertyAdapter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2006, 2007, 2011 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-import java.lang.annotation.Annotation;
-import java.util.List;
-
-/**
- * Organizes all {@link org.apache.tapestry5.ioc.services.PropertyAdapter}s for a particular class.
- * <p/>
- * Only provides access to <em>simple</em> properties. Indexed properties are ignored.
- * <p/>
- * When accessing properties by name, the case of the name is ignored.
- */
-public interface ClassPropertyAdapter
-{
- /**
- * Returns the names of all properties, sorted into alphabetic order. This includes true properties
- * (as defined in the JavaBeans specification), but also public fields. Starting in Tapestry 5.3, even public static fields are included.
- */
- List<String> getPropertyNames();
-
- /**
- * Returns the type of bean this adapter provides properties for.
- */
- Class getBeanType();
-
- /**
- * Returns the property adapter with the given name, or null if no such adapter exists.
- *
- * @param name of the property (case is ignored)
- */
- PropertyAdapter getPropertyAdapter(String name);
-
- /**
- * Reads the value of a property.
- *
- * @param instance the object to read a value from
- * @param propertyName the name of the property to read (case is ignored)
- * @throws UnsupportedOperationException if the property is write only
- * @throws IllegalArgumentException if property does not exist
- */
- Object get(Object instance, String propertyName);
-
- /**
- * Updates the value of a property.
- *
- * @param instance the object to update
- * @param propertyName the name of the property to update (case is ignored)
- * @throws UnsupportedOperationException if the property is read only
- * @throws IllegalArgumentException if property does not exist
- */
- void set(Object instance, String propertyName, Object value);
-
- /**
- * Returns the annotation of a given property for the specified type if such an annotation is present, else null.
- *
- * @param instance the object to read a value from
- * @param propertyName the name of the property to read (case is ignored)
- * @param annotationClass the type of annotation to return
- *
- * @throws IllegalArgumentException if property does not exist
- *
- * @since 5.4
- */
- Annotation getAnnotation(Object instance, String propertyName, Class<? extends Annotation> annotationClass);
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/Coercion.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/Coercion.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/Coercion.java
deleted file mode 100644
index b7a4cc8..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/Coercion.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-/**
- * Responsible for converting from one type to another. This is used primarily around component parameters.
- *
- * @param <S> the source type (input)
- * @param <T> the target type (output)
- */
-public interface Coercion<S, T>
-{
- /**
- * Converts an input value.
- *
- * @param input the input value
- */
- T coerce(S input);
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
deleted file mode 100644
index 746de1e..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/CoercionTuple.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2006, 2007, 2008, 2010, 2011, 2012 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-import org.apache.tapestry5.plastic.PlasticUtils;
-
-/**
- * An immutable object that represents a mapping from one type to another. This is also the contribution type when
- * building the {@link org.apache.tapestry5.ioc.services.TypeCoercer} service. Wraps a
- * {@link org.apache.tapestry5.ioc.services.Coercion} object that performs the work with additional properties that
- * describe
- * the input and output types of the coercion, needed when searching for an appropriate coercion (or sequence of
- * coercions).
- *
- * @param <S>
- * source (input) type
- * @param <T>
- * target (output) type
- */
-public final class CoercionTuple<S, T>
-{
- private final Class<S> sourceType;
-
- private final Class<T> targetType;
-
- private final Coercion<S, T> coercion;
-
- /**
- * Wraps an arbitrary coercion with an implementation of toString() that identifies the source and target types.
- */
- private class CoercionWrapper<WS, WT> implements Coercion<WS, WT>
- {
- private final Coercion<WS, WT> coercion;
-
- public CoercionWrapper(Coercion<WS, WT> coercion)
- {
- this.coercion = coercion;
- }
-
- @Override
- public WT coerce(WS input)
- {
- return coercion.coerce(input);
- }
-
- @Override
- public String toString()
- {
- return String.format("%s --> %s", convert(sourceType), convert(targetType));
- }
- }
-
- private String convert(Class type)
- {
- if (Void.class.equals(type))
- return "null";
-
- String name = PlasticUtils.toTypeName(type);
-
- int dotx = name.lastIndexOf('.');
-
- // Strip off a package name of "java.lang"
-
- if (dotx > 0 && name.substring(0, dotx).equals("java.lang"))
- return name.substring(dotx + 1);
-
- return name;
- }
-
- /**
- * Standard constructor, which defaults wrap to true.
- */
- public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion)
- {
- this(sourceType, targetType, coercion, true);
- }
-
- /**
- * Convenience constructor to help with generics.
- *
- * @since 5.2.0
- */
- public static <S, T> CoercionTuple<S, T> create(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion)
- {
- return new CoercionTuple<S, T>(sourceType, targetType, coercion);
- }
-
- /**
- * Internal-use constructor.
- *
- * @param sourceType
- * the source (or input) type of the coercion, may be Void.class to indicate a coercion from null
- * @param targetType
- * the target (or output) type of the coercion
- * @param coercion
- * the object that performs the coercion
- * @param wrap
- * if true, the coercion is wrapped to provide a useful toString()
- */
- @SuppressWarnings("unchecked")
- public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion, boolean wrap)
- {
- assert sourceType != null;
- assert targetType != null;
- assert coercion != null;
-
- this.sourceType = PlasticUtils.toWrapperType(sourceType);
- this.targetType = PlasticUtils.toWrapperType(targetType);
- this.coercion = wrap ? new CoercionWrapper<S, T>(coercion) : coercion;
- }
-
- @Override
- public String toString()
- {
- return coercion.toString();
- }
-
- public Coercion<S, T> getCoercion()
- {
- return coercion;
- }
-
- public Class<S> getSourceType()
- {
- return sourceType;
- }
-
- public Class<T> getTargetType()
- {
- return targetType;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAccess.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAccess.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAccess.java
deleted file mode 100644
index ae542c5..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAccess.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2006, 2010, 2013 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-import java.lang.annotation.Annotation;
-
-/**
- * A wrapper around the JavaBean Introspector that allows more manageable access to JavaBean properties of objects.
- * <p/>
- * Only provides access to <em>simple</em> properties. Indexed properties are ignored.
- * <p>
- * Starting in Tapestry 5.2, public fields can now be accessed as if they were properly JavaBean properties. Where there
- * is a name conflict, the true property will be favored over the field access.
- */
-public interface PropertyAccess
-{
- /**
- * Reads the value of a property.
- *
- * @throws UnsupportedOperationException
- * if the property is write only
- * @throws IllegalArgumentException
- * if property does not exist
- */
- Object get(Object instance, String propertyName);
-
- /**
- * Updates the value of a property.
- *
- * @throws UnsupportedOperationException
- * if the property is read only
- * @throws IllegalArgumentException
- * if property does not exist
- */
- void set(Object instance, String propertyName, Object value);
-
- /**
- * Returns the annotation of a given property for the specified type if such an annotation is present, else null.
- * A convenience over invoking {@link #getAdapter(Object)}.{@link ClassPropertyAdapter#getPropertyAdapter(String)}.{@link PropertyAdapter#getAnnotation(Class)}
- *
- * @param instance the object to read a value from
- * @param propertyName the name of the property to read (case is ignored)
- * @param annotationClass the type of annotation to return
- * @throws IllegalArgumentException
- * if property does not exist
- *
- * @since 5.4
- */
- Annotation getAnnotation(Object instance, String propertyName, Class<? extends Annotation> annotationClass);
-
- /**
- * Returns the adapter for a particular object instance. A convienience over invoking {@link #getAdapter(Class)}.
- */
- ClassPropertyAdapter getAdapter(Object instance);
-
- /**
- * Returns the adapter used to access properties within the indicated class.
- */
- ClassPropertyAdapter getAdapter(Class forClass);
-
- /**
- * Discards all stored property access information, discarding all created class adapters.
- */
- void clearCache();
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAdapter.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAdapter.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAdapter.java
deleted file mode 100644
index 947535e..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PropertyAdapter.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2006, 2008, 2010, 2011 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-/**
- * Provides access to a single property within a class. Acts as an {@link org.apache.tapestry5.ioc.AnnotationProvider};
- * when searching for annotations, the read method (if present) is checked first, followed by the write method, followed
- * by the underlying field (when the property name matches the field name).
- * <p/>
- * Starting in release 5.2, this property may actually be a public field. In 5.3, it may be a public static field.
- *
- * @see org.apache.tapestry5.ioc.services.ClassPropertyAdapter
- */
-@SuppressWarnings("unchecked")
-public interface PropertyAdapter extends AnnotationProvider
-{
- /**
- * Returns the name of the property (or public field).
- */
- String getName();
-
- /**
- * Returns true if the property is readable (i.e., has a getter method or is a public field).
- */
- boolean isRead();
-
- /**
- * Returns the method used to read the property, or null if the property is not readable (or is a public field).
- */
- public Method getReadMethod();
-
- /**
- * Returns true if the property is writeable (i.e., has a setter method or is a non-final field).
- */
- boolean isUpdate();
-
- /**
- * Returns the method used to update the property, or null if the property is not writeable (or a public field).
- */
- public Method getWriteMethod();
-
- /**
- * Reads the property value.
- *
- * @param instance to read from
- * @throws UnsupportedOperationException if the property is write only
- */
- Object get(Object instance);
-
- /**
- * Updates the property value. The provided value must not be null if the property type is primitive, and must
- * otherwise be of the proper type.
- *
- * @param instance to update
- * @param value new value for the property
- * @throws UnsupportedOperationException if the property is read only
- */
- void set(Object instance, Object value);
-
- /**
- * Returns the type of the property.
- */
- Class getType();
-
- /**
- * Returns true if the return type of the read method is not the same as the property type. This can occur when the
- * property has been defined using generics, in which case, the method's type may be Object when the property type
- * is something more specific. This method is primarily used when generating runtime code related to the property.
- */
- boolean isCastRequired();
-
- /**
- * Returns the {@link org.apache.tapestry5.ioc.services.ClassPropertyAdapter} that provides access to other
- * properties defined by the same class.
- */
- ClassPropertyAdapter getClassAdapter();
-
- /**
- * Returns the type of bean to which this property belongs. This is the same as
- * {@link org.apache.tapestry5.ioc.services.ClassPropertyAdapter#getBeanType()}.
- */
- Class getBeanType();
-
- /**
- * Returns true if the property is actually a public field (possibly, a public static field).
- *
- * @since 5.2
- */
- boolean isField();
-
- /**
- * Returns the field if the property is a public field or null if the property is accessed via the read method.
- *
- * @since 5.2
- */
- Field getField();
-
- /**
- * The class in which the property (or public field) is defined.
- *
- * @since 5.2
- */
- Class getDeclaringClass();
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java
deleted file mode 100644
index ec8eaad..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.services;
-
-import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
-
-/**
- * Makes use of {@link org.apache.tapestry5.ioc.services.Coercion}s to convert between an input value (of some specific
- * type) and a desired output type. Smart about coercing, even if it requires multiple coercion steps (i.e., via an
- * intermediate type, such as String).
- */
-@UsesConfiguration(CoercionTuple.class)
-public interface TypeCoercer
-{
- /**
- * Performs a coercion from an input type to a desired output type. When the target type is a primitive, the actual
- * conversion will be to the equivalent wrapper type. In some cases, the TypeCoercer will need to search for an
- * appropriate coercion, and may even combine existing coercions to form new ones; in those cases, the results of
- * the search are cached.
- * <p/>
- * The TypeCoercer also caches the results of a coercion search.
- *
- * @param <S>
- * source type (input)
- * @param <T>
- * target type (output)
- * @param input
- * @param targetType
- * defines the target type
- * @return the coerced value
- * @throws RuntimeException
- * if the input can not be coerced
- */
- <S, T> T coerce(S input, Class<T> targetType);
-
- /**
- * Given a source and target type, computes the coercion that will be used.
- * <p>
- * Note: holding the returned coercion past the time when {@linkplain #clearCache() the cache is cleared} can cause
- * a memory leak, especially in the context of live reloading (wherein holding a reference to a single class make
- * keep an entire ClassLoader from being reclaimed).
- *
- * @since 5.2.0
- * @param <S>
- * source type (input)
- * @param <T>
- * target type (output)
- * @param sourceType
- * type to coerce from
- * @param targetType
- * defines the target type
- * @return the coercion that will ultimately be used
- */
- <S, T> Coercion<S, T> getCoercion(Class<S> sourceType, Class<T> targetType);
-
- /**
- * Used primarily inside test suites, this method performs the same steps as {@link #coerce(Object, Class)}, but
- * returns a string describing the series of coercions, such as "Object --> String --> Long --> Integer".
- *
- * @param <S>
- * source type (input)
- * @param <T>
- * target type (output)
- * @param sourceType
- * the source coercion type (use void.class for coercions from null)
- * @param targetType
- * defines the target type
- * @return a string identifying the series of coercions, or the empty string if no coercion is necessary
- */
- <S, T> String explain(Class<S> sourceType, Class<T> targetType);
-
- /**
- * Clears cached information stored by the TypeCoercer.
- */
- void clearCache();
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
deleted file mode 100644
index c4c5c6d..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2010 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-
-/**
- * Used (as part of a {@link UnknownValueException} to identify what available values
- * are present.
- *
- * @since 5.2.0
- */
-public class AvailableValues
-{
- private final String valueType;
-
- private final List<String> values;
-
- /**
- * @param valueType
- * a word or phrase that describes what the values are such as "component types" or "service ids"
- *@param values
- * a set of objects defining the values; the values will be converted to strings and sorted into
- * ascending order
- */
- public AvailableValues(String valueType, Collection<?> values)
- {
- this.valueType = valueType;
- this.values = sortValues(values);
- }
-
- public AvailableValues(String valueType, Map<?, ?> map)
- {
- this(valueType, map.keySet());
- }
-
- private static List<String> sortValues(Collection<?> values)
- {
- List<String> result = CollectionFactory.newList();
-
- for (Object v : values)
- {
- result.add(String.valueOf(v));
- }
-
- Collections.sort(result);
-
- return Collections.unmodifiableList(result);
- }
-
- /** The type of value, i.e., "component types" or "service ids". */
- public String getValueType()
- {
- return valueType;
- }
-
- /** The values, as strings, in sorted order. */
- public List<String> getValues()
- {
- return values;
- }
-
- @Override
- public String toString()
- {
- return String.format("AvailableValues[%s: %s]", valueType, InternalUtils.join(values));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3d4de7e1/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
deleted file mode 100644
index f5aff7e..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/util/CaseInsensitiveMap.java
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// Licensed 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.tapestry5.ioc.util;
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * An mapped collection where the keys are always strings and access to values is case-insensitive. The case of keys in
- * the map is <em>maintained</em>, but on any access to a key (directly or indirectly), all key comparisons are
- * performed in a case-insensitive manner. The map implementation is intended to support a reasonably finite number
- * (dozens or hundreds, not thousands or millions of key/value pairs. Unlike HashMap, it is based on a sorted list of
- * entries rather than hash bucket. It is also geared towards a largely static map, one that is created and then used
- * without modification.
- *
- * @param <V> the type of value stored
- */
-public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Serializable
-{
- private static final long serialVersionUID = 3362718337611953298L;
-
- private static final int NULL_HASH = Integer.MIN_VALUE;
-
- private static final int DEFAULT_SIZE = 20;
-
- private static class CIMEntry<V> implements Map.Entry<String, V>, Serializable
- {
- private static final long serialVersionUID = 6713986085221148350L;
-
- private String key;
-
- private final int hashCode;
-
- V value;
-
- public CIMEntry(final String key, final int hashCode, V value)
- {
- this.key = key;
- this.hashCode = hashCode;
- this.value = value;
- }
-
- @Override
- public String getKey()
- {
- return key;
- }
-
- @Override
- public V getValue()
- {
- return value;
- }
-
- @Override
- public V setValue(V value)
- {
- V result = this.value;
-
- this.value = value;
-
- return result;
- }
-
- /**
- * Returns true if both keys are null, or if the provided key is the same as, or case-insensitively equal to,
- * the entrie's key.
- *
- * @param key to compare against
- * @return true if equal
- */
- @SuppressWarnings({ "StringEquality" })
- boolean matches(String key)
- {
- return key == this.key || (key != null && key.equalsIgnoreCase(this.key));
- }
-
- boolean valueMatches(Object value)
- {
- return value == this.value || (value != null && value.equals(this.value));
- }
- }
-
- private class EntrySetIterator implements Iterator
- {
- int expectedModCount = modCount;
-
- int index;
-
- int current = -1;
-
- @Override
- public boolean hasNext()
- {
- return index < size;
- }
-
- @Override
- public Object next()
- {
- check();
-
- if (index >= size) throw new NoSuchElementException();
-
- current = index++;
-
- return entries[current];
- }
-
- @Override
- public void remove()
- {
- check();
-
- if (current < 0) throw new NoSuchElementException();
-
- new Position(current, true).remove();
-
- expectedModCount = modCount;
- }
-
- private void check()
- {
- if (expectedModCount != modCount) throw new ConcurrentModificationException();
- }
- }
-
- @SuppressWarnings("unchecked")
- private class EntrySet extends AbstractSet
- {
- @Override
- public Iterator iterator()
- {
- return new EntrySetIterator();
- }
-
- @Override
- public int size()
- {
- return size;
- }
-
- @Override
- public void clear()
- {
- CaseInsensitiveMap.this.clear();
- }
-
- @Override
- public boolean contains(Object o)
- {
- if (!(o instanceof Map.Entry)) return false;
-
- Map.Entry e = (Map.Entry) o;
-
- Position position = select(e.getKey());
-
- return position.isFound() && position.entry().valueMatches(e.getValue());
- }
-
- @Override
- public boolean remove(Object o)
- {
- if (!(o instanceof Map.Entry)) return false;
-
- Map.Entry e = (Map.Entry) o;
-
- Position position = select(e.getKey());
-
- if (position.isFound() && position.entry().valueMatches(e.getValue()))
- {
- position.remove();
- return true;
- }
-
- return false;
- }
-
- }
-
- private class Position
- {
- private final int cursor;
-
- private final boolean found;
-
- Position(int cursor, boolean found)
- {
- this.cursor = cursor;
- this.found = found;
- }
-
- boolean isFound()
- {
- return found;
- }
-
- CIMEntry<V> entry()
- {
- return entries[cursor];
- }
-
- V get()
- {
- return found ? entries[cursor].value : null;
- }
-
- V remove()
- {
- if (!found) return null;
-
- V result = entries[cursor].value;
-
- // Remove the entry by shifting everything else down.
-
- System.arraycopy(entries, cursor + 1, entries, cursor, size - cursor - 1);
-
- // We shifted down, leaving one (now duplicate) entry behind.
-
- entries[--size] = null;
-
- // A structural change for sure
-
- modCount++;
-
- return result;
- }
-
- @SuppressWarnings("unchecked")
- V put(String key, int hashCode, V newValue)
- {
- if (found)
- {
- CIMEntry<V> e = entries[cursor];
-
- V result = e.value;
-
- // Not a structural change, so no change to modCount
-
- // Update the key (to maintain case). By definition, the hash code
- // will not change.
-
- e.key = key;
- e.value = newValue;
-
- return result;
- }
-
- // Not found, we're going to add it.
-
- int newSize = size + 1;
-
- if (newSize == entries.length)
- {
- // Time to expand!
-
- int newCapacity = (size * 3) / 2 + 1;
-
- CIMEntry<V>[] newEntries = new CIMEntry[newCapacity];
-
- System.arraycopy(entries, 0, newEntries, 0, cursor);
-
- System.arraycopy(entries, cursor, newEntries, cursor + 1, size - cursor);
-
- entries = newEntries;
- }
- else
- {
- // Open up a space for the new entry
-
- System.arraycopy(entries, cursor, entries, cursor + 1, size - cursor);
- }
-
- CIMEntry<V> newEntry = new CIMEntry<V>(key, hashCode, newValue);
- entries[cursor] = newEntry;
-
- size++;
-
- // This is definately a structural change
-
- modCount++;
-
- return null;
- }
-
- }
-
- // The list of entries. This is kept sorted by hash code. In some cases, there may be different
- // keys with the same hash code in adjacent indexes.
- private CIMEntry<V>[] entries;
-
- private int size = 0;
-
- // Used by iterators to check for concurrent modifications
-
- private transient int modCount = 0;
-
- private transient Set<Map.Entry<String, V>> entrySet;
-
- public CaseInsensitiveMap()
- {
- this(DEFAULT_SIZE);
- }
-
- @SuppressWarnings("unchecked")
- public CaseInsensitiveMap(int size)
- {
- entries = new CIMEntry[Math.max(size, 3)];
- }
-
- public CaseInsensitiveMap(Map<String, ? extends V> map)
- {
- this(map.size());
-
- for (Map.Entry<String, ? extends V> entry : map.entrySet())
- {
- put(entry.getKey(), entry.getValue());
- }
- }
-
- @Override
- public void clear()
- {
- for (int i = 0; i < size; i++)
- entries[i] = null;
-
- size = 0;
- modCount++;
- }
-
- @Override
- public boolean isEmpty()
- {
- return size == 0;
- }
-
- @Override
- public int size()
- {
- return size;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V put(String key, V value)
- {
- int hashCode = caseInsenitiveHashCode(key);
-
- return select(key, hashCode).put(key, hashCode, value);
- }
-
- @Override
- public boolean containsKey(Object key)
- {
- return select(key).isFound();
- }
-
- @Override
- public V get(Object key)
- {
- return select(key).get();
- }
-
- @Override
- public V remove(Object key)
- {
- return select(key).remove();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Set<Map.Entry<String, V>> entrySet()
- {
- if (entrySet == null) entrySet = new EntrySet();
-
- return entrySet;
- }
-
- private Position select(Object key)
- {
- if (key == null || key instanceof String)
- {
- String keyString = (String) key;
- return select(keyString, caseInsenitiveHashCode(keyString));
- }
-
- return new Position(0, false);
- }
-
- /**
- * Searches the elements for the index of the indicated key and (case insensitive) hash code. Sets the _cursor and
- * _found attributes.
- */
- private Position select(String key, int hashCode)
- {
- if (size == 0) return new Position(0, false);
-
- int low = 0;
- int high = size - 1;
-
- int cursor;
-
- while (low <= high)
- {
- cursor = (low + high) >> 1;
-
- CIMEntry e = entries[cursor];
-
- if (e.hashCode < hashCode)
- {
- low = cursor + 1;
- continue;
- }
-
- if (e.hashCode > hashCode)
- {
- high = cursor - 1;
- continue;
- }
-
- return tunePosition(key, hashCode, cursor);
- }
-
- return new Position(low, false);
- }
-
- /**
- * select() has located a matching hashCode, but there's an outlying possibility that multiple keys share the same
- * hashCode. Backup the cursor until we get to locate the initial hashCode match, then march forward until the key
- * is located, or the hashCode stops matching.
- *
- * @param key
- * @param hashCode
- */
- private Position tunePosition(String key, int hashCode, int cursor)
- {
- boolean found = false;
-
- while (cursor > 0)
- {
- if (entries[cursor - 1].hashCode != hashCode) break;
-
- cursor--;
- }
-
- while (true)
- {
- if (entries[cursor].matches(key))
- {
- found = true;
- break;
- }
-
- // Advance to the next entry.
-
- cursor++;
-
- // If out of entries,
- if (cursor >= size || entries[cursor].hashCode != hashCode) break;
- }
-
- return new Position(cursor, found);
- }
-
- static int caseInsenitiveHashCode(String input)
- {
- if (input == null) return NULL_HASH;
-
- int length = input.length();
- int hash = 0;
-
- // This should end up more or less equal to input.toLowerCase().hashCode(), unless String
- // changes its implementation. Let's hope this is reasonably fast.
-
- for (int i = 0; i < length; i++)
- {
- int ch = input.charAt(i);
-
- int caselessCh = Character.toLowerCase(ch);
-
- hash = 31 * hash + caselessCh;
- }
-
- return hash;
- }
-
-}