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:30 UTC
[32/45] tapestry-5 git commit: Fourth pass creating the BeanModel and
Commons packages.
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java
deleted file mode 100644
index 9151381..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/OrderedConfiguration.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2006, 2008, 2009, 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;
-
-/**
- * Object passed into a service contributor method that allows the method provide contributed values to the service's
- * configuration.
- * <p/>
- * A service can <em>collect</em> contributions in three different ways:
- * <ul>
- * <li>As an un-ordered collection of values</li>
- * <li>As an ordered list of values (where each value has a unique id, pre-requisites and post-requisites)</li>
- * <li>As a map of keys and values
- * </ul>
- * <p/>
- * The service defines the <em>type</em> of contribution, in terms of a base class or service interface. Contributions
- * must be compatible with the type, or be {@linkplain org.apache.tapestry5.ioc.services.TypeCoercer coercable} to the type.
- *
- * @see org.apache.tapestry5.ioc.annotations.Contribute
- * @see org.apache.tapestry5.ioc.annotations.UsesConfiguration
- */
-public interface OrderedConfiguration<T>
-{
- /**
- * Adds an ordered object to a service's contribution. Each object has an id (which must be unique). Optionally,
- * pre-requisites (a list of ids that must precede this object) and post-requisites (ids that must follow) can be
- * provided.
- * <p/>
- * <p>If no constraints are supplied, then an implicit constraint is supplied: after the previously
- * contributed id <em>within the same contribution method</em>.
- *
- * @param id a unique id for the object; the id will be fully qualified with the contributing module's id
- * @param constraints used to order the object relative to other contributed objects
- * @param object to add to the service's configuration
- */
- void add(String id, T object, String... constraints);
-
- /**
- * Overrides a normally contributed object. Each override must match a single normally contributed object.
- *
- * @param id identifies object to override
- * @param object overriding object (may be null)
- * @param constraints constraints for the overridden object, replacing constraints for the original object (even if
- * omitted, in which case the override object will have no ordering constraints)
- * @since 5.1.0.0
- */
- void override(String id, T object, String... constraints);
-
- /**
- * Adds an ordered object by instantiating (with dependencies) the indicated class. When the configuration type is
- * an interface and the class to be contributed is a local file,
- * then a reloadable proxy for the class will be created and contributed.
- *
- * @param id of contribution (used for ordering)
- * @param clazz class to instantiate
- * @param constraints used to order the object relative to other contributed objects
- * @since 5.1.0.0
- */
- void addInstance(String id, Class<? extends T> clazz, String... constraints);
-
- /**
- * Instantiates an object and adds it as an override. When the configuration type is an interface and the class to
- * be contributed is a local file, then a reloadable proxy for the class will be created and contributed.
- *
- * @param id of object to override
- * @param clazz to instantiate
- * @param constraints constraints for the overridden object, replacing constraints for the original object (even if
- * omitted, in which case the override object will have no ordering constraints)
- * @since 5.1.0.0
- */
- void overrideInstance(String id, Class<? extends T> clazz, String... constraints);
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AccessableObjectAnnotationProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AccessableObjectAnnotationProvider.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AccessableObjectAnnotationProvider.java
deleted file mode 100644
index 2acfd0d..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AccessableObjectAnnotationProvider.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2008 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.services;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-
-/**
- * Provides access to annotations of an accessable object such as a {@link java.lang.reflect.Method} or {@link
- * java.lang.reflect.Field}.
- */
-public class AccessableObjectAnnotationProvider implements AnnotationProvider
-{
- private final AccessibleObject object;
-
- public AccessableObjectAnnotationProvider(AccessibleObject object)
- {
- this.object = object;
- }
-
- @Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
- {
- return object.getAnnotation(annotationClass);
- }
-
- @Override
- public String toString()
- {
- return String.format("AnnotationProvider[%s]", object);
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AnnotationProviderChain.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AnnotationProviderChain.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AnnotationProviderChain.java
deleted file mode 100644
index 49b0b15..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AnnotationProviderChain.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2008 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.services;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-
-import java.lang.annotation.Annotation;
-import java.util.List;
-
-/**
- * Chain of command for {@link org.apache.tapestry5.ioc.AnnotationProvider}.
- */
-public class AnnotationProviderChain implements AnnotationProvider
-{
- private final AnnotationProvider[] providers;
-
- public AnnotationProviderChain(AnnotationProvider[] providers)
- {
- this.providers = providers;
- }
-
- /**
- * Creates an AnnotationProvider from the list of providers. Returns either an {@link AnnotationProviderChain} or
- * the sole element in the list.
- */
- public static AnnotationProvider create(List<AnnotationProvider> providers)
- {
- int size = providers.size();
-
- if (size == 1) return providers.get(0);
-
- return new AnnotationProviderChain(providers.toArray(new AnnotationProvider[providers.size()]));
- }
-
- @Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
- {
- for (AnnotationProvider p : providers)
- {
- T result = p.getAnnotation(annotationClass);
-
- if (result != null) return result;
- }
-
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java
deleted file mode 100644
index af4bd7d..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java
+++ /dev/null
@@ -1,250 +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.internal.services;
-
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
-
-import java.beans.PropertyDescriptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.GenericsUtils;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
-import org.apache.tapestry5.ioc.services.PropertyAdapter;
-
-public class ClassPropertyAdapterImpl implements ClassPropertyAdapter
-{
- private final Map<String, PropertyAdapter> adapters = newCaseInsensitiveMap();
-
- private final Class beanType;
-
- public ClassPropertyAdapterImpl(Class beanType, List<PropertyDescriptor> descriptors)
- {
- this.beanType = beanType;
-
- // lazy init
- Map<String, List<Method>> nonBridgeMethods = null;
-
- for (PropertyDescriptor pd : descriptors)
- {
- // Indexed properties will have a null propertyType (and a non-null
- // indexedPropertyType). We ignore indexed properties.
-
- final Class<?> thisPropertyType = pd.getPropertyType();
- if (thisPropertyType == null)
- continue;
-
- Method readMethod = pd.getReadMethod();
- Method writeMethod = pd.getWriteMethod();
-
- // TAP5-1493
- if (readMethod != null && readMethod.isBridge())
- {
- if (nonBridgeMethods == null)
- {
- nonBridgeMethods = groupNonBridgeMethodsByName(beanType);
- }
- readMethod = findMethodWithSameNameAndParamCount(readMethod, nonBridgeMethods);
- }
-
- // TAP5-1548, TAP5-1885: trying to find a getter which Introspector missed
- if (readMethod == null) {
- final String prefix = thisPropertyType != boolean.class ? "get" : "is";
- try
- {
- Method method = beanType.getMethod(prefix + capitalize(pd.getName()));
- final Class<?> returnType = method.getReturnType();
- if (returnType.equals(thisPropertyType) || returnType.isInstance(thisPropertyType)) {
- readMethod = method;
- }
- }
- catch (SecurityException e) {
- // getter not usable.
- }
- catch (NoSuchMethodException e)
- {
- // getter doesn't exist.
- }
- }
-
- if (writeMethod != null && writeMethod.isBridge())
- {
- if (nonBridgeMethods == null)
- {
- nonBridgeMethods = groupNonBridgeMethodsByName(beanType);
- }
- writeMethod = findMethodWithSameNameAndParamCount(writeMethod, nonBridgeMethods);
- }
-
- // TAP5-1548, TAP5-1885: trying to find a setter which Introspector missed
- if (writeMethod == null) {
- try
- {
- Method method = beanType.getMethod("set" + capitalize(pd.getName()), pd.getPropertyType());
- final Class<?> returnType = method.getReturnType();
- if (returnType.equals(void.class)) {
- writeMethod = method;
- }
- }
- catch (SecurityException e) {
- // setter not usable.
- }
- catch (NoSuchMethodException e)
- {
- // setter doesn't exist.
- }
- }
-
- Class propertyType = readMethod == null ? thisPropertyType : GenericsUtils.extractGenericReturnType(
- beanType, readMethod);
-
- PropertyAdapter pa = new PropertyAdapterImpl(this, pd.getName(), propertyType, readMethod, writeMethod);
-
- adapters.put(pa.getName(), pa);
- }
-
- // Now, add any public fields (even if static) that do not conflict
-
- for (Field f : beanType.getFields())
- {
- String name = f.getName();
-
- if (!adapters.containsKey(name))
- {
- Class propertyType = GenericsUtils.extractGenericFieldType(beanType, f);
- PropertyAdapter pa = new PropertyAdapterImpl(this, name, propertyType, f);
-
- adapters.put(name, pa);
- }
- }
- }
-
- private static String capitalize(String name)
- {
- return Character.toUpperCase(name.charAt(0)) + name.substring(1);
- }
-
- /**
- * Find a replacement for the method (if one exists)
- * @param method A method
- * @param groupedMethods Methods mapped by name
- * @return A method from groupedMethods with the same name / param count
- * (default to providedmethod if none found)
- */
- private Method findMethodWithSameNameAndParamCount(Method method, Map<String, List<Method>> groupedMethods) {
- List<Method> methodGroup = groupedMethods.get(method.getName());
- if (methodGroup != null)
- {
- for (Method nonBridgeMethod : methodGroup)
- {
- if (nonBridgeMethod.getParameterTypes().length == method.getParameterTypes().length)
- {
- // return the non-bridge method with the same name / argument count
- return nonBridgeMethod;
- }
- }
- }
-
- // default to the provided method
- return method;
- }
-
- /**
- * Find all of the public methods that are not bridge methods and
- * group them by method name
- *
- * {@see Method#isBridge()}
- * @param type Bean type
- * @return
- */
- private Map<String, List<Method>> groupNonBridgeMethodsByName(Class type)
- {
- Map<String, List<Method>> methodGroupsByName = CollectionFactory.newMap();
- for (Method method : type.getMethods())
- {
- if (!method.isBridge())
- {
- List<Method> methodGroup = methodGroupsByName.get(method.getName());
- if (methodGroup == null)
- {
- methodGroup = CollectionFactory.newList();
- methodGroupsByName.put(method.getName(), methodGroup);
- }
- methodGroup.add(method);
- }
- }
- return methodGroupsByName;
- }
-
- @Override
- public Class getBeanType()
- {
- return beanType;
- }
-
- @Override
- public String toString()
- {
- String names = InternalUtils.joinSorted(adapters.keySet());
-
- return String.format("<ClassPropertyAdaptor %s: %s>", beanType.getName(), names);
- }
-
- @Override
- public List<String> getPropertyNames()
- {
- return InternalUtils.sortedKeys(adapters);
- }
-
- @Override
- public PropertyAdapter getPropertyAdapter(String name)
- {
- return adapters.get(name);
- }
-
- @Override
- public Object get(Object instance, String propertyName)
- {
- return adaptorFor(propertyName).get(instance);
- }
-
- @Override
- public void set(Object instance, String propertyName, Object value)
- {
- adaptorFor(propertyName).set(instance, value);
- }
-
- @Override
- public Annotation getAnnotation(Object instance, String propertyName, Class<? extends Annotation> annotationClass) {
- return adaptorFor(propertyName).getAnnotation(annotationClass);
- }
-
- private PropertyAdapter adaptorFor(String name)
- {
- PropertyAdapter pa = adapters.get(name);
-
- if (pa == null)
- throw new IllegalArgumentException(ServiceMessages.noSuchProperty(beanType, name));
-
- return pa;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CompoundCoercion.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CompoundCoercion.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CompoundCoercion.java
deleted file mode 100644
index 4a5dece..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/CompoundCoercion.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2006, 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.services;
-
-import org.apache.tapestry5.ioc.services.Coercion;
-
-/**
- * Combines two coercions to create a coercion through an intermediate type.
- *
- * @param <S> The source (input) type
- * @param <I> The intermediate type
- * @param <T> The target (output) type
- */
-public class CompoundCoercion<S, I, T> implements Coercion<S, T>
-{
- private final Coercion<S, I> op1;
-
- private final Coercion<I, T> op2;
-
- public CompoundCoercion(Coercion<S, I> op1, Coercion<I, T> op2)
- {
- this.op1 = op1;
- this.op2 = op2;
- }
-
- @Override
- public T coerce(S input)
- {
- // Run the input through the first operation (S --> I), then run the result of that through
- // the second operation (I --> T).
-
- I intermediate = op1.coerce(input);
-
- return op2.coerce(intermediate);
- }
-
- @Override
- public String toString()
- {
- return String.format("%s, %s", op1, op2);
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticClassListenerLogger.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticClassListenerLogger.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticClassListenerLogger.java
deleted file mode 100644
index 8ebdede..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticClassListenerLogger.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 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.internal.services;
-
-import org.apache.tapestry5.plastic.ClassType;
-import org.apache.tapestry5.plastic.PlasticClassEvent;
-import org.apache.tapestry5.plastic.PlasticClassListener;
-import org.slf4j.Logger;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
-
-public class PlasticClassListenerLogger implements PlasticClassListener
-{
- private final Logger logger;
-
- public PlasticClassListenerLogger(Logger logger)
- {
- this.logger = logger;
- }
-
- @Override
- public void classWillLoad(PlasticClassEvent event)
- {
- if (logger.isDebugEnabled())
- {
- Marker marker = MarkerFactory.getMarker(event.getPrimaryClassName());
-
- String extendedClassName = event.getType() == ClassType.PRIMARY ? event.getPrimaryClassName() : String
- .format("%s (%s for %s)", event.getClassName(), event.getType(), event.getPrimaryClassName());
-
- logger.debug(marker,
- String.format("Loading class %s:\n%s", extendedClassName, event.getDissasembledBytecode()));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
deleted file mode 100644
index 112e29d..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 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.internal.services;
-
-import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
-import org.apache.tapestry5.internal.plastic.asm.Type;
-import org.apache.tapestry5.internal.plastic.asm.tree.*;
-import org.apache.tapestry5.ioc.Location;
-import org.apache.tapestry5.ioc.ObjectCreator;
-import org.apache.tapestry5.ioc.annotations.IncompatibleChange;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
-import org.apache.tapestry5.plastic.*;
-import org.slf4j.Logger;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-
-public class PlasticProxyFactoryImpl implements PlasticProxyFactory
-{
- public static final String INTERNAL_GET_DELEGATE = "_____internalGetDelegate_DONT_CALL_THIS_METHOD_____";
-
- private final PlasticManager manager;
-
- private final Map<String, Location> memberToLocation = CollectionFactory.newConcurrentMap();
-
- public PlasticProxyFactoryImpl(ClassLoader parentClassLoader, Logger logger)
- {
- this(PlasticManager.withClassLoader(parentClassLoader).create(), logger);
- }
-
- public PlasticProxyFactoryImpl(PlasticManager manager, Logger logger)
- {
- assert manager != null;
-
- this.manager = manager;
-
- if (logger != null)
- {
- manager.addPlasticClassListener(new PlasticClassListenerLogger(logger));
- }
- }
-
- @Override
- public ClassLoader getClassLoader()
- {
- return manager.getClassLoader();
- }
-
- @Override
- public <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, Class<? extends T> implementationType, PlasticClassTransformer callback)
- {
- return manager.createProxy(interfaceType, implementationType, callback);
- }
-
- @Override
- public <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, PlasticClassTransformer callback)
- {
- return manager.createProxy(interfaceType, callback);
- }
-
-
- @Override
- public <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType,
- Class<? extends T> implementationType)
- {
- return manager.createProxyTransformation(interfaceType, implementationType);
- }
-
- @Override
- public <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType)
- {
- return createProxyTransformation(interfaceType, null);
- }
-
- @Override
- public <T> T createProxy(final Class<T> interfaceType, final ObjectCreator<T> creator, final String description)
- { return createProxy(interfaceType, null, creator, description);
- }
-
- @Override
- public <T> T createProxy(final Class<T> interfaceType, final Class<? extends T> implementationType,
- final ObjectCreator<T> creator, final String description)
- {
- assert creator != null;
- assert InternalUtils.isNonBlank(description);
-
- ClassInstantiator<T> instantiator = createProxy(interfaceType, implementationType, new PlasticClassTransformer()
- {
- @Override
- public void transform(PlasticClass plasticClass)
- {
- final PlasticField objectCreatorField = plasticClass.introduceField(ObjectCreator.class, "creator")
- .inject(creator);
-
- final String interfaceTypeName = interfaceType.getName();
- PlasticMethod delegateMethod = plasticClass.introducePrivateMethod(interfaceTypeName, "delegate",
- null, null);
-
- final InstructionBuilderCallback returnCreateObject = new InstructionBuilderCallback()
- {
- @Override
- public void doBuild(InstructionBuilder builder)
- {
- builder.loadThis().getField(objectCreatorField);
- builder.invoke(ObjectCreator.class, Object.class, "createObject");
- builder.checkcast(interfaceType).returnResult();
- }
- };
-
- delegateMethod.changeImplementation(returnCreateObject);
-
- for (Method method : interfaceType.getMethods())
- {
- plasticClass.introduceMethod(method).delegateTo(delegateMethod);
- }
-
- // TA5-2235
- MethodDescription getDelegateMethodDescription =
- new MethodDescription(interfaceType.getName(), INTERNAL_GET_DELEGATE);
- plasticClass.introduceMethod(getDelegateMethodDescription, returnCreateObject);
-
- plasticClass.addToString(description);
-
- }
- });
-
- return interfaceType.cast(instantiator.newInstance());
- }
-
- private ClassNode readClassNode(Class clazz)
- {
- byte[] bytecode = PlasticInternalUtils.readBytecodeForClass(manager.getClassLoader(), clazz.getName(), false);
-
- return bytecode == null ? null : PlasticInternalUtils.convertBytecodeToClassNode(bytecode);
- }
-
- @Override
- public Location getMethodLocation(final Method method)
- {
- ObjectCreator<String> descriptionCreator = new ObjectCreator<String>()
- {
- @Override
- public String createObject()
- {
- return InternalUtils.asString(method);
- }
- };
-
- return getMemberLocation(method, method.getName(), Type.getMethodDescriptor(method),
- descriptionCreator);
- }
-
- @Override
- public Location getConstructorLocation(final Constructor constructor)
- {
- ObjectCreator<String> descriptionCreator = new ObjectCreator<String>()
- {
- @Override
- public String createObject()
- {
- StringBuilder builder = new StringBuilder(constructor.getDeclaringClass().getName()).append("(");
- String sep = "";
-
- for (Class parameterType : constructor.getParameterTypes())
- {
- builder.append(sep);
- builder.append(parameterType.getSimpleName());
-
- sep = ", ";
- }
-
- builder.append(")");
-
- return builder.toString();
- }
- };
-
- return getMemberLocation(constructor, "<init>", Type.getConstructorDescriptor(constructor),
- descriptionCreator);
- }
-
- @Override
- public void clearCache()
- {
- memberToLocation.clear();
- }
-
-
- public Location getMemberLocation(Member member, String methodName, String memberTypeDesc, ObjectCreator<String> textDescriptionCreator)
- {
- String className = member.getDeclaringClass().getName();
-
- String key = className + ":" + methodName + ":" + memberTypeDesc;
-
- Location location = memberToLocation.get(key);
-
- if (location == null)
- {
- location = constructMemberLocation(member, methodName, memberTypeDesc, textDescriptionCreator.createObject());
-
- memberToLocation.put(key, location);
- }
-
- return location;
-
- }
-
- private Location constructMemberLocation(Member member, String methodName, String memberTypeDesc, String textDescription)
- {
-
- ClassNode classNode = readClassNode(member.getDeclaringClass());
-
- if (classNode == null)
- {
- throw new RuntimeException(String.format("Unable to read class file for %s (to gather line number information).",
- textDescription));
- }
-
- for (MethodNode mn : (List<MethodNode>) classNode.methods)
- {
- if (mn.name.equals(methodName) && mn.desc.equals(memberTypeDesc))
- {
- int lineNumber = findFirstLineNumber(mn.instructions);
-
- // If debugging info is not available, we may lose the line number data, in which case,
- // just generate the Location from the textDescription.
-
- if (lineNumber < 1)
- {
- break;
- }
-
- String description = String.format("%s (at %s:%d)", textDescription, classNode.sourceFile, lineNumber);
-
- return new StringLocation(description, lineNumber);
- }
- }
-
- // Didn't find it. Odd.
-
- return new StringLocation(textDescription, 0);
- }
-
- private int findFirstLineNumber(InsnList instructions)
- {
- for (AbstractInsnNode node = instructions.getFirst(); node != null; node = node.getNext())
- {
- if (node instanceof LineNumberNode)
- {
- return ((LineNumberNode) node).line;
- }
- }
-
- return -1;
- }
-
- @Override
- public void addPlasticClassListener(PlasticClassListener listener)
- {
- manager.addPlasticClassListener(listener);
- }
-
- @Override
- public void removePlasticClassListener(PlasticClassListener listener)
- {
- manager.removePlasticClassListener(listener);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
deleted file mode 100644
index 8dd1e02..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImpl.java
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2006, 2007, 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.services;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
-import org.apache.tapestry5.ioc.services.PropertyAccess;
-
-@SuppressWarnings("unchecked")
-public class PropertyAccessImpl implements PropertyAccess
-{
- private final Map<Class, ClassPropertyAdapter> adapters = CollectionFactory.newConcurrentMap();
-
- @Override
- public Object get(Object instance, String propertyName)
- {
- return getAdapter(instance).get(instance, propertyName);
- }
-
- @Override
- public void set(Object instance, String propertyName, Object value)
- {
- getAdapter(instance).set(instance, propertyName, value);
- }
-
- @Override
- public Annotation getAnnotation(Object instance, String propertyName, Class<? extends Annotation> annotationClass) {
- return getAdapter(instance).getAnnotation(instance, propertyName, annotationClass);
- }
-
-
- /**
- * Clears the cache of adapters and asks the {@link Introspector} to clear its cache.
- */
- @Override
- public synchronized void clearCache()
- {
- adapters.clear();
-
- Introspector.flushCaches();
- }
-
- @Override
- public ClassPropertyAdapter getAdapter(Object instance)
- {
- return getAdapter(instance.getClass());
- }
-
- @Override
- public ClassPropertyAdapter getAdapter(Class forClass)
- {
- ClassPropertyAdapter result = adapters.get(forClass);
-
- if (result == null)
- {
- result = buildAdapter(forClass);
- adapters.put(forClass, result);
- }
-
- return result;
- }
-
- /**
- * Builds a new adapter and updates the _adapters cache. This not only guards access to the adapter cache, but also
- * serializes access to the Java Beans Introspector, which is not thread safe. In addition, handles the case where
- * the class in question is an interface, accumulating properties inherited from super-classes.
- */
- private synchronized ClassPropertyAdapter buildAdapter(Class forClass)
- {
- // In some race conditions, we may hit this method for the same class multiple times.
- // We just let it happen, replacing the old ClassPropertyAdapter with a new one.
-
- try
- {
- BeanInfo info = Introspector.getBeanInfo(forClass);
-
- List<PropertyDescriptor> descriptors = CollectionFactory.newList();
-
- addAll(descriptors, info.getPropertyDescriptors());
-
- // TAP5-921 - Introspector misses interface methods not implemented in an abstract class
- if (forClass.isInterface() || Modifier.isAbstract(forClass.getModifiers()) )
- addPropertiesFromExtendedInterfaces(forClass, descriptors);
-
- addPropertiesFromScala(forClass, descriptors);
-
- return new ClassPropertyAdapterImpl(forClass, descriptors);
- }
- catch (Throwable ex)
- {
- throw new RuntimeException(ex);
- }
- }
-
- private <T> void addAll(List<T> list, T[] array)
- {
- list.addAll(Arrays.asList(array));
- }
-
- private void addPropertiesFromExtendedInterfaces(Class forClass, List<PropertyDescriptor> descriptors)
- throws IntrospectionException
- {
- LinkedList<Class> queue = CollectionFactory.newLinkedList();
-
- // Seed the queue
- addAll(queue, forClass.getInterfaces());
-
- while (!queue.isEmpty())
- {
- Class c = queue.removeFirst();
-
- BeanInfo info = Introspector.getBeanInfo(c);
-
- // Duplicates occur and are filtered out in ClassPropertyAdapter which stores
- // a property name to descriptor map.
- addAll(descriptors, info.getPropertyDescriptors());
- addAll(queue, c.getInterfaces());
- }
- }
-
- private void addPropertiesFromScala(Class forClass, List<PropertyDescriptor> descriptors)
- throws IntrospectionException
- {
- for (Method method : forClass.getMethods())
- {
- addPropertyIfScalaGetterMethod(forClass, descriptors, method);
- }
- }
-
- private void addPropertyIfScalaGetterMethod(Class forClass, List<PropertyDescriptor> descriptors, Method method)
- throws IntrospectionException
- {
- if (!isScalaGetterMethod(method))
- return;
-
- PropertyDescriptor propertyDescriptor = new PropertyDescriptor(method.getName(), forClass, method.getName(),
- null);
-
- // found a getter, looking for the setter now
- try
- {
- Method setterMethod = findScalaSetterMethod(forClass, method);
-
- propertyDescriptor.setWriteMethod(setterMethod);
- }
- catch (NoSuchMethodException e)
- {
- // ignore
- }
-
- // check if the same property was already discovered with java bean accessors
-
- addScalaPropertyIfNoJavaBeansProperty(descriptors, propertyDescriptor, method);
- }
-
- private void addScalaPropertyIfNoJavaBeansProperty(List<PropertyDescriptor> descriptors,
- PropertyDescriptor propertyDescriptor, Method getterMethod)
- {
- boolean found = false;
-
- for (PropertyDescriptor currentPropertyDescriptor : descriptors)
- {
- if (currentPropertyDescriptor.getName().equals(getterMethod.getName()))
- {
- found = true;
-
- break;
- }
- }
-
- if (!found)
- descriptors.add(propertyDescriptor);
- }
-
- private Method findScalaSetterMethod(Class forClass, Method getterMethod) throws NoSuchMethodException
- {
- return forClass.getMethod(getterMethod.getName() + "_$eq", getterMethod.getReturnType());
- }
-
- private boolean isScalaGetterMethod(Method method)
- {
- try
- {
- return Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0
- && !method.getReturnType().equals(Void.TYPE)
- && method.getDeclaringClass().getDeclaredField(method.getName()) != null;
- }
- catch (NoSuchFieldException ex)
- {
- return false;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java
deleted file mode 100644
index 97685ef..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2006-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.internal.services;
-
-import org.apache.tapestry5.ioc.AnnotationProvider;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
-import org.apache.tapestry5.ioc.services.PropertyAdapter;
-import org.apache.tapestry5.ioc.util.ExceptionUtils;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.*;
-import java.util.List;
-
-public class PropertyAdapterImpl implements PropertyAdapter
-{
- private final ClassPropertyAdapter classAdapter;
-
- private final String name;
-
- private final Method readMethod;
-
- private final Method writeMethod;
-
- private final Class type;
-
- private final boolean castRequired;
-
- // Synchronized by this; lazily initialized
- private AnnotationProvider annotationProvider;
-
- private final Field field;
-
- private final Class declaringClass;
-
- PropertyAdapterImpl(ClassPropertyAdapter classAdapter, String name, Class type, Method readMethod,
- Method writeMethod)
- {
- this.classAdapter = classAdapter;
- this.name = name;
- this.type = type;
-
- this.readMethod = readMethod;
- this.writeMethod = writeMethod;
-
- declaringClass = readMethod != null ? readMethod.getDeclaringClass() : writeMethod.getDeclaringClass();
-
- castRequired = readMethod != null && readMethod.getReturnType() != type;
-
- field = null;
- }
-
- PropertyAdapterImpl(ClassPropertyAdapter classAdapter, String name, Class type, Field field)
- {
- this.classAdapter = classAdapter;
- this.name = name;
- this.type = type;
-
- this.field = field;
-
- declaringClass = field.getDeclaringClass();
-
- castRequired = field.getType() != type;
-
- readMethod = null;
- writeMethod = null;
- }
-
- @Override
- public String getName()
- {
- return name;
- }
-
- @Override
- public Method getReadMethod()
- {
- return readMethod;
- }
-
- @Override
- public Class getType()
- {
- return type;
- }
-
- @Override
- public Method getWriteMethod()
- {
- return writeMethod;
- }
-
- @Override
- public boolean isRead()
- {
- return field != null || readMethod != null;
- }
-
- @Override
- public boolean isUpdate()
- {
- return writeMethod != null || (field != null && !isFinal(field));
- }
-
- private boolean isFinal(Member member)
- {
- return Modifier.isFinal(member.getModifiers());
- }
-
- @Override
- public Object get(Object instance)
- {
- if (field == null && readMethod == null)
- {
- throw new UnsupportedOperationException(String.format("Class %s does not provide an accessor ('getter') method for property '%s'.", toClassName(instance), name));
- }
-
- Throwable fail;
-
- try
- {
- if (field == null)
- return readMethod.invoke(instance);
- else
- return field.get(instance);
- } catch (InvocationTargetException ex)
- {
- fail = ex.getTargetException();
- } catch (Exception ex)
- {
- fail = ex;
- }
-
- throw new RuntimeException(ServiceMessages.readFailure(name, instance, fail), fail);
- }
-
- @Override
- public void set(Object instance, Object value)
- {
- if (field == null && writeMethod == null)
- {
- throw new UnsupportedOperationException(String.format("Class %s does not provide a mutator ('setter') method for property '%s'.",
- toClassName(instance),
- name
- ));
- }
-
- Throwable fail;
-
- try
- {
- if (field == null)
- writeMethod.invoke(instance, value);
- else
- field.set(instance, value);
-
- return;
- } catch (InvocationTargetException ex)
- {
- fail = ex.getTargetException();
- } catch (Exception ex)
- {
- fail = ex;
- }
-
- throw new RuntimeException(String.format("Error updating property '%s' of %s: %s",
- name, toClassName(instance),
- ExceptionUtils.toMessage(fail)), fail);
- }
-
- private String toClassName(Object instance)
- {
- return instance == null ? "<null>" : instance.getClass().getName();
- }
-
- @Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
- {
- return getAnnnotationProvider().getAnnotation(annotationClass);
- }
-
- /**
- * Creates (as needed) the annotation provider for this property.
- */
- private synchronized AnnotationProvider getAnnnotationProvider()
- {
- if (annotationProvider == null)
- {
- List<AnnotationProvider> providers = CollectionFactory.newList();
-
- if (readMethod != null)
- providers.add(new AccessableObjectAnnotationProvider(readMethod));
-
- if (writeMethod != null)
- providers.add(new AccessableObjectAnnotationProvider(writeMethod));
-
- // There's an assumption here, that the fields match the property name (we ignore case
- // which leads to a manageable ambiguity) and that the field and the getter/setter
- // are in the same class (i.e., that we don't have a getter exposing a protected field inherted
- // from a base class, or some other oddity).
-
- Class cursor = getBeanType();
-
- out:
- while (cursor != null)
- {
- for (Field f : cursor.getDeclaredFields())
- {
- if (f.getName().equalsIgnoreCase(name))
- {
- providers.add(new AccessableObjectAnnotationProvider(f));
-
- break out;
- }
- }
-
- cursor = cursor.getSuperclass();
- }
-
- annotationProvider = AnnotationProviderChain.create(providers);
- }
-
- return annotationProvider;
- }
-
- @Override
- public boolean isCastRequired()
- {
- return castRequired;
- }
-
- @Override
- public ClassPropertyAdapter getClassAdapter()
- {
- return classAdapter;
- }
-
- @Override
- public Class getBeanType()
- {
- return classAdapter.getBeanType();
- }
-
- @Override
- public boolean isField()
- {
- return field != null;
- }
-
- @Override
- public Field getField()
- {
- return field;
- }
-
- @Override
- public Class getDeclaringClass()
- {
- return declaringClass;
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java
deleted file mode 100644
index e92ef2d..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2006, 2007, 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.internal.services;
-
-import org.apache.tapestry5.ioc.Messages;
-import org.apache.tapestry5.ioc.internal.util.MessagesImpl;
-import org.apache.tapestry5.ioc.services.Coercion;
-import org.apache.tapestry5.plastic.PlasticUtils;
-
-public class ServiceMessages
-{
- private final static Messages MESSAGES = MessagesImpl.forClass(ServiceMessages.class);
-
- private ServiceMessages()
- {
- }
-
- public static String noSuchProperty(Class clazz, String propertyName)
- {
- return MESSAGES.format("no-such-property", clazz.getName(), propertyName);
- }
-
-
- public static String readFailure(String propertyName, Object instance, Throwable cause)
- {
- return MESSAGES.format("read-failure", propertyName, instance, cause);
- }
-
- public static String propertyTypeMismatch(String propertyName, Class sourceClass, Class propertyType,
- Class expectedType)
- {
- return MESSAGES.format("property-type-mismatch", propertyName, sourceClass.getName(), propertyType.getName(),
- expectedType.getName());
- }
-
- public static String shutdownListenerError(Object listener, Throwable cause)
- {
- return MESSAGES.format("shutdown-listener-error", listener, cause);
- }
-
- public static String failedCoercion(Object input, Class targetType, Coercion coercion, Throwable cause)
- {
- return MESSAGES.format("failed-coercion", String.valueOf(input), PlasticUtils.toTypeName(targetType),
- coercion, cause);
- }
-
- public static String registryShutdown(String serviceId)
- {
- return MESSAGES.format("registry-shutdown", serviceId);
- }
-
- public static String serviceBuildFailure(String serviceId, Throwable cause)
- {
- return MESSAGES.format("service-build-failure", serviceId, cause);
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/StringLocation.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/StringLocation.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/StringLocation.java
deleted file mode 100644
index 0769b7e..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/StringLocation.java
+++ /dev/null
@@ -1,65 +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.services;
-
-import org.apache.tapestry5.ioc.Location;
-import org.apache.tapestry5.ioc.Resource;
-
-/**
- * Implementation of {@link Location} used when the underlying resource isn't really known.
- */
-public final class StringLocation implements Location
-{
- private final String description;
-
- private final int line;
-
- public StringLocation(String description, int line)
- {
- this.description = description;
- this.line = line;
- }
-
- @Override
- public String toString()
- {
- return description;
- }
-
- /**
- * Returns 0.
- */
- @Override
- public int getColumn()
- {
- return 0;
- }
-
- @Override
- public int getLine()
- {
- return line;
- }
-
- /**
- * Returns null; we don't know where the file really is (it's probably a class on the class path).
- */
- @Override
- public Resource getResource()
- {
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
deleted file mode 100644
index 46f1c0a..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2006, 2007, 2008, 2010, 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.services;
-
-import org.apache.tapestry5.func.F;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InheritanceSearch;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.internal.util.LockSupport;
-import org.apache.tapestry5.ioc.services.Coercion;
-import org.apache.tapestry5.ioc.services.CoercionTuple;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
-import org.apache.tapestry5.ioc.util.AvailableValues;
-import org.apache.tapestry5.ioc.util.UnknownValueException;
-import org.apache.tapestry5.plastic.PlasticUtils;
-import org.apache.tapestry5.util.StringToEnumCoercion;
-
-import java.util.*;
-
-@SuppressWarnings("all")
-public class TypeCoercerImpl extends LockSupport implements TypeCoercer
-{
- // Constructed from the service's configuration.
-
- private final Map<Class, List<CoercionTuple>> sourceTypeToTuple = CollectionFactory.newMap();
-
- /**
- * A coercion to a specific target type. Manages a cache of coercions to specific types.
- */
- private class TargetCoercion
- {
- private final Class type;
-
- private final Map<Class, Coercion> cache = CollectionFactory.newConcurrentMap();
-
- TargetCoercion(Class type)
- {
- this.type = type;
- }
-
- void clearCache()
- {
- cache.clear();
- }
-
- Object coerce(Object input)
- {
- Class sourceType = input != null ? input.getClass() : Void.class;
-
- if (type.isAssignableFrom(sourceType))
- {
- return input;
- }
-
- Coercion c = getCoercion(sourceType);
-
- try
- {
- return type.cast(c.coerce(input));
- } catch (Exception ex)
- {
- throw new RuntimeException(ServiceMessages.failedCoercion(input, type, c, ex), ex);
- }
- }
-
- String explain(Class sourceType)
- {
- return getCoercion(sourceType).toString();
- }
-
- private Coercion getCoercion(Class sourceType)
- {
- Coercion c = cache.get(sourceType);
-
- if (c == null)
- {
- c = findOrCreateCoercion(sourceType, type);
- cache.put(sourceType, c);
- }
-
- return c;
- }
- }
-
- /**
- * Map from a target type to a TargetCoercion for that type.
- */
- private final Map<Class, TargetCoercion> typeToTargetCoercion = new WeakHashMap<Class, TargetCoercion>();
-
- private static final Coercion NO_COERCION = new Coercion<Object, Object>()
- {
- @Override
- public Object coerce(Object input)
- {
- return input;
- }
- };
-
- private static final Coercion COERCION_NULL_TO_OBJECT = new Coercion<Void, Object>()
- {
- @Override
- public Object coerce(Void input)
- {
- return null;
- }
-
- @Override
- public String toString()
- {
- return "null --> null";
- }
- };
-
- public TypeCoercerImpl(Collection<CoercionTuple> tuples)
- {
- for (CoercionTuple tuple : tuples)
- {
- Class key = tuple.getSourceType();
-
- InternalUtils.addToMapList(sourceTypeToTuple, key, tuple);
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Object coerce(Object input, Class targetType)
- {
- assert targetType != null;
-
- Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
-
- if (effectiveTargetType.isInstance(input))
- {
- return input;
- }
-
-
- return getTargetCoercion(effectiveTargetType).coerce(input);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <S, T> Coercion<S, T> getCoercion(Class<S> sourceType, Class<T> targetType)
- {
- assert sourceType != null;
- assert targetType != null;
-
- Class effectiveSourceType = PlasticUtils.toWrapperType(sourceType);
- Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
-
- if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
- {
- return NO_COERCION;
- }
-
- return getTargetCoercion(effectiveTargetType).getCoercion(effectiveSourceType);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <S, T> String explain(Class<S> sourceType, Class<T> targetType)
- {
- assert sourceType != null;
- assert targetType != null;
-
- Class effectiveTargetType = PlasticUtils.toWrapperType(targetType);
- Class effectiveSourceType = PlasticUtils.toWrapperType(sourceType);
-
- // Is a coercion even necessary? Not if the target type is assignable from the
- // input value.
-
- if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
- {
- return "";
- }
-
- return getTargetCoercion(effectiveTargetType).explain(effectiveSourceType);
- }
-
- private TargetCoercion getTargetCoercion(Class targetType)
- {
- try
- {
- acquireReadLock();
-
- TargetCoercion tc = typeToTargetCoercion.get(targetType);
-
- return tc != null ? tc : createAndStoreNewTargetCoercion(targetType);
- } finally
- {
- releaseReadLock();
- }
- }
-
- private TargetCoercion createAndStoreNewTargetCoercion(Class targetType)
- {
- try
- {
- upgradeReadLockToWriteLock();
-
- // Inner check since some other thread may have beat us to it.
-
- TargetCoercion tc = typeToTargetCoercion.get(targetType);
-
- if (tc == null)
- {
- tc = new TargetCoercion(targetType);
- typeToTargetCoercion.put(targetType, tc);
- }
-
- return tc;
- } finally
- {
- downgradeWriteLockToReadLock();
- }
- }
-
- @Override
- public void clearCache()
- {
- try
- {
- acquireReadLock();
-
- // There's no need to clear the typeToTargetCoercion map, as it is a WeakHashMap and
- // will release the keys for classes that are no longer in existence. On the other hand,
- // there's likely all sorts of references to unloaded classes inside each TargetCoercion's
- // individual cache, so clear all those.
-
- for (TargetCoercion tc : typeToTargetCoercion.values())
- {
- // Can tc ever be null?
-
- tc.clearCache();
- }
- } finally
- {
- releaseReadLock();
- }
- }
-
- /**
- * Here's the real meat; we do a search of the space to find coercions, or a system of
- * coercions, that accomplish
- * the desired coercion.
- * <p/>
- * There's <strong>TREMENDOUS</strong> room to improve this algorithm. For example, inheritance lists could be
- * cached. Further, there's probably more ways to early prune the search. However, even with dozens or perhaps
- * hundreds of tuples, I suspect the search will still grind to a conclusion quickly.
- * <p/>
- * The order of operations should help ensure that the most efficient tuple chain is located. If you think about how
- * tuples are added to the queue, there are two factors: size (the number of steps in the coercion) and
- * "class distance" (that is, number of steps up the inheritance hiearchy). All the appropriate 1 step coercions
- * will be considered first, in class distance order. Along the way, we'll queue up all the 2 step coercions, again
- * in class distance order. By the time we reach some of those, we'll have begun queueing up the 3 step coercions, and
- * so forth, until we run out of input tuples we can use to fabricate multi-step compound coercions, or reach a
- * final response.
- * <p/>
- * This does create a good number of short lived temporary objects (the compound tuples), but that's what the GC is
- * really good at.
- *
- * @param sourceType
- * @param targetType
- * @return coercer from sourceType to targetType
- */
- @SuppressWarnings("unchecked")
- private Coercion findOrCreateCoercion(Class sourceType, Class targetType)
- {
- if (sourceType == Void.class)
- {
- return searchForNullCoercion(targetType);
- }
-
- // These are instance variables because this method may be called concurrently.
- // On a true race, we may go to the work of seeking out and/or fabricating
- // a tuple twice, but it's more likely that different threads are looking
- // for different source/target coercions.
-
- Set<CoercionTuple> consideredTuples = CollectionFactory.newSet();
- LinkedList<CoercionTuple> queue = CollectionFactory.newLinkedList();
-
- seedQueue(sourceType, targetType, consideredTuples, queue);
-
- while (!queue.isEmpty())
- {
- CoercionTuple tuple = queue.removeFirst();
-
- // If the tuple results in a value type that is assignable to the desired target type,
- // we're done! Later, we may add a concept of "cost" (i.e. number of steps) or
- // "quality" (how close is the tuple target type to the desired target type). Cost
- // is currently implicit, as compound tuples are stored deeper in the queue,
- // so simpler coercions will be located earlier.
-
- Class tupleTargetType = tuple.getTargetType();
-
- if (targetType.isAssignableFrom(tupleTargetType))
- {
- return tuple.getCoercion();
- }
-
- // So .. this tuple doesn't get us directly to the target type.
- // However, it *may* get us part of the way. Each of these
- // represents a coercion from the source type to an intermediate type.
- // Now we're going to look for conversions from the intermediate type
- // to some other type.
-
- queueIntermediates(sourceType, targetType, tuple, consideredTuples, queue);
- }
-
- // Not found anywhere. Identify the source and target type and a (sorted) list of
- // all the known coercions.
-
- throw new UnknownValueException(String.format("Could not find a coercion from type %s to type %s.",
- sourceType.getName(), targetType.getName()), buildCoercionCatalog());
- }
-
- /**
- * Coercion from null is special; we match based on the target type and its not a spanning
- * search. In many cases, we
- * return a pass-thru that leaves the value as null.
- *
- * @param targetType
- * desired type
- * @return the coercion
- */
- private Coercion searchForNullCoercion(Class targetType)
- {
- List<CoercionTuple> tuples = getTuples(Void.class, targetType);
-
- for (CoercionTuple tuple : tuples)
- {
- Class tupleTargetType = tuple.getTargetType();
-
- if (targetType.equals(tupleTargetType))
- return tuple.getCoercion();
- }
-
- // Typical case: no match, this coercion passes the null through
- // as null.
-
- return COERCION_NULL_TO_OBJECT;
- }
-
- /**
- * Builds a string listing all the coercions configured for the type coercer, sorted
- * alphabetically.
- */
- @SuppressWarnings("unchecked")
- private AvailableValues buildCoercionCatalog()
- {
- List<CoercionTuple> masterList = CollectionFactory.newList();
-
- for (List<CoercionTuple> list : sourceTypeToTuple.values())
- {
- masterList.addAll(list);
- }
-
- return new AvailableValues("Configured coercions", masterList);
- }
-
- /**
- * Seeds the pool with the initial set of coercions for the given type.
- */
- private void seedQueue(Class sourceType, Class targetType, Set<CoercionTuple> consideredTuples,
- LinkedList<CoercionTuple> queue)
- {
- // Work from the source type up looking for tuples
-
- for (Class c : new InheritanceSearch(sourceType))
- {
- List<CoercionTuple> tuples = getTuples(c, targetType);
-
- if (tuples == null)
- {
- continue;
- }
-
- for (CoercionTuple tuple : tuples)
- {
- queue.addLast(tuple);
- consideredTuples.add(tuple);
- }
-
- // Don't pull in Object -> type coercions when doing
- // a search from null.
-
- if (sourceType == Void.class)
- {
- return;
- }
- }
- }
-
- /**
- * Creates and adds to the pool a new set of coercions based on an intermediate tuple. Adds
- * compound coercion tuples
- * to the end of the queue.
- *
- * @param sourceType
- * the source type of the coercion
- * @param targetType
- * TODO
- * @param intermediateTuple
- * a tuple that converts from the source type to some intermediate type (that is not
- * assignable to the target type)
- * @param consideredTuples
- * set of tuples that have already been added to the pool (directly, or as a compound
- * coercion)
- * @param queue
- * the work queue of tuples
- */
- @SuppressWarnings("unchecked")
- private void queueIntermediates(Class sourceType, Class targetType, CoercionTuple intermediateTuple,
- Set<CoercionTuple> consideredTuples, LinkedList<CoercionTuple> queue)
- {
- Class intermediateType = intermediateTuple.getTargetType();
-
- for (Class c : new InheritanceSearch(intermediateType))
- {
- for (CoercionTuple tuple : getTuples(c, targetType))
- {
- if (consideredTuples.contains(tuple))
- {
- continue;
- }
-
- Class newIntermediateType = tuple.getTargetType();
-
- // If this tuple is for coercing from an intermediate type back towards our
- // initial source type, then ignore it. This should only be an optimization,
- // as branches that loop back towards the source type will
- // eventually be considered and discarded.
-
- if (sourceType.isAssignableFrom(newIntermediateType))
- {
- continue;
- }
-
- // The intermediateTuple coercer gets from S --> I1 (an intermediate type).
- // The current tuple's coercer gets us from I2 --> X. where I2 is assignable
- // from I1 (i.e., I2 is a superclass/superinterface of I1) and X is a new
- // intermediate type, hopefully closer to our eventual target type.
-
- Coercion compoundCoercer = new CompoundCoercion(intermediateTuple.getCoercion(), tuple.getCoercion());
-
- CoercionTuple compoundTuple = new CoercionTuple(sourceType, newIntermediateType, compoundCoercer, false);
-
- // So, every tuple that is added to the queue can take as input the sourceType.
- // The target type may be another intermediate type, or may be something
- // assignable to the target type, which will bring the search to a successful
- // conclusion.
-
- queue.addLast(compoundTuple);
- consideredTuples.add(tuple);
- }
- }
- }
-
- /**
- * Returns a non-null list of the tuples from the source type.
- *
- * @param sourceType
- * used to locate tuples
- * @param targetType
- * used to add synthetic tuples
- * @return non-null list of tuples
- */
- private List<CoercionTuple> getTuples(Class sourceType, Class targetType)
- {
- List<CoercionTuple> tuples = sourceTypeToTuple.get(sourceType);
-
- if (tuples == null)
- {
- tuples = Collections.emptyList();
- }
-
- // So, when we see String and an Enum type, we add an additional synthetic tuple to the end
- // of the real list. This is the easiest way to accomplish this is a thread-safe and class-reloading
- // safe way (i.e., what if the Enum is defined by a class loader that gets discarded? Don't want to cause
- // memory leaks by retaining an instance). In any case, there are edge cases where we may create
- // the tuple unnecessarily (such as when an explicit string-to-enum coercion is part of the TypeCoercer
- // configuration), but on the whole, this is cheap and works.
-
- if (sourceType == String.class && Enum.class.isAssignableFrom(targetType))
- {
- tuples = extend(tuples, new CoercionTuple(sourceType, targetType, new StringToEnumCoercion(targetType)));
- }
-
- return tuples;
- }
-
- private static <T> List<T> extend(List<T> list, T extraValue)
- {
- return F.flow(list).append(extraValue).toList();
- }
-}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/c7bf35ce/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InheritanceSearch.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InheritanceSearch.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InheritanceSearch.java
deleted file mode 100644
index f1830a7..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InheritanceSearch.java
+++ /dev/null
@@ -1,159 +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.plastic.PlasticUtils;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Set;
-
-/**
- * Used to search from a particular class up the inheritance hierarchy of extended classes and implemented interfaces.
- * <p/>
- * The search starts with the initial class (provided in the constructor). It progresses up the inheritance chain, but
- * skips java.lang.Object.
- * <p/>
- * Once classes are exhausted, the inheritance hierarchy is searched. This is a breadth-first search, rooted in the
- * interfaces implemented by the initial class at its super classes.
- * <p/>
- * Once all interfaces are exhausted, java.lang.Object is returned (it is always returned last).
- * <p/>
- * Two minor tweak to normal inheritance rules: <ul> <li> Normally, the parent class of an <em>object</em> array is
- * java.lang.Object, which is odd because FooService[] is assignable to Object[]. Thus, we tweak the search so that the
- * effective super class of FooService[] is Object[]. <li> The "super class" of a primtive type is its <em>wrapper type</em>,
- * with the exception of void, whose "super class" is left at its normal value (Object.class) </ul>
- * <p/>
- * This class implements the {@link Iterable} interface, so it can be used directly in a for loop: <code> for (Class
- * search : new InheritanceSearch(startClass)) { ... } </code>
- * <p/>
- * This class is not thread-safe.
- */
-public class InheritanceSearch implements Iterator<Class>, Iterable<Class>
-{
- private Class searchClass;
-
- private final Set<Class> addedInterfaces = CollectionFactory.newSet();
-
- private final LinkedList<Class> interfaceQueue = CollectionFactory.newLinkedList();
-
- private enum State
- {
- CLASS, INTERFACE, DONE
- }
-
- private State state;
-
- public InheritanceSearch(Class searchClass)
- {
- this.searchClass = searchClass;
-
- queueInterfaces(searchClass);
-
- state = searchClass == Object.class ? State.INTERFACE : State.CLASS;
- }
-
- private void queueInterfaces(Class searchClass)
- {
- for (Class intf : searchClass.getInterfaces())
- {
- if (addedInterfaces.contains(intf)) continue;
-
- interfaceQueue.addLast(intf);
- addedInterfaces.add(intf);
- }
- }
-
- @Override
- public Iterator<Class> iterator()
- {
- return this;
- }
-
- @Override
- public boolean hasNext()
- {
- return state != State.DONE;
- }
-
- @Override
- public Class next()
- {
- switch (state)
- {
- case CLASS:
-
- Class result = searchClass;
-
- searchClass = parentOf(searchClass);
-
- if (searchClass == null) state = State.INTERFACE;
- else queueInterfaces(searchClass);
-
- return result;
-
- case INTERFACE:
-
- if (interfaceQueue.isEmpty())
- {
- state = State.DONE;
- return Object.class;
- }
-
- Class intf = interfaceQueue.removeFirst();
-
- queueInterfaces(intf);
-
- return intf;
-
- default:
- throw new IllegalStateException();
- }
-
- }
-
- /**
- * Returns the parent of the given class. Tweaks inheritance for object arrays. Returns null instead of
- * Object.class.
- */
- private Class parentOf(Class clazz)
- {
- if (clazz != void.class && clazz.isPrimitive()) return PlasticUtils.toWrapperType(clazz);
-
- if (clazz.isArray() && clazz != Object[].class)
- {
- Class componentType = clazz.getComponentType();
-
- while (componentType.isArray()) componentType = componentType.getComponentType();
-
- if (!componentType.isPrimitive()) return Object[].class;
- }
-
- Class parent = clazz.getSuperclass();
-
- return parent != Object.class ? parent : null;
- }
-
- /**
- * @throws UnsupportedOperationException
- * always
- */
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
-}