You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2006/07/06 17:25:47 UTC
svn commit: r419581 [1/2] - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/internal/test/
main/java/org/apache/tapestry/ioc/
main/java/org/apache/tapestry/ioc/annotations/ main/...
Author: hlship
Date: Thu Jul 6 08:25:45 2006
New Revision: 419581
URL: http://svn.apache.org/viewvc?rev=419581&view=rev
Log:
Flesh out more of the new IoC container.
Added:
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
- copied, changed from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleGrinder.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/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/ServiceCreator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycle.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCConstants.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/RegistryBuilder.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/annotations/Lifecycle.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/
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/ioc/def/ServiceDef.java
- copied, changed from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDef.java
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
- copied, changed from r418781, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleGrinderTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ReadManifest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java
- copied, changed from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleGrinder.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDef.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleGrinderTest.java
Modified:
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/Module.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/ioc/ServiceResources.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/test/TestBase.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/ModuleBuilderWithId.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/pageload/ComponentTemplateSourceImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.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/internal/transform/worker/RetainWorkerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/worker/UnclaimedFieldWorkerTest.java
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/BasicServiceCreator.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,112 @@
+// 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.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+/**
+ * Basic implementation of {@link org.apache.tapestry.internal.ioc.ServiceCreator} that handles
+ * invoking a method on the module builder, and figures out the correct parameters to pass into the
+ * annotated method.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class BasicServiceCreator implements ServiceCreator
+{
+ private final Object _moduleBuilder;
+
+ private final ServiceDef _serviceDef;
+
+ private final String _serviceId;
+
+ private final Map<Class, Object> _parameterDefaults = newMap();
+
+ private final ErrorLog _log;
+
+ public BasicServiceCreator(ServiceDef serviceDef, Object moduleBuilder,
+ ServiceResources resources)
+ {
+ _serviceId = serviceDef.getServiceId();
+ _serviceDef = serviceDef;
+ _moduleBuilder = moduleBuilder;
+ _log = resources.getErrorLog();
+
+ _parameterDefaults.put(String.class, _serviceId);
+ _parameterDefaults.put(ServiceResources.class, resources);
+ _parameterDefaults.put(ErrorLog.class, _log);
+ _parameterDefaults.put(Class.class, serviceDef.getServiceInterface());
+ }
+
+ /**
+ * Invoked from the proxy to create the actual service implementation. TODO: Interceptors, etc.
+ */
+ public Object createService()
+ {
+ Method m = _serviceDef.getBuilderMethod();
+
+ Class[] parameterTypes = m.getParameterTypes();
+ Annotation[][] annotations = m.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 result = null;
+
+ try
+ {
+ result = m.invoke(_moduleBuilder, parameters);
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(IOCMessages.builderMethodError(m, _serviceId, ex), ex);
+ }
+
+ if (result == null)
+ throw new RuntimeException(IOCMessages.builderMethodReturnedNull(m, _serviceId));
+
+ return result;
+ }
+
+ private Object calculateParameterValue(Class parameterType, Annotation[] parameterAnnotations)
+ {
+ // TODO: Injecting services based on an annotation
+
+ // See if we have any "pre-determined" parameter type to object mappings
+
+ Object result = _parameterDefaults.get(parameterType);
+
+ // TODO: Injecting services based on type
+
+ if (result == null)
+ _log.warn(IOCMessages.unknownBuilderParameter(parameterType, _serviceDef
+ .getBuilderMethod(), _serviceId), null);
+
+ return result;
+ }
+}
Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java (from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleGrinder.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleGrinder.java&r1=418781&r2=419581&rev=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleGrinder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java Thu Jul 6 08:25:45 2006
@@ -23,7 +23,11 @@
import java.util.Set;
import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.IOCConstants;
import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.Lifecycle;
+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;
@@ -35,29 +39,29 @@
*
* @author Howard M. Lewis Ship
*/
-public class ModuleGrinder
+public class DefaultModuleDefImpl implements ModuleDef
{
/** The prefix used to identify service building methods. */
private static final String BUILD_METHOD_NAME_PREFIX = "build";
- private final Class _moduleBuilder;
+ private final Class _builderClass;
private final ErrorLog _log;
- /** Keyed on unqualified service id. */
+ /** Keyed on fully qualified service id. */
private final Map<String, ServiceDef> _serviceDefs = newMap();
private final String _moduleId;
/**
- * @param moduleBuilder
- * the class that is responsible for building
+ * @param builderClass
+ * the class that is responsible for building services, etc.
* @param log
*/
- public ModuleGrinder(Class moduleBuilder, ErrorLog log)
+ public DefaultModuleDefImpl(Class builderClass, ErrorLog log)
{
- _moduleBuilder = moduleBuilder;
+ _builderClass = builderClass;
_log = log;
_moduleId = extractModuleId();
@@ -65,35 +69,21 @@
grind();
}
- /** Returns the ids of the services built/provided by the module. */
+ public Class getBuilderClass()
+ {
+ return _builderClass;
+ }
+
public Set<String> getServiceIds()
{
return _serviceDefs.keySet();
}
- /**
- * Returns a service definition via local (unqualified) service id. May return null (after
- * logging a warning) if the requested service does not exist.
- *
- * @param serviceId
- * unqualified service ids
- * @return service definition or null
- */
public ServiceDef getServiceDef(String serviceId)
{
- ServiceDef result = _serviceDefs.get(serviceId);
-
- if (result == null)
- _log.warn(IOCMessages.missingService(serviceId, _moduleId), null);
-
- return result;
+ return _serviceDefs.get(serviceId);
}
- /**
- * Returns the module id extracted from the {@link org.apache.tapestry.ioc.annotations.Id}
- * annotation on the module builder class (or calculated from the module bulder's package, if
- * the annotation is not present).
- */
public String getModuleId()
{
return _moduleId;
@@ -101,12 +91,12 @@
private String extractModuleId()
{
- Id id = getAnnotation(_moduleBuilder, Id.class);
+ Id id = getAnnotation(_builderClass, Id.class);
if (id != null)
return id.value();
- String className = _moduleBuilder.getName();
+ String className = _builderClass.getName();
// Don't try to do this with classes in the default package. Then again, you should
// never put classes in the default package!
@@ -116,25 +106,18 @@
return className.substring(0, lastdot);
}
+ // This appears useless, but it's really about some kind of ambiguity in Class, which seems
+ // to think getAnnotation() returns Object, not <? extends Annotation>. This may be a bug
+ // in Eclipse's Java compiler.
+
private <T extends Annotation> T getAnnotation(AnnotatedElement element, Class<T> annotationType)
{
return element.getAnnotation(annotationType);
}
- // private <T extends Annotation> T getRequiredAnnotation(AnnotatedElement element,
- // Class<T> annotationType)
- // {
- // T result = element.getAnnotation(annotationType);
- //
- // if (result == null)
- // _log.fail(IOCMessages.missingAnnotation(annotationType, element), null);
- //
- // return result;
- // }
-
private void grind()
{
- Method[] methods = _moduleBuilder.getMethods();
+ Method[] methods = _builderClass.getMethods();
Comparator<Method> c = new Comparator<Method>()
{
@@ -169,7 +152,7 @@
private void addServiceBuildMethod(Method method)
{
// TODO: Methods named just "build"
- String serviceId = method.getName().substring(BUILD_METHOD_NAME_PREFIX.length());
+ String serviceId = _moduleId + "." + method.getName().substring(BUILD_METHOD_NAME_PREFIX.length());
ServiceDef existing = _serviceDefs.get(serviceId);
@@ -198,6 +181,15 @@
return;
}
- _serviceDefs.put(serviceId, new ServiceDefImpl(serviceId, method));
+ String lifecycle = extractLifecycle(method);
+
+ _serviceDefs.put(serviceId, new ServiceDefImpl(serviceId, lifecycle, method));
+ }
+
+ private String extractLifecycle(Method method)
+ {
+ Lifecycle lifecycle = method.getAnnotation(Lifecycle.class);
+
+ return lifecycle != null ? lifecycle.value() : IOCConstants.DEFAULT_LIFECYCLE;
}
}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -43,8 +43,64 @@
return MESSAGES.format("build-method-wrong-return-type", method);
}
+ static String noSuchModule(String moduleId)
+ {
+ return MESSAGES.format("no-such-module", moduleId);
+ }
+
static String missingService(String serviceId, String moduleId)
{
return MESSAGES.format("missing-service", serviceId, moduleId);
}
+
+ public static String builderLocked()
+ {
+ return MESSAGES.getMessage("builder-locked");
+ }
+
+ public static String moduleIdConflict(String id)
+ {
+ return MESSAGES.format("module-id-conflict", id);
+ }
+
+ static String serviceWrongInterface(String serviceId, Class actualInterface,
+ Class requestedInterface)
+ {
+ return MESSAGES.format(
+ "service-wrong-interface",
+ serviceId,
+ actualInterface.getName(),
+ requestedInterface.getName());
+ }
+
+ static String instantiateBuilderError(Class builderClass, String moduleId, Throwable cause)
+ {
+ return MESSAGES
+ .format("instantiate-builder-error", builderClass.getName(), moduleId, cause);
+ }
+
+ static String singletonProxyToString(String serviceId, Class serviceInterface)
+ {
+ return MESSAGES.format("singleton-proxy-to-string", serviceId, serviceInterface.getName());
+ }
+
+ static String builderMethodError(Method m, String serviceId, Throwable cause)
+ {
+ return MESSAGES.format("builder-method-error", m, serviceId, cause);
+ }
+
+ static String unknownBuilderParameter(Class parameterType, Method method, String serviceId)
+ {
+ return MESSAGES.format(
+ "unknown-builder-parameter",
+ parameterType.getName(),
+ method,
+ serviceId);
+ }
+
+ static String builderMethodReturnedNull(Method method, String serviceId)
+ {
+ return MESSAGES.format("builder-method-returned-null", method, serviceId);
+ }
+
}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/InternalRegistry.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,37 @@
+// 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 org.apache.tapestry.ioc.Registry;
+
+public interface InternalRegistry extends Registry
+{
+ /**
+ * Locates a service given a fully qualified service id and the corresponding service interface
+ * type
+ *
+ * @param <T>
+ * @param serviceId
+ * the simple or fully qualified service id
+ * @param serviceInterface
+ * the interface the service implements
+ * @param module
+ * the module requesting the service (used for visibility checks)
+ * @return the service's proxy
+ * @throws RuntimeException
+ * if the service does not exist (this is considered programmer error)
+ */
+ <T> T getService(String serviceId, Class<T> serviceInterface, Module module);
+}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -15,13 +15,28 @@
package org.apache.tapestry.internal.ioc;
/**
- * A module with the Tapestry IoC registry. Each Module is constructed around a corresponding module
- * builder instance; the methods and annotations of that instance define the services provided by
- * the module.
+ * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding
+ * module builder instance; the methods and annotations of that instance define the services
+ * provided by the module.
*
* @author Howard M. Lewis Ship
*/
public interface Module
{
-
+ /**
+ * Locates a service given a service id and the corresponding service interface type.
+ *
+ * @param <T>
+ * @param serviceId
+ * the fully qualified service id
+ * @param serviceInterface
+ * the interface the service implements
+ * @param module
+ * the module requesting the service, or null for no module; this is used for
+ * performing visibility checks
+ * @return the service's proxy
+ * @throws RuntimeException
+ * if the service does not exist (this is considered programmer error)
+ */
+ <T> T getService(String serviceId, Class<T> serviceInterface, Module module);
}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java Thu Jul 6 08:25:45 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 java.util.Map;
+
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ModuleImpl implements Module
+{
+ private InternalRegistry _registry;
+
+ private ModuleDef _moduleDef;
+
+ private Object _moduleBuilder;
+
+ /** Keyed on fully qualified service id; values are instantiated services (proxies). */
+ private final Map<String, Object> _services = newMap();
+
+ public <T> T getService(String serviceId, Class<T> serviceInterface, Module module)
+ {
+ ServiceDef def = _moduleDef.getServiceDef(serviceId);
+
+ // No check yet for visibility, so ...
+
+ Object service = findOrCreate(def);
+
+ try
+ {
+ return serviceInterface.cast(service);
+ }
+ catch (ClassCastException ex)
+ {
+ throw new RuntimeException(IOCMessages.serviceWrongInterface(serviceId, def
+ .getServiceInterface(), serviceInterface));
+ }
+
+ }
+
+ // 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
+ // 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!
+
+ private synchronized Object findOrCreate(ServiceDef def)
+ {
+ String key = def.getServiceId();
+
+ Object result = _services.get(key);
+
+ if (result == null)
+ {
+ result = create(def);
+ _services.put(key, result);
+ }
+
+ return result;
+ }
+
+ /** Creates the service and updates the cache of created services. */
+ 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);
+ }
+ }
+
+ Object service = new Object();
+
+ _services.put(def.getServiceId(), service);
+
+ return service;
+ }
+
+}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,53 @@
+// 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.Map;
+
+import org.apache.hivemind.util.IdUtils;
+import org.apache.tapestry.ioc.Registry;
+
+public class RegistryImpl implements Registry, InternalRegistry
+{
+ /** Keyed on module id. */
+ private Map<String, Module> _modules;
+
+ public <T> T getService(String serviceId, Class<T> serviceInterface, Module module)
+ {
+ Module containingModule = localeModuleForService(serviceId);
+
+ return containingModule.getService(serviceId, serviceInterface, module);
+ }
+
+ public <T> T getService(String serviceId, Class<T> serviceInterface)
+ {
+ Module module = localeModuleForService(serviceId);
+
+ return module.getService(serviceId, serviceInterface, null);
+ }
+
+ private Module localeModuleForService(String serviceId)
+ {
+ String moduleId = IdUtils.extractModule(serviceId);
+
+ Module module = _modules.get(moduleId);
+
+ if (module == null)
+ throw new RuntimeException(IOCMessages.noSuchModule(moduleId));
+
+ return module;
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceCreator.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceCreator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceCreator.java Thu Jul 6 08:25:45 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.internal.ioc;
+
+/**
+ * Interface used to encapsulate any strategy used to obtain a service implementation (the real
+ * service implementation, not a proxy) on demand.
+ *
+ * @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.internal.ioc.SingletonServiceLifecycle
+ */
+public interface ServiceCreator
+{
+ /** Create and return the service implementation. */
+ Object createService();
+}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -16,6 +16,8 @@
import java.lang.reflect.Method;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
/**
* @author Howard M. Lewis Ship
*/
@@ -25,9 +27,12 @@
private final String _serviceId;
- ServiceDefImpl(String serviceId, Method builderMethod)
+ private final String _lifecycle;
+
+ ServiceDefImpl(String serviceId, String lifecycle, Method builderMethod)
{
_serviceId = serviceId;
+ _lifecycle = lifecycle;
_builderMethod = builderMethod;
}
@@ -44,6 +49,11 @@
public Class getServiceInterface()
{
return _builderMethod.getReturnType();
+ }
+
+ public String getServiceLifeycle()
+ {
+ return _lifecycle;
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycle.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycle.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycle.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,136 @@
+// 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.reflect.Modifier;
+
+import org.apache.hivemind.service.BodyBuilder;
+import org.apache.hivemind.service.ClassFab;
+import org.apache.hivemind.service.ClassFabUtils;
+import org.apache.hivemind.service.ClassFactory;
+import org.apache.hivemind.service.MethodIterator;
+import org.apache.hivemind.service.MethodSignature;
+import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * The basic implementation of a service lifecycle, which provides for a proxy that forces the
+ * creation of the real service when a method is invoked on the proxy.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class SingletonServiceLifecycle implements ServiceLifecycle
+{
+ public Object createService(ServiceDef serviceDef, Object moduleBuilder,
+ ServiceResources resources)
+ {
+ ClassFactory factory = resources.getService(
+ IOCConstants.CLASS_FACTORY_SERVICE_ID,
+ ClassFactory.class);
+
+ Class proxyClass = createProxyClass(serviceDef, factory);
+
+ ServiceCreator creator = new BasicServiceCreator(serviceDef, moduleBuilder, resources);
+
+ try
+ {
+ return proxyClass.getConstructors()[0].newInstance(creator);
+ }
+ catch (Exception ex)
+ {
+ // This should never happen, so we won't go to a lot of trouble
+ // reporting it.
+ throw new RuntimeException(ex.getMessage(), ex);
+ }
+ }
+
+ private Class createProxyClass(ServiceDef serviceDef, ClassFactory factory)
+ {
+ String serviceId = serviceDef.getServiceId();
+ Class serviceInterface = serviceDef.getServiceInterface();
+
+ String name = ClassFabUtils.generateClassName(serviceInterface);
+ ClassFab cf = factory.newClass(name, Object.class);
+
+ addInfrastructure(cf, serviceInterface);
+
+ addDelegateGetter(cf, serviceInterface);
+
+ addServiceMethods(cf, serviceId, serviceInterface);
+
+ return cf.createClass();
+ }
+
+ private void addServiceMethods(ClassFab cf, String serviceId, Class serviceInterface)
+ {
+ MethodIterator mi = new MethodIterator(serviceInterface);
+
+ while (mi.hasNext())
+ {
+ MethodSignature sig = mi.next();
+
+ // Make each method in the proxy delegates to the service implementation (or outermost
+ // interceptor). The "($r)" cast is magic for converting to the return type and
+ // understands void methods. The "$$" is just the list of method arguments.
+
+ String body = "return ($r) _delegate()." + sig.getName() + "($$);";
+
+ cf.addMethod(Modifier.PUBLIC, sig, body);
+ }
+
+ // If toString() is not part of the service interface, then add a toString()
+ // to the class. Objects visible to client code need a toString() to help
+ // with debugging.
+
+ if (!mi.getToString())
+ ClassFabUtils.addToStringMethod(cf, IOCMessages.singletonProxyToString(
+ serviceId,
+ serviceInterface));
+ }
+
+ private void addDelegateGetter(ClassFab cf, Class serviceInterface)
+ {
+ BodyBuilder builder = new BodyBuilder();
+ builder.begin();
+
+ // We can release the creator after invoking it, we only create the service once.
+
+ builder.addln("if (_delegate == null)");
+ builder.begin();
+ builder.addln("_delegate = ({0}) _creator.createService();", serviceInterface.getName());
+ builder.addln("_creator = null;");
+ builder.end();
+
+ builder.addln("return _delegate;");
+ builder.end();
+
+ MethodSignature sig = new MethodSignature(serviceInterface, "_delegate", null, null);
+
+ cf.addMethod(Modifier.PRIVATE | Modifier.SYNCHRONIZED, sig, builder.toString());
+ }
+
+ private void addInfrastructure(ClassFab cf, Class serviceInterface)
+ {
+ cf.addInterface(serviceInterface);
+ cf.addField("_delegate", serviceInterface);
+ cf.addField("_creator", ServiceCreator.class);
+
+ cf.addConstructor(new Class[]
+ { ServiceCreator.class }, null, "_creator = $1;");
+ }
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,38 @@
+// 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.test;
+
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.test.BaseTestCase;
+
+/**
+ * Contains additional factory and training methods related to internal interfaces.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class InternalBaseTestCase extends BaseTestCase
+{
+
+ protected final InternalComponentResources newInternalComponentResources()
+ {
+ return newMock(InternalComponentResources.class);
+ }
+
+ protected final ComponentTemplate newComponentTemplate()
+ {
+ return newMock(ComponentTemplate.class);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCConstants.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCConstants.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCConstants.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,32 @@
+// 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.internal.annotations.Utility;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@Utility
+public class IOCConstants
+{
+ public static final String DEFAULT_LIFECYCLE = "singleton";
+
+ /**
+ * Used to obtain the {@link org.apache.hivemind.service.ClassFactory} service, which is crucial
+ * when creating new classes for proxies and the like.
+ */
+ public static final String CLASS_FACTORY_SERVICE_ID = "tapestry.ioc.ClassFactory";
+}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Registry.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,40 @@
+// 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;
+
+/**
+ * Public access to the IoC service registry.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface Registry
+{
+ /**
+ * Obtains a service via its fully qualified service id. Returns the service's proxy. The
+ * service proxy implements the same interface as the actual service, and is used to instantiate
+ * the actual service only as needed.
+ *
+ * @param <T>
+ * @param serviceId
+ * fully qualified service id, used to locate the service object
+ * @param serviceInterface
+ * the interface implemented by the service (or an interface extended by the service
+ * interface)
+ * @return the service instance
+ * @throws RuntimeException
+ * if the service is not defined, or if an error occurs instantitating it
+ */
+ <T> T getService(String serviceId, Class<T> serviceInterface);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,69 @@
+// 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 java.util.Map;
+
+import org.apache.tapestry.internal.ioc.IOCMessages;
+import org.apache.tapestry.ioc.def.ModuleDef;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+/**
+ * Used to construct the IoC {@link org.apache.tapestry.ioc.Registry}. This class is <em>not</em>
+ * threadsafe. The registry, once created, <em>is</em> threadsafe.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class RegistryBuilder
+{
+ /** Module defs, keyed on module id. */
+ private final Map<String, ModuleDef> _modules = newMap();
+
+ private final ErrorLog _log;
+
+ private boolean _locked;
+
+ public RegistryBuilder(ErrorLog log)
+ {
+ _log = log;
+ }
+
+ public void add(ModuleDef moduleDef)
+ {
+ checkLocked();
+
+ String id = moduleDef.getModuleId();
+
+ if (_modules.containsKey(id))
+ {
+ _log.warn(IOCMessages.moduleIdConflict(id), null);
+ return;
+ }
+
+ _modules.put(id, moduleDef);
+ }
+
+ private void checkLocked()
+ {
+ if (_locked)
+ throw new RuntimeException(IOCMessages.builderLocked());
+ }
+
+ Registry build()
+ {
+ return null;
+ }
+}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java Thu Jul 6 08:25:45 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;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * A strategy for creating a service when first referenced. Most implementations create a proxy to
+ * the service, and defer the creation of the actual service implementation until needed.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ServiceLifecycle
+{
+ /**
+ * Creates the service implementation or, more commonly, creates a proxy that will cause the
+ * service itself to be created as needed.
+ * @param serviceDef
+ * additional definition of the service
+ * @param resources
+ * source of additional services or other resources that may be needed when
+ * constructing the core service implementation
+ * @param builder
+ * module builder instance, against which methods may be invoked to create the
+ * service
+ *
+ * @return the service or equivalent service proxy
+ */
+ Object createService(ServiceDef serviceDef, Object moduleBuilder, ServiceResources resources);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceResources.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/ServiceResources.java Thu Jul 6 08:25:45 2006
@@ -22,18 +22,29 @@
*/
public interface ServiceResources
{
+ /** Returns the fully qualified id of the service. */
+ String getServiceId();
+
+ /** Returns the service interface implemented by the service. */
+ Class getServiceInterface();
+
/**
- * Locates a service given a fully qualified service id and the corresponding service interface
- * type.
+ * Locates a service given a service id and the corresponding service interface type. The
+ * service id may be simple (just an id), in which case it is evaluated as a reference to
+ * another service within the same module. Alternately, it can be a fully qualified id, in which
+ * case the service may be provided by any module.
*
* @param <T>
* @param serviceId
- * fully qualified id of the service
+ * the simple or fully qualified service id
* @param serviceInterface
* the interface the service implements
- * @return the service's proxy
+ * @return the service instance (or proxy)
* @throws RuntimeException
* if the service does not exist (this is considered programmer error)
*/
<T> T getService(String serviceId, Class<T> serviceInterface);
+
+ /** Returns an error log appropriate for the service. */
+ ErrorLog getErrorLog();
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Lifecycle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Lifecycle.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Lifecycle.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Lifecycle.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,38 @@
+// 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 java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * An optional annotation that may be placed on a service building method of a module. The
+ * annotation overrides the default lifecycle for services (the default being a global singleton
+ * that is instantiated on demand) for an alternate lifecycle. Alternate lifecycles are typically
+ * used to bind a service implementation to a single thread or request.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Lifecycle {
+ /** An identifier used to look up a non-default lifecycle. */
+ String value();
+}
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,52 @@
+// 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 java.util.Set;
+
+/**
+ * Defines the contents of a module. In the default case, this is information about the services
+ * provided by the module builder class.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ModuleDef
+{
+ /** Returns the ids of the services built/provided by the module. */
+ Set<String> getServiceIds();
+
+ /**
+ * Returns a service definition via the fully qualified service id.
+ *
+ * @param serviceId
+ * fully qualified service id
+ * @return service definition or null if it doesn't exist
+ */
+ ServiceDef getServiceDef(String serviceId);
+
+ /**
+ * Returns the module id extracted from the {@link org.apache.tapestry.ioc.annotations.Id}
+ * annotation on the module builder class (or calculated from the module builder's package, if
+ * the annotation is not present).
+ */
+ String getModuleId();
+
+ /**
+ * Returns the class that will be instantiated. Annotated instance methods of this class are
+ * invoked to build services, to decorate/intercept services, and make contributions to other
+ * services.
+ */
+ Class getBuilderClass();
+}
\ No newline at end of file
Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java (from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDef.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDef.java&r1=418781&r2=419581&rev=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDef.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java Thu Jul 6 08:25:45 2006
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.ioc;
+package org.apache.tapestry.ioc.def;
import java.lang.reflect.Method;
@@ -29,7 +29,7 @@
*/
Method getBuilderMethod();
- /** Returns the unqualified service id, derived from the method name. */
+ /** Returns the fully qualified service id, derived from the method name. */
String getServiceId();
/**
@@ -37,4 +37,11 @@
* the outside world, as well as the one used to build proxies.
*/
Class getServiceInterface();
+
+ /**
+ * Returns the lifecycle defined for the service. This is indicated by adding a
+ * {@link org.apache.tapestry.ioc.annotations.Lifecycle} annotation to the builder method for
+ * the service.
+ */
+ String getServiceLifeycle();
}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -18,6 +18,7 @@
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@@ -26,9 +27,10 @@
import org.apache.commons.logging.Log;
import org.apache.hivemind.Resource;
-import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
-import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.transform.ClassTransformation;
@@ -80,11 +82,6 @@
return newMock(Log.class);
}
- protected final InternalComponentResources newInternalComponentResources()
- {
- return newMock(InternalComponentResources.class);
- }
-
protected final void trainAddInjectedField(ClassTransformation ct, Class type,
String suggestedName, Object value, String fieldName)
{
@@ -115,9 +112,9 @@
if (newModified != startModified)
return;
- // Sleep 1/4 second and try again
+ // Sleep 1/20 second and try again
- sleep(250);
+ sleep(50);
}
}
@@ -156,9 +153,38 @@
return newMock(Resource.class);
}
- protected final ComponentTemplate newComponentTemplate()
+ protected final void trainGetBuilderMethod(ServiceDef def, Method m)
+ {
+ def.getBuilderMethod();
+ setReturnValue(m);
+ }
+
+ protected final void trainGetServiceInterface(ServiceDef def, Class serviceInterface)
+ {
+ def.getServiceInterface();
+ setReturnValue(serviceInterface);
+ }
+
+ protected final void trainGetErrorLog(ServiceResources resources, ErrorLog log)
+ {
+ resources.getErrorLog();
+ setReturnValue(log);
+ }
+
+ protected final void trainGetServiceId(ServiceDef def, String serviceId)
+ {
+ def.getServiceId();
+ setReturnValue(serviceId);
+ }
+
+ protected final ServiceResources newServiceResources()
+ {
+ return newMock(ServiceResources.class);
+ }
+
+ protected final ServiceDef newServiceDef()
{
- return newMock(ComponentTemplate.class);
+ return newMock(ServiceDef.class);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TestBase.java Thu Jul 6 08:25:45 2006
@@ -15,6 +15,7 @@
package org.apache.tapestry.test;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.ioc.ErrorLog;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.testng.annotations.Configuration;
@@ -108,6 +109,11 @@
protected final void unreachable()
{
fail("This code should not be reachable.");
+ }
+
+ protected final ErrorLog newErrorLog()
+ {
+ return newMock(ErrorLog.class);
}
}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -74,7 +75,7 @@
}
/** Constructs and returns a new {@link ArrayList} as a copy of the provided list. */
- public static <T> List<T> newList(List<T> list)
+ public static <T> List<T> newList(Collection<T> list)
{
return new ArrayList<T>(list);
}
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=419581&r1=419580&r2=419581&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 Thu Jul 6 08:25:45 2006
@@ -15,4 +15,13 @@
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.
-missing-service=Service ''{0}'' (within module ''{1}'') does not exist.
\ No newline at end of file
+missing-service=Service ''{0}'' (within module ''{1}'') 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.
+no-such-module=Module ''{0}'' does not exist. Please ensure that the JAR file for the module is on the classpath.
+service-wrong-interface=Service ''{0}'' implements interface {1}, which is not compatible with the requested type {2}.
+instantiate-builder-error=Unable to instantiate class {0} as builder for module ''{1}'': {2}
+singleton-proxy-to-string=<Singleton proxy for {0}({1})>
+builder-method-error=Error invoking builder method {0} (for service ''{1}''): {2}
+unknown-builder-parameter=Unexpected parameter type {0} for method {1} (service ''{2}''). The value null will be passed into the builder method. Expect further errors below.
+builder-method-returned-null=Builder method {0} (for service ''{1}'') returned null.
\ No newline at end of file
Added: 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=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/BasicServiceCreatorTest.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,276 @@
+// 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.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class BasicServiceCreatorTest extends InternalBaseTestCase
+{
+ private static final String SERVICE_ID = "ioc.Fie";
+
+ private FieService _fie;
+
+ private String _expectedServiceId;
+
+ private ServiceResources _expectedServiceResources;
+
+ private ErrorLog _expectedErrorLog;
+
+ private Class _expectedServiceInterface;
+
+ private Method findMethod(String name)
+ {
+ return findMethod(this, name);
+ }
+
+ private Method findMethod(Object source, String name)
+ {
+ Class clazz = source.getClass();
+ for (Method m : clazz.getMethods())
+ {
+ if (m.getName().equals(name))
+ return m;
+ }
+
+ throw new RuntimeException("No method named '" + name + "'.");
+ }
+
+ @Test
+ public void noargsMethod()
+ {
+ ServiceDef def = newServiceDef();
+ ServiceResources resources = newServiceResources();
+ ErrorLog log = newErrorLog();
+ _fie = newFieService();
+
+ trainGetServiceId(def, SERVICE_ID);
+
+ trainGetErrorLog(resources, log);
+
+ trainGetServiceInterface(def, FieService.class);
+
+ replay();
+
+ ServiceCreator sc = new BasicServiceCreator(def, this, resources);
+
+ verify();
+
+ trainGetBuilderMethod(def, findMethod("build_noargs"));
+
+ replay();
+
+ Object actual = sc.createService();
+
+ assertSame(actual, _fie);
+
+ verify();
+ }
+
+ @Test
+ public void argsMethod()
+ {
+ ServiceDef def = newServiceDef();
+ ServiceResources resources = newServiceResources();
+ ErrorLog log = newErrorLog();
+
+ _expectedErrorLog = log;
+ _expectedServiceId = SERVICE_ID;
+ _expectedServiceInterface = FieService.class;
+ _expectedServiceResources = resources;
+
+ _fie = newFieService();
+
+ trainGetServiceId(def, SERVICE_ID);
+
+ trainGetErrorLog(resources, log);
+
+ trainGetServiceInterface(def, FieService.class);
+
+ trainGetBuilderMethod(def, findMethod("build_args"));
+
+ replay();
+
+ ServiceCreator sc = new BasicServiceCreator(def, this, resources);
+
+ Object actual = sc.createService();
+
+ assertSame(actual, _fie);
+
+ verify();
+ }
+
+ @Test
+ public void builderMethodReturnsNull()
+ {
+ ServiceDef def = newServiceDef();
+ ServiceResources resources = newServiceResources();
+ ErrorLog log = newErrorLog();
+ _fie = null;
+
+ trainGetServiceId(def, SERVICE_ID);
+
+ trainGetErrorLog(resources, log);
+
+ trainGetServiceInterface(def, FieService.class);
+
+ trainGetBuilderMethod(def, findMethod("build_noargs"));
+
+ replay();
+
+ ServiceCreator sc = new BasicServiceCreator(def, this, resources);
+
+ try
+ {
+ sc.createService();
+ unreachable();
+ }
+ 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.");
+ }
+
+ verify();
+ }
+
+ @Test
+ public void builderMethodFailed()
+ {
+ ServiceDef def = newServiceDef();
+ ServiceResources resources = newServiceResources();
+ ErrorLog log = newErrorLog();
+ _fie = null;
+
+ trainGetServiceId(def, SERVICE_ID);
+
+ trainGetErrorLog(resources, log);
+
+ trainGetServiceInterface(def, FieService.class);
+
+ trainGetBuilderMethod(def, findMethod("build_fail"));
+
+ replay();
+
+ ServiceCreator sc = new BasicServiceCreator(def, this, resources);
+
+ try
+ {
+ sc.createService();
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(
+ ex.getMessage(),
+ "Error invoking 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");
+
+ InvocationTargetException inner1 = (InvocationTargetException) ex.getCause();
+ RuntimeException inner2 = (RuntimeException) inner1.getTargetException();
+
+ assertEquals(inner2.getMessage(), "Method failed.");
+ }
+
+ verify();
+ }
+
+ @Test
+ public void builderMethodHasUnmatchableParameter()
+ {
+ ServiceDef def = newServiceDef();
+ ServiceResources resources = newServiceResources();
+ ErrorLog log = newErrorLog();
+ _fie = newFieService();
+
+ trainGetServiceId(def, SERVICE_ID);
+
+ trainGetErrorLog(resources, log);
+
+ trainGetServiceInterface(def, FieService.class);
+
+ Method method = findMethod("build_invalidargs");
+
+ trainGetBuilderMethod(def, method);
+
+ // The second call is when we need to report the method as having an error.
+
+ trainGetBuilderMethod(def, method);
+
+ log.warn(IOCMessages.unknownBuilderParameter(Object.class, method, SERVICE_ID), null);
+
+ replay();
+
+ ServiceCreator sc = new BasicServiceCreator(def, this, resources);
+
+ Object actual = sc.createService();
+
+ verify();
+
+ assertSame(actual, _fie);
+ }
+
+ private FieService newFieService()
+ {
+ return newMock(FieService.class);
+ }
+
+ public FieService build_noargs()
+ {
+ return _fie;
+ }
+
+ @SuppressNullCheck
+ public FieService build_invalidargs(Object unknown)
+ {
+ return _fie;
+ }
+
+ public FieService build_fail()
+ {
+ throw new RuntimeException("Method failed.");
+ }
+
+ public FieService build_args(String serviceId, ServiceResources resources, ErrorLog errorLog,
+ Class serviceInterface)
+ {
+ assertEquals(serviceId, _expectedServiceId);
+ assertSame(resources, _expectedServiceResources);
+ assertSame(errorLog, _expectedErrorLog);
+ assertSame(serviceInterface, _expectedServiceInterface);
+
+ return _fie;
+ }
+
+}
Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java (from r418781, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleGrinderTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleGrinderTest.java&r1=418781&r2=419581&rev=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleGrinderTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java Thu Jul 6 08:25:45 2006
@@ -19,17 +19,21 @@
import java.util.Set;
import org.apache.tapestry.ioc.ErrorLog;
+import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.test.TestBase;
import org.testng.Assert;
import org.testng.annotations.Test;
import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
/**
* @author Howard M. Lewis Ship
*/
-public class ModuleGrinderTest extends TestBase
+public class DefaultModuleDefImplTest extends TestBase
{
@Test
public void moduleBuilderWithoutId()
@@ -40,18 +44,13 @@
// BigDecimal is arbitrary, any class would do.
- ModuleGrinder g = new ModuleGrinder(BigDecimal.class, log);
+ ModuleDef g = new DefaultModuleDefImpl(BigDecimal.class, log);
Assert.assertEquals("java.math", g.getModuleId());
verify();
}
- protected final ErrorLog newErrorLog()
- {
- return newMock(ErrorLog.class);
- }
-
@Test
public void moduleBuilderWithId()
{
@@ -61,7 +60,7 @@
// BigDecimal is arbitrary, any class would do.
- ModuleGrinder g = new ModuleGrinder(ModuleBuilderWithId.class, log);
+ ModuleDef g = new DefaultModuleDefImpl(ModuleBuilderWithId.class, log);
Assert.assertEquals("tapestry.ioc", g.getModuleId());
@@ -77,29 +76,31 @@
// BigDecimal is arbitrary, any class would do.
- ModuleGrinder g = new ModuleGrinder(SimpleModuleBuilder.class, log);
+ ModuleDef g = new DefaultModuleDefImpl(SimpleModuleBuilder.class, log);
Set<String> ids = g.getServiceIds();
- Assert.assertEquals(ids.size(), 2);
- Assert.assertTrue(ids.contains("Fred"));
- Assert.assertTrue(ids.contains("Barney"));
+ assertEquals(ids.size(), 2);
+ assertTrue(ids.contains("ioc.Fred"));
+ assertTrue(ids.contains("ioc.Barney"));
- ServiceDef sd = g.getServiceDef("Fred");
+ ServiceDef sd = g.getServiceDef("ioc.Fred");
- assertEquals(sd.getServiceId(), "Fred");
+ assertEquals(sd.getServiceId(), "ioc.Fred");
assertEquals(sd.getServiceInterface(), FieService.class);
assertEquals(sd.getBuilderMethod(), SimpleModuleBuilder.class.getMethod("buildFred"));
+ assertEquals(sd.getServiceLifeycle(), IOCConstants.DEFAULT_LIFECYCLE);
- sd = g.getServiceDef("Barney");
+ sd = g.getServiceDef("ioc.Barney");
- assertEquals(sd.getServiceId(), "Barney");
+ assertEquals(sd.getServiceId(), "ioc.Barney");
assertEquals(sd.getServiceInterface(), FoeService.class);
assertEquals(sd.getBuilderMethod(), SimpleModuleBuilder.class.getMethod("buildBarney"));
+ assertEquals(sd.getServiceLifeycle(), "threaded");
verify();
}
@@ -121,16 +122,16 @@
// BigDecimal is arbitrary, any class would do.
- ModuleGrinder g = new ModuleGrinder(ServiceIdConflictMethodBuilder.class, log);
+ ModuleDef g = new DefaultModuleDefImpl(ServiceIdConflictMethodBuilder.class, log);
Set<String> ids = g.getServiceIds();
Assert.assertEquals(ids.size(), 1);
- Assert.assertTrue(ids.contains("Fred"));
+ Assert.assertTrue(ids.contains("ioc.Fred"));
- ServiceDef sd = g.getServiceDef("Fred");
+ ServiceDef sd = g.getServiceDef("ioc.Fred");
- assertEquals(sd.getServiceId(), "Fred");
+ assertEquals(sd.getServiceId(), "ioc.Fred");
assertEquals(sd.getServiceInterface(), FieService.class);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleBuilderWithId.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleBuilderWithId.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleBuilderWithId.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleBuilderWithId.java Thu Jul 6 08:25:45 2006
@@ -17,7 +17,7 @@
import org.apache.tapestry.ioc.annotations.Id;
/**
- * Used by {@link org.apache.tapestry.internal.ioc.ModuleGrinderTest}.
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImplTest}.
*
* @author Howard M. Lewis Ship
*/
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ReadManifest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ReadManifest.java?rev=419581&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ReadManifest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ReadManifest.java Thu Jul 6 08:25:45 2006
@@ -0,0 +1,91 @@
+// 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.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import static java.lang.String.format;
+import static org.apache.tapestry.util.CollectionFactory.newList;
+
+public class ReadManifest
+{
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception
+ {
+ ClassLoader loader = ReadManifest.class.getClassLoader();
+
+ Enumeration<URL> urls = loader.getResources("META-INF/MANIFEST.MF");
+
+ while (urls.hasMoreElements())
+ {
+ URL url = urls.nextElement();
+
+ System.out.println(url);
+
+ InputStream is = url.openStream();
+
+ Manifest mf = new Manifest(is);
+
+ is.close();
+
+ printManifest(mf);
+ }
+
+ }
+
+ static void printManifest(Manifest mf)
+ {
+
+ printAttributes(mf.getMainAttributes());
+
+ if (false)
+ {
+ Map<String, Attributes> entries = mf.getEntries();
+ List<String> keys = newList(entries.keySet());
+ Collections.sort(keys);
+
+ for (String key : keys)
+ {
+ System.out.println(format(" %s", key));
+
+ Attributes a = entries.get(key);
+
+ printAttributes(a);
+
+ }
+ }
+ }
+
+ private static void printAttributes(Attributes a)
+ {
+ for (Object key : a.keySet())
+ {
+ Object value = a.get(key);
+
+ System.out.println(format(" %30s: %s", key, value));
+ }
+
+ }
+}
Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java (from r418781, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java&r1=418781&r2=419581&rev=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceIdConflictMethodBuilder.java Thu Jul 6 08:25:45 2006
@@ -14,11 +14,14 @@
package org.apache.tapestry.internal.ioc;
+import org.apache.tapestry.ioc.annotations.Id;
+
/**
- * Used by {@link org.apache.tapestry.internal.ioc.ModuleGrinderTest}.
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImplTest}.
*
* @author Howard M. Lewis Ship
*/
+@Id("ioc")
public class ServiceIdConflictMethodBuilder
{
public FieService buildFred()
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java Thu Jul 6 08:25:45 2006
@@ -14,11 +14,15 @@
package org.apache.tapestry.internal.ioc;
+import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.Lifecycle;
+
/**
- * Used by {@link org.apache.tapestry.internal.ioc.ModuleGrinderTest}.
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImplTest}.
*
* @author Howard M. Lewis Ship
*/
+@Id("ioc")
public class SimpleModuleBuilder
{
public FieService buildFred()
@@ -26,6 +30,7 @@
return null;
}
+ @Lifecycle("threaded")
public FoeService buildBarney()
{
return null;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/pageload/ComponentTemplateSourceImplTest.java Thu Jul 6 08:25:45 2006
@@ -14,8 +14,6 @@
package org.apache.tapestry.internal.pageload;
-import static org.testng.Assert.assertSame;
-
import java.io.File;
import java.net.URLClassLoader;
import java.util.Locale;
@@ -29,15 +27,17 @@
import org.apache.tapestry.events.UpdateEvent;
import org.apache.tapestry.internal.parser.ComponentTemplate;
import org.apache.tapestry.internal.parser.TemplateParser;
-import org.apache.tapestry.test.BaseTestCase;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.easymock.EasyMock;
import org.testng.Assert;
import org.testng.annotations.Test;
+import static org.testng.Assert.assertSame;
+
/**
* @author Howard M. Lewis Ship
*/
-public class ComponentTemplateSourceImplTest extends BaseTestCase
+public class ComponentTemplateSourceImplTest extends InternalBaseTestCase
{
private static final String PACKAGE = "org.apache.tapestry.internal.pageload";
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java Thu Jul 6 08:25:45 2006
@@ -261,4 +261,9 @@
_registry = null;
_source = null;
}
+
+ protected final InternalComponentResources newInternalComponentResources()
+ {
+ return newMock(InternalComponentResources.class);
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java?rev=419581&r1=419580&r2=419581&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/InternalClassTransformationImplTest.java Thu Jul 6 08:25:45 2006
@@ -415,4 +415,9 @@
assertNull(getters.getObjectArray());
assertNull(getters.getIntArray());
}
+
+ protected final InternalComponentResources newInternalComponentResources()
+ {
+ return newMock(InternalComponentResources.class);
+ }
}