You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/18 05:07:00 UTC
svn commit: r422949 [1/2] - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/internal/pageload/
main/java/org/apache/tapestry/internal/parser/
main/java/org/apache/tapestry/intern...
Author: hlship
Date: Mon Jul 17 20:06:58 2006
New Revision: 422949
URL: http://svn.apache.org/viewvc?rev=422949&view=rev
Log:
Partially implement decorator/interceptor support.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilder.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/InternalUtils.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/After.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Before.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ArrayDecoratorMethodModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoDelegateDecoratorMethodModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/PrimitiveDecoratorMethodModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/VoidBuilderMethodModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/VoidDecoratorMethodModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/InternalUtilsTest.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateParserImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java Mon Jul 17 20:06:58 2006
@@ -14,9 +14,9 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.internal.ioc.IOCUtilities.calculateParametersForMethod;
import static org.apache.tapestry.util.CollectionFactory.newMap;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
@@ -24,8 +24,6 @@
import org.apache.tapestry.ioc.ErrorLog;
import org.apache.tapestry.ioc.ServiceCreator;
import org.apache.tapestry.ioc.ServiceResources;
-import org.apache.tapestry.ioc.annotations.InjectService;
-import org.apache.tapestry.ioc.def.ServiceDef;
/**
* Basic implementation of {@link org.apache.tapestry.ioc.ServiceCreator} that handles invoking a
@@ -38,8 +36,6 @@
{
private final Object _moduleBuilder;
- private final ServiceDef _serviceDef;
-
private final String _serviceId;
private final Map<Class, Object> _parameterDefaults = newMap();
@@ -50,11 +46,9 @@
private final Method _builderMethod;
- public BasicServiceCreator(ServiceDef serviceDef, Method method, Object moduleBuilder,
- ServiceResources resources)
+ public BasicServiceCreator(Method method, Object moduleBuilder, ServiceResources resources)
{
- _serviceId = serviceDef.getServiceId();
- _serviceDef = serviceDef;
+ _serviceId = resources.getServiceId();
_builderMethod = method;
_moduleBuilder = moduleBuilder;
_log = resources.getErrorLog();
@@ -64,24 +58,18 @@
_parameterDefaults.put(ServiceResources.class, resources);
_parameterDefaults.put(ErrorLog.class, _log);
_parameterDefaults.put(Log.class, resources.getServiceLog());
- _parameterDefaults.put(Class.class, serviceDef.getServiceInterface());
+ _parameterDefaults.put(Class.class, resources.getServiceInterface());
}
/**
- * Invoked from the proxy to create the actual service implementation. TODO: Interceptors, etc.
+ * Invoked from the proxy to create the actual service implementation.
*/
public Object createService()
{
- Class[] parameterTypes = _builderMethod.getParameterTypes();
- Annotation[][] annotations = _builderMethod.getParameterAnnotations();
- int parameterCount = parameterTypes.length;
-
- Object[] parameters = new Object[parameterCount];
-
- for (int i = 0; i < parameterCount; i++)
- {
- parameters[i] = calculateParameterValue(parameterTypes[i], annotations[i]);
- }
+ Object[] parameters = calculateParametersForMethod(
+ _builderMethod,
+ _resources,
+ _parameterDefaults);
Object result = null;
@@ -101,42 +89,6 @@
throw new RuntimeException(IOCMessages.builderMethodReturnedNull(
_builderMethod,
_serviceId));
-
- return result;
- }
-
- private <T extends Annotation> T findAnnotation(Annotation[] annotations,
- Class<T> annotationClass)
- {
- for (Annotation a : annotations)
- {
- if (annotationClass.isInstance(a))
- return annotationClass.cast(a);
- }
-
- return null;
- }
-
- @SuppressWarnings("unchecked")
- private Object calculateParameterValue(Class parameterType, Annotation[] parameterAnnotations)
- {
- InjectService is = findAnnotation(parameterAnnotations, InjectService.class);
-
- if (is != null)
- {
- String serviceId = is.value();
-
- return _resources.getService(serviceId, parameterType);
- }
-
- // See if we have any "pre-determined" parameter type to object mappings
-
- Object result = _parameterDefaults.get(parameterType);
-
- // This will return a non-null value, or throw an exception
-
- if (result == null)
- result = _resources.getService(parameterType);
return result;
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,84 @@
+// 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.tapestry.internal.ioc;
+
+import static org.apache.tapestry.util.Defense.notBlank;
+import static org.apache.tapestry.util.Defense.notNull;
+
+import java.lang.reflect.Method;
+
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.util.Defense;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class DecoratorDefImpl implements DecoratorDef
+{
+ private final String _decoratorId;
+
+ private final String _before;
+
+ private final String _after;
+
+ private final Method _decoratorMethod;
+
+ @SuppressNullCheck
+ public DecoratorDefImpl(String decoratorId, String before, String after, Method decoratorMethod)
+ {
+ _decoratorId = notBlank(decoratorId, "decoratorId");
+ _before = before;
+ _after = after;
+ _decoratorMethod = notNull(decoratorMethod, "decoratorMethod");
+ }
+
+ @Override
+ public String toString()
+ {
+ return InternalUtils.asString(_decoratorMethod);
+ }
+
+ public String getAfter()
+ {
+ return _after;
+ }
+
+ public String getBefore()
+ {
+ return _before;
+ }
+
+ public String getDecoratorId()
+ {
+ return _decoratorId;
+ }
+
+ public ServiceDecorator createDecorator(Object moduleBuilder, ServiceResources resources)
+ {
+ return null;
+ }
+
+ /** Currently just returns false. */
+ public boolean matches(ServiceDef serviceDef)
+ {
+ return false;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java Mon Jul 17 20:06:58 2006
@@ -14,6 +14,12 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
+import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodWrongReturnType;
+import static org.apache.tapestry.internal.ioc.IOCMessages.decoratorMethodWrongReturnType;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
+
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
@@ -22,19 +28,18 @@
import java.util.Map;
import java.util.Set;
+import org.apache.hivemind.util.IdUtils;
import org.apache.tapestry.ioc.ErrorLog;
import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.annotations.After;
+import org.apache.tapestry.ioc.annotations.Before;
import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.annotations.Lifecycle;
import org.apache.tapestry.ioc.annotations.Private;
+import org.apache.tapestry.ioc.def.DecoratorDef;
import org.apache.tapestry.ioc.def.ModuleDef;
import org.apache.tapestry.ioc.def.ServiceDef;
-import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
-import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodWrongReturnType;
-import static org.apache.tapestry.internal.ioc.IOCMessages.voidBuildMethod;
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-
/**
* Grinds through a module builder class, identifying all the services and contributions.
*
@@ -43,9 +48,11 @@
public class DefaultModuleDefImpl implements ModuleDef
{
/** The prefix used to identify service building methods. */
-
private static final String BUILD_METHOD_NAME_PREFIX = "build";
+ /** The prefix used to identify service decorating methods. */
+ private static final String DECORATE_METHOD_NAME_PREFIX = "decorate";
+
private final Class _builderClass;
private final ErrorLog _log;
@@ -53,6 +60,9 @@
/** Keyed on fully qualified service id. */
private final Map<String, ServiceDef> _serviceDefs = newMap();
+ /** Keyed on fully qualified decorator id. */
+ private final Map<String, DecoratorDef> _decoratorDefs = newMap();
+
private final String _moduleId;
/**
@@ -142,19 +152,84 @@
{
String name = m.getName();
- if (!name.startsWith(BUILD_METHOD_NAME_PREFIX))
+ if (name.startsWith(BUILD_METHOD_NAME_PREFIX))
+ {
+ addServiceBuildMethod(m);
continue;
+ }
+
+ if (name.startsWith(DECORATE_METHOD_NAME_PREFIX))
+ {
+ addDecorateMethod(m);
+ continue;
+ }
+ }
+ }
+
+ private void addDecorateMethod(Method method)
+ {
+ // TODO: methods just named "decorate"
+
+ String id = _moduleId + "." + stripMethodPrefix(method, DECORATE_METHOD_NAME_PREFIX);
+
+ // TODO: Check for duplicates
+
+ Class returnType = method.getReturnType();
+
+ if (returnType.isPrimitive() || returnType.isArray())
+ {
+ _log.warn(decoratorMethodWrongReturnType(method), null);
+ return;
+ }
- addServiceBuildMethod(m);
+ if (!methodContainsObjectParameter(method))
+ {
+ _log.warn(IOCMessages.decoratorMethodNeedsDelegateParameter(method), null);
+ return;
}
+
+ // TODO: Check that at least one parameter is type java.lang.Object,
+ // since that's how the delegate is passed in.
+
+ After afterAnnotation = method.getAnnotation(After.class);
+ Before beforeAnnotation = method.getAnnotation(Before.class);
+
+ String after = afterAnnotation == null ? null : IdUtils.qualifyList(
+ _moduleId,
+ afterAnnotation.value());
+ String before = beforeAnnotation == null ? null : IdUtils.qualifyList(
+ _moduleId,
+ beforeAnnotation.value());
+
+ DecoratorDef def = new DecoratorDefImpl(id, before, after, method);
+
+ _decoratorDefs.put(id, def);
+ }
+
+ private boolean methodContainsObjectParameter(Method method)
+ {
+ for (Class parameterType : method.getParameterTypes())
+ {
+ // TODO: But what if the type Object parameter has an injection?
+ // We should skip it and look for a different parameter.
+
+ if (parameterType.equals(Object.class))
+ return true;
+ }
+
+ return false;
+ }
+
+ private String stripMethodPrefix(Method method, String prefix)
+ {
+ return method.getName().substring(prefix.length());
}
/** Invoked for public methods that have the proper prefix. */
private void addServiceBuildMethod(Method method)
{
// TODO: Methods named just "build"
- String serviceId = _moduleId + "."
- + method.getName().substring(BUILD_METHOD_NAME_PREFIX.length());
+ String serviceId = _moduleId + "." + stripMethodPrefix(method, BUILD_METHOD_NAME_PREFIX);
ServiceDef existing = _serviceDefs.get(serviceId);
@@ -171,12 +246,6 @@
Class returnType = method.getReturnType();
- if (returnType.equals(void.class))
- {
- _log.warn(voidBuildMethod(method), null);
- return;
- }
-
if (!returnType.isInterface())
{
_log.warn(buildMethodWrongReturnType(method), null);
@@ -195,4 +264,10 @@
return lifecycle != null ? lifecycle.value() : IOCConstants.DEFAULT_LIFECYCLE;
}
+
+ public Set<DecoratorDef> getDecoratorDefs()
+ {
+ return newSet(_decoratorDefs.values());
+ }
+
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java Mon Jul 17 20:06:58 2006
@@ -14,13 +14,14 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.internal.util.InternalUtils.asString;
+
import java.lang.reflect.Method;
import java.util.List;
import org.apache.hivemind.Messages;
import org.apache.hivemind.impl.MessageFormatter;
import org.apache.tapestry.internal.annotations.Utility;
-import org.apache.tapestry.ioc.def.ServiceDef;
/**
* @author Howard M. Lewis Ship
@@ -32,17 +33,19 @@
static String buildMethodConflict(Method conflict, String existing)
{
- return MESSAGES.format("build-method-conflict", conflict, existing);
+ return MESSAGES.format("build-method-conflict", asString(conflict), existing);
}
- static String voidBuildMethod(Method method)
+ static String buildMethodWrongReturnType(Method method)
{
- return MESSAGES.format("void-build-method", method);
+ return MESSAGES.format("build-method-wrong-return-type", asString(method), method
+ .getReturnType().getCanonicalName());
}
- static String buildMethodWrongReturnType(Method method)
+ static String decoratorMethodWrongReturnType(Method method)
{
- return MESSAGES.format("build-method-wrong-return-type", method);
+ return MESSAGES.format("decorator-method-wrong-return-type", asString(method), method
+ .getReturnType().getCanonicalName());
}
static String noSuchModule(String moduleId)
@@ -86,14 +89,19 @@
return MESSAGES.format("proxy-to-string", serviceId, serviceInterface.getName());
}
- static String builderMethodError(Method m, String serviceId, Throwable cause)
+ static String builderMethodError(Method method, String serviceId, Throwable cause)
+ {
+ return MESSAGES.format("builder-method-error", asString(method), serviceId, cause);
+ }
+
+ static String decoratorMethodError(Method method, String serviceId, Throwable cause)
{
- return MESSAGES.format("builder-method-error", m, serviceId, cause);
+ return MESSAGES.format("decorator-method-error", asString(method), serviceId, cause);
}
static String builderMethodReturnedNull(Method method, String serviceId)
{
- return MESSAGES.format("builder-method-returned-null", method, serviceId);
+ return MESSAGES.format("builder-method-returned-null", asString(method), serviceId);
}
static String serviceIsPrivate(String serviceId)
@@ -128,5 +136,17 @@
static String unknownLifecycle(String name)
{
return MESSAGES.format("unknown-lifecycle", name);
+ }
+
+ static String decoratorMethodNeedsDelegateParameter(Method method)
+ {
+ return MESSAGES.format("decorator-method-needs-delegate-parameter", asString(method));
+ }
+
+ static String decoratorReturnedWrongType(Method method, String serviceId, Object returned,
+ Class serviceInterface)
+ {
+ return MESSAGES.format("decorator-returned-wrong-type", new Object[]
+ { asString(method), serviceId, returned, serviceInterface.getName() });
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,94 @@
+// 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.tapestry.internal.ioc;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tapestry.internal.annotations.Utility;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.annotations.InjectService;
+
+/**
+ * Contains static methods used within this package.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Utility
+public class IOCUtilities
+{
+
+ public static <T extends Annotation> T findAnnotation(Annotation[] annotations,
+ Class<T> annotationClass)
+ {
+ for (Annotation a : annotations)
+ {
+ if (annotationClass.isInstance(a))
+ return annotationClass.cast(a);
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Object calculateParameterValue(Class parameterType,
+ Annotation[] parameterAnnotations, ServiceResources serviceResources,
+ Map<Class, Object> parameterDefaults)
+ {
+ InjectService is = findAnnotation(parameterAnnotations, InjectService.class);
+
+ if (is != null)
+ {
+ String serviceId = is.value();
+
+ return serviceResources.getService(serviceId, parameterType);
+ }
+
+ // See if we have any "pre-determined" parameter type to object mappings
+
+ Object result = parameterDefaults.get(parameterType);
+
+ // This will return a non-null value, or throw an exception
+
+ if (result == null)
+ result = serviceResources.getService(parameterType);
+
+ // ... so the result is never null
+
+ return result;
+ }
+
+ public static Object[] calculateParametersForMethod(Method method,
+ ServiceResources serviceResources, Map<Class, Object> parameterDefaults)
+ {
+ Class[] parameterTypes = method.getParameterTypes();
+ Annotation[][] annotations = method.getParameterAnnotations();
+ int parameterCount = parameterTypes.length;
+
+ Object[] parameters = new Object[parameterCount];
+
+ for (int i = 0; i < parameterCount; i++)
+ {
+ parameters[i] = calculateParameterValue(
+ parameterTypes[i],
+ annotations[i],
+ serviceResources,
+ parameterDefaults);
+ }
+ return parameters;
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilder.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilder.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilder.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,83 @@
+// 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.tapestry.internal.ioc;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tapestry.ioc.ServiceCreator;
+import org.apache.tapestry.ioc.ServiceDecorator;
+
+/**
+ * Responsible for constructing the interceptor stack, on demand, by invoking an ordered series of
+ * decorators ({@link org.apache.tapestry.ioc.def.DecoratorDef}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class InterceptorStackBuilder implements ServiceCreator
+{
+ private final String _serviceId;
+
+ private final ServiceCreator _coreServiceCreator;
+
+ private final Module _module;
+
+ /**
+ * @param module
+ * the module containing the decorator method
+ * @param serviceId
+ * identifies the service to be decorated
+ * @param coreServiceCreator
+ * responsible for creating the core service which is then decorated with a stack of
+ * interceptors
+ */
+ public InterceptorStackBuilder(Module module, String serviceId,
+ ServiceCreator coreServiceCreator)
+ {
+ _module = module;
+ _serviceId = serviceId;
+ _coreServiceCreator = coreServiceCreator;
+ }
+
+ public Object createService()
+ {
+ Object current = _coreServiceCreator.createService();
+
+ List<ServiceDecorator> decorators = _module.findDecoratorsForService(_serviceId);
+
+ // We get the decorators ordered according to their dependencies. However, we want to
+ // process from the last interceptor to the first, so we reverse the list.
+
+ Collections.reverse(decorators);
+
+ for (ServiceDecorator decorator : decorators)
+ {
+ Object interceptor = decorator.createInterceptor(current);
+
+ // Decorator methods may return null; this indicates that the decorator chose not to
+ // decorate.
+
+ if (interceptor != null)
+ current = interceptor;
+ }
+
+ // The stack of interceptors (plus the core service implementation) are "represented" to the
+ // outside world
+ // as the outermost interceptor. That will still be buried inside the service proxy.
+
+ return current;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java Mon Jul 17 20:06:58 2006
@@ -14,8 +14,12 @@
package org.apache.tapestry.internal.ioc;
+import java.util.List;
+
import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.ServiceDecorator;
import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.def.ServiceDef;
/**
* Internal view of the module registry, adding additional methods needed by modules.
@@ -70,4 +74,11 @@
* if the lifecycle name does not match a known lifecycle
*/
ServiceLifecycle getServiceLifecycle(String lifecycle);
+
+ /**
+ * Searches for decorators for a particular service. The resulting
+ * {@link org.apache.tapestry.ioc.def.DecoratorDef}s are ordered, then converted into
+ * {@link ServiceDecorator}s.
+ */
+ List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/Module.java Mon Jul 17 20:06:58 2006
@@ -15,6 +15,9 @@
package org.apache.tapestry.internal.ioc;
import java.util.Collection;
+import java.util.List;
+
+import org.apache.tapestry.ioc.ServiceDecorator;
/**
* A module within the Tapestry IoC registry. Each Module is constructed around a corresponding
@@ -53,4 +56,22 @@
* @return a collection of strings, each a fully qualified id of a service
*/
Collection<String> findServiceIdsForInterface(Class serviceInterface, Module module);
+
+ /**
+ * Locates all the decorators that should apply the identified service. This includes visibility
+ * rules (private services may only be decorated by decorators in the same module) and other
+ * filtering rules. The resulting list is ordered and from the list of
+ * {@link org.apache.tapestry.ioc.def.DecoratorDef}s, a list of {@link ServiceDecorator}s is
+ * returned.
+ *
+ * @param serviceId
+ * identifies the service to be decorated
+ * @return the ordered list of service decorators
+ */
+ List<ServiceDecorator> findDecoratorsForService(String serviceId);
+
+ /**
+ * Returns the instantiated module builder instance.
+ */
+ Object getModuleBuilder();
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java Mon Jul 17 20:06:58 2006
@@ -14,8 +14,14 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.Defense.notBlank;
+import static org.apache.tapestry.util.Defense.notNull;
+
import java.lang.reflect.Modifier;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.apache.hivemind.service.BodyBuilder;
@@ -27,16 +33,12 @@
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.ioc.IOCConstants;
import org.apache.tapestry.ioc.ServiceCreator;
+import org.apache.tapestry.ioc.ServiceDecorator;
import org.apache.tapestry.ioc.ServiceLifecycle;
import org.apache.tapestry.ioc.ServiceResources;
import org.apache.tapestry.ioc.def.ModuleDef;
import org.apache.tapestry.ioc.def.ServiceDef;
-import static org.apache.tapestry.util.CollectionFactory.newList;
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-import static org.apache.tapestry.util.Defense.notBlank;
-import static org.apache.tapestry.util.Defense.notNull;
-
/**
* @author Howard M. Lewis Ship
*/
@@ -48,6 +50,10 @@
private Object _moduleBuilder;
+ /** Identifies the internal module. Services within this module are never decorated. */
+
+ private static final String INTERNAL_MODULE_ID = "tapestry.ioc";
+
public ModuleImpl(InternalRegistry registry, ModuleDef moduleDef)
{
_registry = registry;
@@ -94,6 +100,14 @@
return def.isPrivate() && this != module;
}
+ /** TODO: Returns an empty list currently. */
+ public List<ServiceDecorator> findDecoratorsForService(String serviceId)
+ {
+ ServiceDef sd = _moduleDef.getServiceDef(serviceId);
+
+ return _registry.findDecoratorsForService(sd);
+ }
+
@SuppressNullCheck
public Collection<String> findServiceIdsForInterface(Class serviceInterface, Module module)
{
@@ -119,10 +133,11 @@
// Why synchronized here? Two reasons. First, with some lifecycle models (or perhaps in some
// scenarios using interceptors), we may try to acquire the write lock a second time and the
- // Synchronized.Write annotation doesn't currently support that. Second, I'm concerned about
+ // @Synchronized.Write annotation doesn't currently support that. Second, I'm concerned about
// multiple threads building services simultaneously, and getting into a thread deadlock. Of
// course, this isn't a solution for that ... we may need a global mutex to handle that specific
- // case!
+ // case! Alternately, I've thought about creating a "service creation" thread at startup and
+ // queuing service creation requests to that thread, and blocking the local thread.
private synchronized Object findOrCreate(ServiceDef def)
{
@@ -139,41 +154,41 @@
return result;
}
- /** Creates the service and updates the cache of created services. */
+ /**
+ * Creates the service and updates the cache of created services. Method is called from
+ * synchronized block.
+ */
private Object create(ServiceDef def)
{
- if (_moduleBuilder == null)
- {
- Class builderClass = _moduleDef.getBuilderClass();
-
- try
- {
- _moduleBuilder = builderClass.newInstance();
- }
- catch (Exception ex)
- {
- throw new RuntimeException(IOCMessages.instantiateBuilderError(
- builderClass,
- _moduleDef.getModuleId(),
- ex), ex);
- }
- }
+ ensureModuleBuilderExists();
- String lifecycleName = def.getServiceLifeycle();
+ // TODO: Check for recursive service build? This could happen if the
+ // builder method for the service (or a decorator method applied to the service)
+ // takes the service as a parameter.
- ServiceLifecycle lifecycle = _registry.getServiceLifecycle(lifecycleName);
+ ServiceLifecycle lifecycle = _registry.getServiceLifecycle(def.getServiceLifeycle());
ServiceResources resources = new ServiceResourcesImpl(_registry, this, def);
- ServiceCreator coreCreator = def.createServiceCreator(_moduleBuilder, resources);
+ // Build up a stack of operations that will be needed to instantiate the service
+ // (by the proxy, at a later date).
+
+ ServiceCreator creator = def.createServiceCreator(_moduleBuilder, resources);
+
+ creator = new LifecycleWrappedServiceCreator(lifecycle, resources, creator);
- ServiceCreator creator = new LifecycleWrappedServiceCreator(lifecycle, resources,
- coreCreator);
+ // Built in services are not decorated, ever.
+
+ if (!_moduleDef.getModuleId().equals(INTERNAL_MODULE_ID))
+ creator = new InterceptorStackBuilder(this, def.getServiceId(), creator);
- // TODO: Somewhere, in here, we have to add a chance for decorators to
- // create interceptors for the service.
+ // TODO: Add a creator that checks to prevent recursive construction of the service.
+ // What would be a scenario where this could occur? I guess builder method for A
+ // injects B and invokes a method on B and B itself is dependant on A.
// For primitive services, we just create the service right here. For non-primitive services
+ // we create the proxy the defers creation until needed.
+
Object service = lifecycle.getCreateProxy() ? createProxy(resources, creator) : creator
.createService();
@@ -182,6 +197,36 @@
return service;
}
+ private synchronized void ensureModuleBuilderExists()
+ {
+ if (_moduleBuilder != null)
+ return;
+
+ Class builderClass = _moduleDef.getBuilderClass();
+
+ // TODO: Support additional constructors (beyond no arguments constructor)?
+
+ try
+ {
+ _moduleBuilder = builderClass.newInstance();
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(IOCMessages.instantiateBuilderError(builderClass, _moduleDef
+ .getModuleId(), ex), ex);
+ }
+ }
+
+ public Object getModuleBuilder()
+ {
+ // Pretty sure that in the situations where this method is invoked, the MB will already have
+ // been instantiated, but just to be safe.
+
+ ensureModuleBuilderExists();
+
+ return _moduleBuilder;
+ }
+
private Object createProxy(ServiceResources resources, ServiceCreator creator)
{
String serviceId = resources.getServiceId();
@@ -211,9 +256,10 @@
private Class createProxyClass(String serviceId, Class serviceInterface, String proxyDescription)
{
-
String name = ClassFabUtils.generateClassName(serviceInterface);
+ // This is why ClassFactory has to be primitive.
+
ClassFactory factory = _registry.getService(
IOCConstants.CLASS_FACTORY_SERVICE_ID,
ClassFactory.class,
@@ -273,6 +319,10 @@
builder.end();
MethodSignature sig = new MethodSignature(serviceInterface, "_delegate", null, null);
+
+ // Here's the rub, this _delegate() method has to be synchronized. But after the first
+ // time through (when we create the service), the time inside the method is minimal.
+ // Let's hope that they aren't lying when they say that synchronized is now super cheap!
cf.addMethod(Modifier.PRIVATE | Modifier.SYNCHRONIZED, sig, builder.toString());
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java Mon Jul 17 20:06:58 2006
@@ -14,6 +14,9 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -22,12 +25,12 @@
import org.apache.hivemind.util.IdUtils;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.ServiceDecorator;
import org.apache.tapestry.ioc.ServiceLifecycle;
import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.util.CollectionFactory;
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-
/**
* @author Howard M. Lewis Ship
*/
@@ -131,6 +134,12 @@
throw new RuntimeException(IOCMessages.unknownLifecycle(lifecycle));
return result;
+ }
+
+ // TODO: Real implementation
+ public List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef)
+ {
+ return newList();
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,107 @@
+// 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.tapestry.internal.ioc;
+
+import static org.apache.tapestry.internal.ioc.IOCUtilities.calculateParametersForMethod;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+
+/**
+ * A wrapper around a decorator method.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ServiceDecoratorImpl implements ServiceDecorator
+{
+ private final Object _moduleBuilder;
+
+ private final String _serviceId;
+
+ private final Map<Class, Object> _parameterDefaults = newMap();
+
+ private final ErrorLog _log;
+
+ private final ServiceResources _resources;
+
+ private final Method _decoratorMethod;
+
+ private final Class _serviceInterface;
+
+ public ServiceDecoratorImpl(Method method, Object moduleBuilder, ServiceResources resources)
+ {
+ _serviceId = resources.getServiceId();
+ _decoratorMethod = method;
+ _moduleBuilder = moduleBuilder;
+ _log = resources.getErrorLog();
+ _resources = resources;
+ _serviceInterface = resources.getServiceInterface();
+
+ _parameterDefaults.put(String.class, _serviceId);
+ _parameterDefaults.put(ServiceResources.class, resources);
+ _parameterDefaults.put(ErrorLog.class, _log);
+ _parameterDefaults.put(Log.class, resources.getServiceLog());
+ _parameterDefaults.put(Class.class, _serviceInterface);
+ }
+
+ public Object createInterceptor(Object delegate)
+ {
+ // Create a copy of the parameters map so that Object.class points to the delegate instance.
+
+ Map<Class, Object> parameterDefaults = newMap(_parameterDefaults);
+ parameterDefaults.put(Object.class, delegate);
+
+ Object[] parameters = calculateParametersForMethod(
+ _decoratorMethod,
+ _resources,
+ parameterDefaults);
+
+ Object result = null;
+
+ try
+ {
+ result = _decoratorMethod.invoke(_moduleBuilder, parameters);
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(IOCMessages.decoratorMethodError(
+ _decoratorMethod,
+ _serviceId,
+ ex), ex);
+ }
+
+ if (result != null && !_serviceInterface.isInstance(result))
+ {
+ _log.warn(IOCMessages.decoratorReturnedWrongType(
+ _decoratorMethod,
+ _serviceId,
+ result,
+ _serviceInterface), null);
+
+ // Change the result to null so that we won't use the interceptor,
+ // and so that ClassCastExceptions don't occur later down the pipeline.
+
+ result = null;
+ }
+
+ return result;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDefImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDefImpl.java Mon Jul 17 20:06:58 2006
@@ -16,6 +16,7 @@
import java.lang.reflect.Method;
+import org.apache.tapestry.internal.util.InternalUtils;
import org.apache.tapestry.ioc.ServiceCreator;
import org.apache.tapestry.ioc.ServiceResources;
import org.apache.tapestry.ioc.def.ServiceDef;
@@ -41,9 +42,10 @@
_private = isprivate;
}
+ @Override
public String toString()
{
- return _builderMethod.toString();
+ return InternalUtils.asString(_builderMethod);
}
Method getBuilderMethod()
@@ -53,7 +55,7 @@
public ServiceCreator createServiceCreator(Object moduleBuilder, ServiceResources resources)
{
- return new BasicServiceCreator(this, _builderMethod, moduleBuilder, resources);
+ return new BasicServiceCreator(_builderMethod, moduleBuilder, resources);
}
public String getServiceId()
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/pageload/PageLoaderImpl.java Mon Jul 17 20:06:58 2006
@@ -26,8 +26,6 @@
import org.apache.tapestry.internal.structure.PageImpl;
import org.apache.tapestry.internal.transform.ComponentInstantiatorSource;
import org.apache.tapestry.internal.transform.Instantiator;
-import org.apache.tapestry.runtime.ComponentLifecycle;
-import org.apache.tapestry.util.CollectionFactory;
/**
* This implementation is not threadsafe.
@@ -89,9 +87,9 @@
/** Works the component queue, until exausted. */
private void workComponentQueue()
{
-
+
}
-
+
/** For injection. */
public void setComponentInstantiatorSource(ComponentInstantiatorSource source)
{
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateParserImpl.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateParserImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/parser/TemplateParserImpl.java Mon Jul 17 20:06:58 2006
@@ -17,7 +17,6 @@
import static org.apache.tapestry.util.CollectionFactory.newList;
import static org.apache.tapestry.util.CollectionFactory.newMap;
-import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/InternalUtils.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/InternalUtils.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/util/InternalUtils.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,59 @@
+// 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.tapestry.internal.util;
+
+import java.lang.reflect.Method;
+
+import org.apache.tapestry.internal.annotations.Utility;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@Utility
+public class InternalUtils
+{
+ /**
+ * Converts a method to a user presentable string consisting of the containing class name, the
+ * method name, and the short form of the parameter list (the class name of each parameter type,
+ * shorn of the package name portion).
+ *
+ * @param method
+ * @return short string representation
+ */
+ public static String asString(Method method)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(method.getDeclaringClass().getName());
+ buffer.append(".");
+ buffer.append(method.getName());
+ buffer.append("(");
+
+ for (int i = 0; i < method.getParameterTypes().length; i++)
+ {
+ if (i > 0)
+ buffer.append(", ");
+
+ String name = method.getParameterTypes()[i].getSimpleName();
+
+ int dotx = name.lastIndexOf('.');
+
+ buffer.append(name.substring(dotx + 1));
+
+ }
+
+ return buffer.append(")").toString();
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,35 @@
+// 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.tapestry.ioc;
+
+/**
+ * A service decorator is derived from a {@link org.apache.tapestry.ioc.def.DecoratorDef} and is
+ * responsible for building an interceptor around an existing implementation (called the
+ * "delegate").
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ServiceDecorator
+{
+ /**
+ * Creates a new object implementing the same service interface as the delegate object.
+ *
+ * @param delegate
+ * an existing object implementing the service interface.
+ * @return a new object implementing the same service interface, or delegate or null if the
+ * decorator chooses not to create a new interceptor.
+ */
+ public Object createInterceptor(Object delegate);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/After.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/After.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/After.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/After.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,42 @@
+// 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.tapestry.ioc.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Used with a service decorator method to control the order in which decorations occur. Identifies
+ * decorators which should occur after the annotated decorator.
+ *
+ * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.ioc.def.DecoratorDef
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface After {
+
+ /**
+ * A comma separated list of ids. Ids that are simple (unqualified) will be qualified with the
+ * appropriate module id. Alternately, the value "*" may be used to indicate the method should
+ * be ordered last.
+ */
+ String value();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Before.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Before.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Before.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Before.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,41 @@
+// 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.tapestry.ioc.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Used with a service decorator method to control the order in which decorations occur. Identifies
+ * other decorators which should occur before the annotated decorator.
+ *
+ * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.ioc.def.DecoratorDef
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Before {
+ /**
+ * A comma separated list of ids. Ids that are simple (unqualified) will be qualified with the
+ * appropriate module id. Alternately, the value "*" may be used to indicate the method should
+ * be ordered last.
+ */
+ String value();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,92 @@
+// 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.tapestry.ioc.def;
+
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+
+/**
+ * Definition of a service decorator, which (by default) is derived from a service decorator method.
+ * <p>
+ * A note on decorator scheduling. The scheduling is based on the desired order of <em>behavior</em>.
+ * Thus, if logging should occur before security checks, and security checks should occur before
+ * transaction management, then the desired decorator order is Logging, Security, Transactions. This
+ * might be specified as having Security occur after Logging, and Transactions occur after Security.
+ * It might also be specified by having Logging occur before "*", and Transactions occur after "*",
+ * with no specified scheduling for Security.
+ * <p>
+ * Once this order is established, decorators are <em>applied</em> in reverse order. Each
+ * decorator's job is to create an <em>interceptor</em> for the service, that delegates to the
+ * next implementation. This implies that the decorators are executed last to first. In the above
+ * example, the core service implementation would be passed to the Transaction decorator, resulting
+ * in the Transaction interceptor. The Transaction interceptor would be passed to the Security
+ * decorator, resulting in the Security interceptor. The Security interceptor would be passed to the
+ * Logging decorator, resulting in the Logging interceptor. Thus at runtime, the Logging interceptor
+ * will execute first, then delegate to the Security interceptor, which would delegate to the
+ * Transaction interceptor, which would finally delegate to the core service implementation.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface DecoratorDef
+{
+ /**
+ * Returns the id of the decorator, qualified by containing modules's id. The id uniquely
+ * identifies the decorator and may be used to set the order of operations for decorators.
+ * Decorators and services are in different namespaces (thus it is acceptible, even common, for
+ * a service and a decorator to have the same id).
+ */
+ String getDecoratorId();
+
+ /**
+ * Returns a comma-seperated list of decorators who should precede this decorator. May also
+ * return "*" to indicate that this decorator is always last. May return an empty string.
+ */
+
+ String getBefore();
+
+ /**
+ * Returns a comma-seperated list of decorators who should follow this decorator. May also
+ * return a "*" to indicate that this decorator is always first. May return an empty string.
+ */
+
+ String getAfter();
+
+ /**
+ * Creates an object that can perform the decoration (in the default case, by invoking the
+ * decorator method on the module builder instance.
+ *
+ * @param moduleBuilder
+ * the module builder instance associated with the module containing the decorator
+ * (not necessarily the module containing the service being decorated)
+ * @param resources
+ * the resources visible <em>to the decorator</em> (which may be in a different
+ * module than the service being decorated). Other resource properties (serviceId,
+ * serviceInterface, log, etc.) are for the service being decorated.
+ * @return
+ */
+ ServiceDecorator createDecorator(Object moduleBuilder, ServiceResources resources);
+
+ /**
+ * Used to determine which services may be decorated by this decorator. When decorating a
+ * service, first the decorators that target the service are identified, then ordering occurs,
+ * then the {@link ServiceDecorator}s are invoked.
+ *
+ * @param serviceDef
+ * @return true if the decorator applies to the service
+ */
+ boolean matches(ServiceDef serviceDef);
+
+ // TODO: Filtering information ... what modules and services are decorated by the decorator
+}
\ No newline at end of file
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java Mon Jul 17 20:06:58 2006
@@ -24,7 +24,7 @@
*/
public interface ModuleDef
{
- /** Returns the ids of the services built/provided by the module. */
+ /** Returns the fully qualified ids of the services built/provided by the module. */
Set<String> getServiceIds();
/**
@@ -35,6 +35,11 @@
* @return service definition or null if it doesn't exist
*/
ServiceDef getServiceDef(String serviceId);
+
+ /**
+ * Returns all the decorator definitions built/provided by this module.
+ */
+ Set<DecoratorDef> getDecoratorDefs();
/**
* Returns the module id extracted from the {@link org.apache.tapestry.ioc.annotations.Id}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Mon Jul 17 20:06:58 2006
@@ -15,7 +15,6 @@
package org.apache.tapestry.test;
import static java.lang.Thread.sleep;
-import static org.apache.tapestry.util.CollectionFactory.newList;
import java.io.File;
import java.io.FileOutputStream;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java Mon Jul 17 20:06:58 2006
@@ -15,7 +15,6 @@
package org.apache.tapestry.util;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -57,6 +56,12 @@
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> Set<T> newSet(Collection<T> values)
+ {
+ return new HashSet<T>(values);
}
/**
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties Mon Jul 17 20:06:58 2006
@@ -12,9 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-build-method-conflict=Service building method {0} conflicts with (has the same name as, but different parameters than) previously seen method {1} and has been ignored.
-void-build-method=Method {0} appears to be a service builder method, but a void return type doesn't make sense. The method has been ignored.
-build-method-wrong-return-type=Method {0} is named like a service builder method, but the return type is not acceptible (try an interface). The method has been ignored.
+build-method-conflict=Service building method {0} conflicts with (has the same name as, but different parameters than) \
+ previously seen method {1} and has been ignored.
+build-method-wrong-return-type=Method {0} is named like a service builder method, \
+ but the return type ({1}) is not acceptible (try an interface). \
+ The method has been ignored.
+decorator-method-wrong-return-type=Method {0} is named like a service decorator method, \
+ but the return type ({1}) is not acceptible (try Object). The method has been ignored.
missing-service=Service ''{0}'' does not exist.
builder-locked=The Registry Builder has created the Registry, further operations are not allowed.
module-id-conflict=Module ''{0}'' has already been defined. The duplicate definition will be ignored.
@@ -23,8 +27,16 @@
instantiate-builder-error=Unable to instantiate class {0} as builder for module ''{1}'': {2}
proxy-to-string=<Proxy for {0}({1})>
builder-method-error=Error invoking service builder method {0} (for service ''{1}''): {2}
+decorator-method-error=Error invoking service decorator method {0} (for service ''{1}''): {2}
builder-method-returned-null=Builder method {0} (for service ''{1}'') returned null.
service-is-private=Service ''{0}'' is private, and may not be referenced outside of its containing module.
no-service-matches-type=No (visible) service implements the interface {0}.
-many-service-matches=Service interface {0} is matched by {1,number} (visible) services: {2}. Automatic dependency resolution requires that exactly one service implement the interface.
-unknown-lifecycle=Unknown service lifecycle ''{0}''.
\ No newline at end of file
+many-service-matches=Service interface {0} is matched by {1,number} (visible) services: {2}. \
+ Automatic dependency resolution requires that exactly one service implement the interface.
+unknown-lifecycle=Unknown service lifecycle ''{0}''.
+decorator-method-needs-delegate-parameter=Decorator methods must a parameter for the service delegate \
+ (i.e., the object the created interceptor will delegate to). \
+ Method {0} does not include such a parameter, and has been ignored.
+decorator-returned-wrong-type=Decorator method {0} (invoked for service ''{1}'') returned {2}, \
+ which is not assignable to the {3} service interface.
+
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ArrayDecoratorMethodModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ArrayDecoratorMethodModule.java?rev=422949&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ArrayDecoratorMethodModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ArrayDecoratorMethodModule.java Mon Jul 17 20:06:58 2006
@@ -0,0 +1,29 @@
+// 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.tapestry.internal.ioc;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImplTest}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ArrayDecoratorMethodModule
+{
+ public Object[] decorateArray(Object delegate)
+ {
+ return null;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java?rev=422949&r1=422948&r2=422949&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java Mon Jul 17 20:06:58 2006
@@ -26,7 +26,6 @@
import org.apache.tapestry.ioc.ServiceCreator;
import org.apache.tapestry.ioc.ServiceResources;
import org.apache.tapestry.ioc.annotations.InjectService;
-import org.apache.tapestry.ioc.def.ServiceDef;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -71,18 +70,16 @@
@Test
public void noargs_method()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
_fie = newFieService();
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
replay();
- ServiceCreator sc = new BasicServiceCreator(def, findMethod("build_noargs"), this,
- resources);
+ ServiceCreator sc = new BasicServiceCreator(findMethod("build_noargs"), this, resources);
Object actual = sc.createService();
@@ -91,22 +88,20 @@
verify();
}
- private void trainForConstructor(ServiceDef def, ServiceResources resources, ErrorLog errorLog,
- Log log)
+ private void trainForConstructor(ServiceResources resources, ErrorLog errorLog, Log log)
{
- trainGetServiceId(def, SERVICE_ID);
+ trainGetServiceId(resources, SERVICE_ID);
trainGetErrorLog(resources, errorLog);
trainGetServiceLog(resources, log);
- trainGetServiceInterface(def, FieService.class);
+ trainGetServiceInterface(resources, FieService.class);
}
@Test
public void method_with_args()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
@@ -119,11 +114,11 @@
_fie = newFieService();
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
replay();
- ServiceCreator sc = new BasicServiceCreator(def, findMethod("build_args"), this, resources);
+ ServiceCreator sc = new BasicServiceCreator(findMethod("build_args"), this, resources);
Object actual = sc.createService();
@@ -135,7 +130,6 @@
@Test
public void injected_service_method()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
@@ -143,14 +137,13 @@
_fie = newFieService();
_expectedFoe = newFoe();
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
trainGetService(resources, "Foe", FoeService.class, _expectedFoe);
replay();
- ServiceCreator sc = new BasicServiceCreator(def, findMethod("build_injected"), this,
- resources);
+ ServiceCreator sc = new BasicServiceCreator(findMethod("build_injected"), this, resources);
Object actual = sc.createService();
@@ -167,19 +160,17 @@
@Test
public void builder_method_returns_null()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
_fie = null;
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
replay();
- ServiceCreator sc = new BasicServiceCreator(def, findMethod("build_noargs"), this,
- resources);
+ ServiceCreator sc = new BasicServiceCreator(findMethod("build_noargs"), this, resources);
try
{
@@ -188,12 +179,9 @@
}
catch (RuntimeException ex)
{
- Assert
- .assertEquals(
- ex.getMessage(),
- "Builder method public org.apache.tapestry.internal.ioc.FieService "
- + "org.apache.tapestry.internal.ioc.BasicServiceCreatorTest.build_noargs() "
- + "(for service 'ioc.Fie') returned null.");
+ Assert.assertEquals(ex.getMessage(), "Builder method "
+ + "org.apache.tapestry.internal.ioc.BasicServiceCreatorTest.build_noargs() "
+ + "(for service 'ioc.Fie') returned null.");
}
verify();
@@ -202,18 +190,17 @@
@Test
public void builder_method_failed()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
_fie = null;
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
replay();
- ServiceCreator sc = new BasicServiceCreator(def, findMethod("build_fail"), this, resources);
+ ServiceCreator sc = new BasicServiceCreator(findMethod("build_fail"), this, resources);
try
{
@@ -222,11 +209,9 @@
}
catch (RuntimeException ex)
{
- assertEquals(
- ex.getMessage(),
- "Error invoking service builder method public org.apache.tapestry.internal.ioc.FieService "
- + "org.apache.tapestry.internal.ioc.BasicServiceCreatorTest.build_fail() "
- + "(for service 'ioc.Fie'): java.lang.reflect.InvocationTargetException");
+ assertEquals(ex.getMessage(), "Error invoking service builder method "
+ + "org.apache.tapestry.internal.ioc.BasicServiceCreatorTest.build_fail() "
+ + "(for service 'ioc.Fie'): java.lang.reflect.InvocationTargetException");
InvocationTargetException inner1 = (InvocationTargetException) ex.getCause();
RuntimeException inner2 = (RuntimeException) inner1.getTargetException();
@@ -240,7 +225,6 @@
@Test
public void auto_dependency()
{
- ServiceDef def = newServiceDef();
ServiceResources resources = newServiceResources();
ErrorLog errorLog = newErrorLog();
Log log = newLog();
@@ -248,7 +232,7 @@
_fie = newFieService();
_expectedFoe = newFoeService();
- trainForConstructor(def, resources, errorLog, log);
+ trainForConstructor(resources, errorLog, log);
Method method = findMethod("build_auto");
@@ -256,7 +240,7 @@
replay();
- ServiceCreator sc = new BasicServiceCreator(def, method, this, resources);
+ ServiceCreator sc = new BasicServiceCreator(method, this, resources);
Object actual = sc.createService();