http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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/f963c7ab/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; - } - -}