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/29 03:57:36 UTC
svn commit: r426741 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/internal/ioc/services/
main/java/org/apache/tapestry/ioc/
main/java/org/apache/tapestry/ioc/services/ test/j...
Author: hlship
Date: Fri Jul 28 18:57:35 2006
New Revision: 426741
URL: http://svn.apache.org/viewvc?rev=426741&view=rev
Log:
Add basic logging inside ClassFactory and ClassFab.
Add ability to make ClassFactory write out bytecode for generated classes.
Add support for "perthread" service lifecycle.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceCreator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceLogger.java
- copied, changed from r426658, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ServiceLoggerTest.java
- copied, changed from r426658, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolder.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java
Modified:
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/services/AbstractFab.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFabImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/CtClassSource.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceLifecycle.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.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/services/ClassFabImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnknownLifecycleModule.java
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=426741&r1=426740&r2=426741&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 Fri Jul 28 18:57:35 2006
@@ -307,16 +307,14 @@
private Class createProxyClass(String serviceId, Class serviceInterface, String proxyDescription)
{
- String name = ClassFabUtils.generateClassName(serviceInterface);
-
- // This is why ClassFactory has to be primitive.
+ // This is why ClassFactory has to be primitive.
ClassFactory factory = _registry.getService(
IOCConstants.CLASS_FACTORY_SERVICE_ID,
ClassFactory.class,
this);
- ClassFab cf = factory.newClass(name, Object.class);
+ ClassFab cf = factory.newClass(serviceInterface);
cf.addField("_creator", ServiceCreator.class);
cf.addField("_delegate", serviceInterface);
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=426741&r1=426740&r2=426741&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 Fri Jul 28 18:57:35 2006
@@ -39,6 +39,7 @@
import org.apache.tapestry.ioc.def.ModuleDef;
import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.ioc.services.ServiceLifecycleSource;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
import org.apache.tapestry.util.CollectionFactory;
import static org.apache.tapestry.util.CollectionFactory.newList;
@@ -112,6 +113,11 @@
public <T> T getService(String serviceId, Class<T> serviceInterface)
{
return getService(serviceId, serviceInterface, null);
+ }
+
+ public void cleanupThread()
+ {
+ getService("tapestry.ioc.ThreadCleanupHub", ThreadCleanupHub.class).cleanup();
}
private Module locateModuleForService(String serviceId)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/AbstractFab.java Fri Jul 28 18:57:35 2006
@@ -18,6 +18,7 @@
import java.util.Map;
+import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.annotations.OneShot;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
@@ -37,10 +38,13 @@
private final CtClassSource _source;
- public AbstractFab(CtClassSource source, CtClass ctClass)
+ private final Log _log;
+
+ public AbstractFab(CtClassSource source, CtClass ctClass, Log log)
{
_ctClass = ctClass;
_source = source;
+ _log = log;
}
/**
@@ -52,6 +56,17 @@
{
CtClass ctInterfaceClass = _source.getCtClass(interfaceClass);
+ try
+ {
+ for (CtClass existing : _ctClass.getInterfaces())
+ if (existing == ctInterfaceClass)
+ return;
+ }
+ catch (Exception ex)
+ {
+ // Don't think this code is actually reachable.
+ }
+
_ctClass.addInterface(ctInterfaceClass);
}
@@ -90,6 +105,9 @@
@OneShot.Lockdown
public Class createClass()
{
+ if (_log.isDebugEnabled())
+ _log.debug(String.format("Creating class from %s", this));
+
return _source.createClass(_ctClass);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFabImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFabImpl.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFabImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFabImpl.java Fri Jul 28 18:57:35 2006
@@ -25,6 +25,7 @@
import javassist.CtMethod;
import javassist.NotFoundException;
+import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.internal.util.InternalUtils;
import org.apache.tapestry.ioc.services.ClassFab;
@@ -54,9 +55,10 @@
private final Set<MethodSignature> _addedSignatures = newSet();
- public ClassFabImpl(CtClassSource source, CtClass ctClass)
+
+ public ClassFabImpl(CtClassSource source, CtClass ctClass, Log log)
{
- super(source, ctClass);
+ super(source, ctClass, log);
}
/**
@@ -143,11 +145,11 @@
throw new RuntimeException(ServiceMessages.unableToAddField(name, getCtClass(), ex), ex);
}
- _description
- .append(_formatter.format("private %s %s;\n\n", ClassFabUtils.getJavaClassName(type), name));
+ _formatter.format("private %s %s;\n\n", ClassFabUtils.getJavaClassName(type), name);
}
- public void proxyMethodsToDelegate(Class serviceInterface, String delegateExpression, String toString)
+ public void proxyMethodsToDelegate(Class serviceInterface, String delegateExpression,
+ String toString)
{
addInterface(serviceInterface);
@@ -207,8 +209,8 @@
// modifiers, return type, name
- _description.append(_formatter.format("%s %s %s", Modifier.toString(modifiers), ClassFabUtils
- .getJavaClassName(ms.getReturnType()), ms.getName()));
+ _formatter.format("%s %s %s", Modifier.toString(modifiers), ClassFabUtils
+ .getJavaClassName(ms.getReturnType()), ms.getName());
// parameters, exceptions and body from this:
addMethodDetailsToDescription(ms.getParameterTypes(), ms.getExceptionTypes(), body);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImpl.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImpl.java Fri Jul 28 18:57:35 2006
@@ -16,6 +16,9 @@
import javassist.CtClass;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hivemind.service.ClassFabUtils;
import org.apache.tapestry.ioc.services.ClassFab;
import org.apache.tapestry.ioc.services.ClassFactory;
@@ -26,6 +29,8 @@
*/
public class ClassFactoryImpl implements ClassFactory
{
+ private final Log _log;
+
/**
* ClassPool shared by all modules (all CtClassSource instances).
*/
@@ -33,13 +38,38 @@
private CtClassSource _classSource = new CtClassSource(_pool);
+ public ClassFactoryImpl()
+ {
+ this(LogFactory.getLog(ClassFactoryImpl.class));
+ }
+
+ public ClassFactoryImpl(Log log)
+ {
+ _log = log;
+ }
+
+ public ClassFab newClass(Class serviceInterface)
+ {
+ String name = ClassFabUtils.generateClassName(serviceInterface);
+
+ ClassFab cf = newClass(name, Object.class);
+
+ cf.addInterface(serviceInterface);
+
+ return cf;
+ }
+
public ClassFab newClass(String name, Class superClass)
{
+ if (_log.isDebugEnabled())
+ _log.debug(String.format("Create ClassFab for %s (extends %s)", name, superClass
+ .getName()));
+
try
{
CtClass ctNewClass = _classSource.newClass(name, superClass);
- return new ClassFabImpl(_classSource, ctNewClass);
+ return new ClassFabImpl(_classSource, ctNewClass, _log);
}
catch (Exception ex)
{
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/CtClassSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/CtClassSource.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/CtClassSource.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/CtClassSource.java Fri Jul 28 18:57:35 2006
@@ -74,8 +74,13 @@
return _pool.makeClass(name, ctSuperClass);
}
+ private static final String WRITE_DIR = System.getProperty("javassist-write-dir");
+
public synchronized Class createClass(CtClass ctClass)
{
+ if (WRITE_DIR != null)
+ writeClass(ctClass);
+
try
{
Class result = _pool.toClass(ctClass);
@@ -87,6 +92,24 @@
catch (Throwable ex)
{
throw new RuntimeException(ServiceMessages.unableToWriteClass(ctClass, ex), ex);
+ }
+ }
+
+ private void writeClass(CtClass ctClass)
+ {
+ try
+ {
+ boolean pruning = ctClass.stopPruning(true);
+
+ ctClass.writeFile(WRITE_DIR);
+
+ ctClass.defrost();
+
+ ctClass.stopPruning(pruning);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace(System.err);
}
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java Fri Jul 28 18:57:35 2006
@@ -47,7 +47,7 @@
{
Class interceptorClass = createInterceptorClass(serviceInterface, serviceId);
- Logger logger = new Logger(serviceLog);
+ ServiceLogger logger = new ServiceLogger(serviceLog);
Constructor cc = interceptorClass.getConstructors()[0];
@@ -75,10 +75,13 @@
private Class createInterceptorClass(Class serviceInterface, String serviceId)
{
- String className = ClassFabUtils.generateClassName(serviceInterface);
- ClassFab cf = _classFactory.newClass(className, Object.class);
+ ClassFab cf = _classFactory.newClass(serviceInterface);
- addInfrastructure(cf, serviceInterface);
+ cf.addField("_delegate", serviceInterface);
+ cf.addField("_logger", ServiceLogger.class);
+
+ cf.addConstructor(new Class[]
+ { serviceInterface, ServiceLogger.class }, null, "{ _delegate = $1; _logger = $2; }");
addMethods(cf, serviceInterface, serviceId);
@@ -90,9 +93,7 @@
MethodIterator mi = new MethodIterator(serviceInterface);
while (mi.hasNext())
- {
addMethod(cf, mi.next());
- }
if (!mi.getToString())
cf.addToString(ServiceMessages.loggingInterceptor(serviceId, serviceInterface));
@@ -160,16 +161,5 @@
builder.addln(" _logger.fail(%s, ex);", quotedMethodName);
builder.addln("throw ex;");
builder.end();
- }
-
- private void addInfrastructure(ClassFab cf, Class serviceInterface)
- {
- cf.addInterface(serviceInterface);
-
- cf.addField("_delegate", serviceInterface);
- cf.addField("_logger", Logger.class);
-
- cf.addConstructor(new Class[]
- { serviceInterface, Logger.class }, null, "{ _delegate = $1; _logger = $2; }");
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceCreator.java?rev=426741&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceCreator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceCreator.java Fri Jul 28 18:57:35 2006
@@ -0,0 +1,64 @@
+// 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.services;
+
+import org.apache.tapestry.ioc.ServiceCreator;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+
+/**
+ * Provides per-thread implementations of services, along with end-of-request thread cleanup.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class PerThreadServiceCreator extends ThreadLocal implements ThreadCleanupListener,
+ ServiceCreator
+{
+ private final ThreadCleanupHub _threadCleanupHub;
+
+ private final ServiceCreator _delegate;
+
+ public PerThreadServiceCreator(ThreadCleanupHub threadCleanupHub, ServiceCreator delegate)
+ {
+ _threadCleanupHub = threadCleanupHub;
+ _delegate = delegate;
+ }
+
+ @Override
+ protected Object initialValue()
+ {
+ // First time the value is accessed per thread, set up a callback to clear out the
+ // value (at the end of the request) and use the creator to create a new instance.
+
+ _threadCleanupHub.addThreadCleanupListener(this);
+
+ return _delegate.createService();
+ }
+
+ public Object createService()
+ {
+ // Get (or create) the service.
+ return get();
+ }
+
+ public void threadDidCleanup()
+ {
+ remove();
+ }
+
+}
\ No newline at end of file
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceLifecycle.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceLifecycle.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/PerThreadServiceLifecycle.java Fri Jul 28 18:57:35 2006
@@ -1,11 +1,33 @@
+// 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.services;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+
import org.apache.tapestry.ioc.ServiceCreator;
import org.apache.tapestry.ioc.ServiceLifecycle;
import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.services.ClassFab;
import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodSignature;
import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import static java.lang.String.format;
+
/**
* Allows a service to exist "per thread" (in each thread). This involves an inner proxy, with a
* ThreadLocal whose initial value is derived from a {@link org.apache.tapestry.ioc.ServiceCreator}.
@@ -13,8 +35,9 @@
* {@link org.apache.tapestry.ioc.services.ThreadCleanupListener} so that it can discard the
* per-thread implementation.
* <p>
- * This scheme ensures that, although the service builder method will be invoked many times of the
- * life of the application, the service decoration process occurs only once.
+ * This scheme ensures that, although the service builder method will be invoked many times over the
+ * life of the application, the service decoration process occurs only once. The final calling chain
+ * is: Service Proxy --> Decorator(s) --> PerThread Proxy --> (per thread) instance.
*
* @author Howard M. Lewis Ship
*/
@@ -24,9 +47,65 @@
private final ClassFactory _classFactory;
- public Object createService(ServiceResources resources, ServiceCreator creator)
+ private static final String PER_THREAD_METHOD_NAME = "_perThreadInstance";
+
+ public PerThreadServiceLifecycle(ThreadCleanupHub threadCleanupHub, ClassFactory classFactory)
+ {
+ _threadCleanupHub = threadCleanupHub;
+ _classFactory = classFactory;
+ }
+
+ public Object createService(ServiceResources resources, final ServiceCreator creator)
+ {
+ Class proxyClass = createProxyClass(resources);
+
+ ServiceCreator perThreadCreator = new PerThreadServiceCreator(_threadCleanupHub, creator);
+
+ try
+ {
+ Constructor ctor = proxyClass.getConstructors()[0];
+
+ return ctor.newInstance(perThreadCreator);
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RuntimeException(ex.getCause());
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private Class createProxyClass(ServiceResources resources)
{
- return null;
+ Class serviceInterface = resources.getServiceInterface();
+
+ ClassFab cf = _classFactory.newClass(serviceInterface);
+
+ cf.addField("_creator", ServiceCreator.class);
+
+ // Constructor takes a ServiceCreator
+
+ // Caution: Javassist needs this to be a block, not just a single statement!
+ cf.addConstructor(new Class[]
+ { ServiceCreator.class }, null, "{ _creator = $1; }");
+
+ String body = format("return (%s) _creator.createService();", serviceInterface.getName());
+
+ MethodSignature sig = new MethodSignature(serviceInterface, PER_THREAD_METHOD_NAME, null,
+ null);
+
+ cf.addMethod(Modifier.PRIVATE, sig, body);
+
+ String toString = format(
+ "<PerThread Proxy for %s(%s)>",
+ resources.getServiceId(),
+ serviceInterface.getName());
+
+ cf.proxyMethodsToDelegate(serviceInterface, PER_THREAD_METHOD_NAME + "()", toString);
+
+ return cf.createClass();
}
public boolean getCreateProxy()
Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceLogger.java (from r426658, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceLogger.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceLogger.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java&r1=426658&r2=426741&rev=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ServiceLogger.java Fri Jul 28 18:57:35 2006
@@ -26,7 +26,7 @@
*
* @author Howard M. Lewis Ship
*/
-public final class Logger
+public final class ServiceLogger
{
private final Log _log;
@@ -36,7 +36,7 @@
private static final String FAIL = " FAIL";
- public Logger(Log log)
+ public ServiceLogger(Log log)
{
_log = log;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImpl.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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.services;
import java.util.List;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java Fri Jul 28 18:57:35 2006
@@ -21,4 +21,11 @@
*/
public interface Registry extends ServiceLocator
{
+ /**
+ * Invoked at the end of a request to discard any thread-specific information accumulated during
+ * the current request.
+ *
+ * @see org.apache.tapestry.ioc.services.ThreadCleanupHub
+ */
+ void cleanupThread();
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java Fri Jul 28 18:57:35 2006
@@ -24,9 +24,6 @@
/**
* Returns the same creator, or a new one, that encapsulates the creation of the core service
* implementation.
- * <p>
- * TODO: Still deciding if ServiceResources needs to be passed in, or just the raw
- * ServiceCreator
*
* @param resources
* source of information about the service to be created, and source of additional
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java Fri Jul 28 18:57:35 2006
@@ -48,7 +48,9 @@
public interface ClassFab
{
/**
- * Adds the specified interface as an interface implemented by this class.
+ * Adds the specified interface as an interface implemented by this class. It is not an error to
+ * invoke this method multiple times with the same interface class (and the interface is only
+ * added once).
*/
void addInterface(Class interfaceClass);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java Fri Jul 28 18:57:35 2006
@@ -22,6 +22,16 @@
public interface ClassFactory
{
/**
+ * Simplified version of {@link #newClass(String, Class)} that generates a name based on the
+ * service interface name, extends from java.lang.Object, and automatically adds the
+ * serviceInterface to the returned ClassFab. This is the most common use when creating the
+ * kinds of proxies used throughout Tapestry IoC.
+ *
+ * @param serviceInterface
+ */
+ ClassFab newClass(Class serviceInterface);
+
+ /**
* Creates a {@link ClassFab} object for the given name; the new class is a subclass of the
* indicated class. The new class is always public and concrete.
*
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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.services;
import org.apache.tapestry.ioc.ServiceLifecycle;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Fri Jul 28 18:57:35 2006
@@ -19,7 +19,9 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.ioc.services.ClassFactoryImpl;
import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImpl;
+import org.apache.tapestry.internal.ioc.services.PerThreadServiceLifecycle;
import org.apache.tapestry.internal.ioc.services.ThreadCleanupHubImpl;
+import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.ServiceLifecycle;
import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.annotations.InjectService;
@@ -38,9 +40,9 @@
* The ClassFactory service is used to create new classes at runtime.
*/
@Lifecycle("primitive")
- public ClassFactory buildClassFactory()
+ public ClassFactory buildClassFactory(Log log)
{
- return new ClassFactoryImpl();
+ return new ClassFactoryImpl(log);
}
/**
@@ -76,7 +78,17 @@
{
return configuration.get(lifecycleName);
}
-
};
+ }
+
+ public void contributeServiceLifecycleSource(
+ MappedConfiguration<String, ServiceLifecycle> configuration,
+ @InjectService("ThreadCleanupHub")
+ ThreadCleanupHub threadCleanupHub, @InjectService("ClassFactory")
+ ClassFactory classFactory)
+ {
+ configuration.add(
+ "perthread",
+ new PerThreadServiceLifecycle(threadCleanupHub, classFactory));
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupHub.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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.services;
/**
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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.services;
import java.util.EventListener;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java Fri Jul 28 18:57:35 2006
@@ -274,12 +274,14 @@
catch (RuntimeException ex)
{
// The exception is now wrapped in a more generic exception.
- assertEquals(
- ex.getCause().getMessage(),
- "Construction of service 'ioc.test.PrimitiveRecursiveFoe' has failed due to recursion: "
- + "the service depends on itself in some way. Please check "
- + ModuleImplTestModule.class.getName()
- + ".buildPrimitiveRecursiveFoe(FoeService) for references to another service that is itself dependent on service 'ioc.test.PrimitiveRecursiveFoe'.");
+ assertTrue(ex
+ .getMessage()
+ .contains(
+ "Construction of service 'ioc.test.PrimitiveRecursiveFoe' has failed due to recursion: "
+ + "the service depends on itself in some way. Please check "
+ + ModuleImplTestModule.class.getName()
+ + ".buildPrimitiveRecursiveFoe(FoeService) for references to another service "
+ + "that is itself dependent on service 'ioc.test.PrimitiveRecursiveFoe'."));
}
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java Fri Jul 28 18:57:35 2006
@@ -23,6 +23,7 @@
import javassist.CtClass;
+import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.impl.BaseLocatable;
import org.apache.hivemind.util.PropertyUtils;
import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImplTest.ToStringService;
@@ -70,7 +71,7 @@
{
CtClass ctClass = _source.newClass(className, superClass);
- return new ClassFabImpl(_source, ctClass);
+ return new ClassFabImpl(_source, ctClass, LogFactory.getLog("ClassFab"));
}
@Test
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImplTest.java?rev=426741&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFactoryImplTest.java Fri Jul 28 18:57:35 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.internal.ioc.services;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.test.BaseTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ClassFactoryImplTest extends BaseTestCase
+{
+ public static class BaseClass
+ {
+ public void run()
+ {
+ }
+ }
+
+ @Test
+ public void new_class_with_name_and_base_class() throws Exception
+ {
+ ClassFactory factory = new ClassFactoryImpl();
+ String name = ClassFabUtils.generateClassName(Runnable.class);
+
+ ClassFab cf = factory.newClass(name, Object.class);
+ cf.addInterface(Runnable.class);
+
+ addRunMethod(cf);
+
+ Class newClass = cf.createClass();
+
+ Runnable instance = (Runnable) newClass.newInstance();
+
+ instance.run();
+ }
+
+ @Test
+ public void new_class_with_non_object_base_class() throws Exception
+ {
+ ClassFactory factory = new ClassFactoryImpl();
+ String name = ClassFabUtils.generateClassName(Runnable.class);
+
+ ClassFab cf = factory.newClass(name, BaseClass.class);
+ cf.addInterface(Runnable.class);
+
+ Class newClass = cf.createClass();
+
+ Runnable instance = (Runnable) newClass.newInstance();
+
+ instance.run();
+ }
+
+ @Test
+ public void new_class_with_interface() throws Exception
+ {
+ ClassFactory factory = new ClassFactoryImpl();
+
+ ClassFab cf = factory.newClass(Runnable.class);
+
+ addRunMethod(cf);
+
+ Class newClass = cf.createClass();
+
+ Runnable instance = (Runnable) newClass.newInstance();
+
+ instance.run();
+ }
+
+ private void addRunMethod(ClassFab cf)
+ {
+ cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "run", null, null), " { } ");
+ }
+}
Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ServiceLoggerTest.java (from r426658, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ServiceLoggerTest.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ServiceLoggerTest.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java&r1=426658&r2=426741&rev=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ServiceLoggerTest.java Fri Jul 28 18:57:35 2006
@@ -26,7 +26,7 @@
/**
* @author Howard M. Lewis Ship
*/
-public class LoggerTest extends BaseTestCase
+public class ServiceLoggerTest extends BaseTestCase
{
private void try_entry(String methodName, String expected, Object... arguments)
{
@@ -36,7 +36,7 @@
replay();
- new Logger(log).entry(methodName, arguments);
+ new ServiceLogger(log).entry(methodName, arguments);
verify();
@@ -50,7 +50,7 @@
replay();
- new Logger(log).exit(methodName, result);
+ new ServiceLogger(log).exit(methodName, result);
verify();
}
@@ -84,7 +84,7 @@
replay();
- new Logger(log).voidExit("wilma");
+ new ServiceLogger(log).voidExit("wilma");
verify();
}
@@ -100,7 +100,7 @@
replay();
- new Logger(log).fail("wilma", t);
+ new ServiceLogger(log).fail("wilma", t);
verify();
}
@@ -115,7 +115,7 @@
replay();
- Logger logger = new Logger(log);
+ ServiceLogger logger = new ServiceLogger(log);
assertTrue(logger.isDebugEnabled());
assertFalse(logger.isDebugEnabled());
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ThreadCleanupHubImplTest.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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.services;
import org.apache.commons.logging.Log;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Fri Jul 28 18:57:35 2006
@@ -22,9 +22,11 @@
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.services.TapestryIOCModule;
+import org.testng.Assert;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
/**
* A few tests that are easiest (or even just possible) by building a Registry and trying out a few
@@ -186,5 +188,51 @@
+ "(at org.apache.tapestry.ioc.UnknownLifecycleModule.buildUnknownLifecycle()): "
+ "Unknown service lifecycle 'magic'.");
}
+ }
+
+ @Test
+ public void simple_perthread() throws Exception
+ {
+ Registry r = buildRegistry(TapestryIOCModule.class, PerThreadModule.class);
+
+ final StringHolder holder = r.getService(StringHolder.class);
+
+ holder.setValue("fred");
+ assertEquals(holder.getValue(), "fred");
+
+ Runnable runnable = new Runnable()
+ {
+ public void run()
+ {
+ Assert.assertNull(holder.getValue());
+
+ holder.setValue("barney");
+ assertEquals(holder.getValue(), "barney");
+ }
+ };
+
+ Thread t = new Thread(runnable);
+
+ t.start();
+ t.join();
+
+ assertEquals(holder.getValue(), "fred");
+ }
+
+ @Test
+ public void registry_thread_cleanup()
+ {
+ Registry r = buildRegistry(TapestryIOCModule.class, PerThreadModule.class);
+
+ StringHolder holder = r.getService(StringHolder.class);
+
+ assertNull(holder.getValue());
+
+ holder.setValue("fred");
+ assertEquals(holder.getValue(), "fred");
+
+ r.cleanupThread();
+
+ assertNull(holder.getValue());
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java?rev=426741&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java Fri Jul 28 18:57:35 2006
@@ -0,0 +1,28 @@
+// 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;
+
+import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.Lifecycle;
+
+@Id("ioc.test")
+public class PerThreadModule
+{
+ @Lifecycle("perthread")
+ public StringHolder buildStringHolder()
+ {
+ return new StringHolderImpl();
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolder.java?rev=426741&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolder.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolder.java Fri Jul 28 18:57:35 2006
@@ -0,0 +1,25 @@
+// 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;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public interface StringHolder
+{
+ void setValue(String value);
+
+ String getValue();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java?rev=426741&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java Fri Jul 28 18:57:35 2006
@@ -0,0 +1,33 @@
+// 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;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class StringHolderImpl implements StringHolder
+{
+ private String _value;
+
+ public String getValue()
+ {
+ return _value;
+ }
+
+ public void setValue(String value)
+ {
+ _value = value;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnknownLifecycleModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnknownLifecycleModule.java?rev=426741&r1=426740&r2=426741&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnknownLifecycleModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/UnknownLifecycleModule.java Fri Jul 28 18:57:35 2006
@@ -1,3 +1,17 @@
+// 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;
import org.apache.tapestry.ioc.annotations.Id;