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 2007/10/28 01:42:19 UTC
svn commit: r589241 - in /tapestry/tapestry5/trunk/tapestry-ioc/src:
main/java/org/apache/tapestry/ioc/
main/java/org/apache/tapestry/ioc/annotations/
main/java/org/apache/tapestry/ioc/internal/
main/java/org/apache/tapestry/ioc/services/ site/apt/ tes...
Author: hlship
Date: Sat Oct 27 16:42:16 2007
New Revision: 589241
URL: http://svn.apache.org/viewvc?rev=589241&view=rev
Log:
TAPESTRY-1829: Allow @Marker annotation on module classes, to automatically mark all services of that module with the annotation
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/module.apt
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java Sat Oct 27 16:42:16 2007
@@ -55,5 +55,16 @@
*/
ServiceBindingOptions eagerLoad();
+ /**
+ * Defines the marker interface for the service, used to connect injections by type at the point
+ * of injection with a particular service implementation, based on the intersection of type and
+ * marker interface. The containing module will sometimes provide a default marker interface for
+ * all services within the module, this method allows that default to be overridden (typically a
+ * different marker annotation, but sometimes to null).
+ *
+ * @param <T>
+ * @param marker
+ * @return this binding options, for further configuration
+ */
<T extends Annotation> ServiceBindingOptions withMarker(Class<T> marker);
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotations/Marker.java Sat Oct 27 16:42:16 2007
@@ -29,6 +29,9 @@
* implementation. This allows for injection based on the combination of type and marker interface.
* These marker interfaces should not have any values. The mere presence of the marker annotation is
* all that is needed.
+ * <p>
+ * When applied to a module class, this sets the default marker for all services within the module
+ * (whereas the normal default marker is null).
*/
@Target(
{ TYPE, METHOD })
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java Sat Oct 27 16:42:16 2007
@@ -84,6 +84,8 @@
private final static Map<Class, ConfigurationType> PARAMETER_TYPE_TO_CONFIGURATION_TYPE = newMap();
+ private final Class _defaultMarker;
+
static
{
PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(Configuration.class, UNORDERED);
@@ -98,12 +100,16 @@
* @param classFactory
* TODO
*/
- public DefaultModuleDefImpl(Class builderClass, Logger logger, ClassFactory classFactory)
+ public DefaultModuleDefImpl(Class<?> builderClass, Logger logger, ClassFactory classFactory)
{
_builderClass = builderClass;
_logger = logger;
_classFactory = classFactory;
+ Marker annotation = builderClass.getAnnotation(Marker.class);
+
+ _defaultMarker = annotation != null ? annotation.value() : null;
+
grind();
bind();
}
@@ -325,7 +331,10 @@
{
Marker annotation = method.getAnnotation(Marker.class);
- return annotation == null ? null : annotation.value();
+ // Use the annotation value if present, otherwise use the module's default
+ // (from the module class's annotation, or null if no annotation there).
+
+ return annotation == null ? _defaultMarker : annotation.value();
}
public void addServiceDef(ServiceDef serviceDef)
@@ -384,7 +393,7 @@
return;
}
- ServiceBinderImpl binder = new ServiceBinderImpl(this, _classFactory);
+ ServiceBinderImpl binder = new ServiceBinderImpl(this, _classFactory, _defaultMarker);
bindMethod.invoke(null, binder);
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Sat Oct 27 16:42:16 2007
@@ -50,6 +50,7 @@
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.ioc.internal.util.OneShotLock;
import org.apache.tapestry.ioc.internal.util.Orderer;
+import org.apache.tapestry.ioc.services.Builtin;
import org.apache.tapestry.ioc.services.ClassFab;
import org.apache.tapestry.ioc.services.ClassFabUtils;
import org.apache.tapestry.ioc.services.ClassFactory;
@@ -61,7 +62,6 @@
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.ioc.services.TapestryIOCModule;
import org.apache.tapestry.ioc.services.ThreadCleanupHub;
-import org.apache.tapestry.ioc.services.TapestryIOCModule.Builtin;
import org.apache.tapestry.services.MasterObjectProvider;
import org.slf4j.Logger;
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java Sat Oct 27 16:42:16 2007
@@ -41,10 +41,14 @@
private final ClassFactory _classFactory;
- public ServiceBinderImpl(ServiceDefAccumulator accumulator, ClassFactory classFactory)
+ private final Class _defaultMarker;
+
+ public ServiceBinderImpl(ServiceDefAccumulator accumulator, ClassFactory classFactory,
+ Class defaultMarker)
{
_accumulator = accumulator;
_classFactory = classFactory;
+ _defaultMarker = defaultMarker;
}
private String _serviceId;
@@ -92,7 +96,7 @@
_serviceId = null;
_serviceInterface = null;
- _marker = null;
+ _marker = _defaultMarker;
_serviceImplementation = null;
_eagerLoad = false;
_scope = null;
@@ -138,7 +142,7 @@
Marker marker = serviceImplementation.getAnnotation(Marker.class);
- _marker = marker != null ? marker.value() : null;
+ _marker = marker != null ? marker.value() : _defaultMarker;
return this;
}
@@ -176,8 +180,6 @@
public <T extends Annotation> ServiceBindingOptions withMarker(Class<T> marker)
{
- notNull(marker, "marker");
-
_lock.check();
_marker = marker;
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java?rev=589241&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java Sat Oct 27 16:42:16 2007
@@ -0,0 +1,24 @@
+package org.apache.tapestry.ioc.services;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks services provided by this module that may need to be unambiguously referenced.
+ * Injecting with this marker annotation and the correct type ensure that the version defined in
+ * this module is used, even if another module provides a service with the same service
+ * interface.
+ */
+@Target(
+{ PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Builtin
+{
+
+}
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Sat Oct 27 16:42:16 2007
@@ -14,15 +14,9 @@
package org.apache.tapestry.ioc.services;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
import java.io.File;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -66,48 +60,27 @@
/**
* Defines the base set of services for the Tapestry IOC container.
*/
+@Marker(Builtin.class)
public final class TapestryIOCModule
{
-
- /**
- * Marks services provided by this module that may need to be unambiguously referenced.
- * Injecting with this marker annotation and the correct type ensure that the version defined in
- * this module is used, even if another module provides a service with the same service
- * interface.
- */
- @Target(
- { PARAMETER, FIELD })
- @Retention(RUNTIME)
- @Documented
- public @interface Builtin
- {
-
- };
-
public static void bind(ServiceBinder binder)
{
- binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class).withMarker(Builtin.class);
- binder.bind(ChainBuilder.class, ChainBuilderImpl.class).withMarker(Builtin.class);
- binder.bind(PropertyAccess.class, PropertyAccessImpl.class).withMarker(Builtin.class);
- binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class).withMarker(Builtin.class);
- binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class).withMarker(
- Builtin.class);
- binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class).withMarker(Builtin.class);
- binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class)
- .withMarker(Builtin.class);
- binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class).withMarker(Builtin.class);
- binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class).withMarker(Builtin.class);
- binder.bind(TypeCoercer.class, TypeCoercerImpl.class).withMarker(Builtin.class);
- binder.bind(ThreadLocale.class, ThreadLocaleImpl.class).withMarker(Builtin.class);
- binder.bind(SymbolSource.class, SymbolSourceImpl.class).withMarker(Builtin.class);
- binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults")
- .withMarker(Builtin.class);
- binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults")
- .withMarker(Builtin.class);
- binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup").withMarker(
- Builtin.class);
- binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class).withMarker(
- Builtin.class);
+ binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class);
+ binder.bind(ChainBuilder.class, ChainBuilderImpl.class);
+ binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
+ binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class);
+ binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class);
+ binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class);
+ binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class);
+ binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class);
+ binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class);
+ binder.bind(TypeCoercer.class, TypeCoercerImpl.class);
+ binder.bind(ThreadLocale.class, ThreadLocaleImpl.class);
+ binder.bind(SymbolSource.class, SymbolSourceImpl.class);
+ binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults");
+ binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults");
+ binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup");
+ binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class);
}
/**
@@ -116,7 +89,6 @@
* proxiable services (those with explicit service interfaces) can be managed in terms of a
* lifecycle.
*/
- @Marker(Builtin.class)
public static ServiceLifecycleSource build(final Map<String, ServiceLifecycle> configuration)
{
return new ServiceLifecycleSource()
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/module.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/module.apt?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/module.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/module.apt Sat Oct 27 16:42:16 2007
@@ -18,6 +18,8 @@
* To <decorate> services by providing <interceptors> around them
* To provide explicit code for building a service
+
+ * To set a default <marker> for all services defined in the module
[]
@@ -264,4 +266,36 @@
You don't <have> to define your methods as static. The use of static methods is only absolutely
necessary in a few cases, where the constructor for a module is dependent on contributions
from the same module (this creates a chicken-and-the-egg situation that is resolved through
- static methods).
\ No newline at end of file
+ static methods).
+
+Default Marker
+
+ Services are often referenced by a particular marker interface on the method or contructor parameter. Tapestry
+ will use the intersection of services with that exact marker and assignable by type to find a unique service
+ to inject.
+
+ Often, all services in a module should share a marker, this can be specified with a @Marker annotation
+ on the module class. For example, the TapestryIOCModule:
+
++---+
+@Marker(Builtin.class)
+public final class TapestryIOCModule
+{
+ . . .
++---+
+
+ This references a particular annotation class, Builtin:
+
++---+
+@Target(
+{ PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Builtin
+{
+
+}
++----+
+
+ The annotation can be applied to method and constructor parameters, for use within the IoC container. It can also be applied
+ to fields, though this is specific to the Tapestry web framework.
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=589241&r1=589240&r2=589241&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Sat Oct 27 16:42:16 2007
@@ -23,11 +23,11 @@
import org.apache.tapestry.ioc.internal.ExceptionInConstructorModule;
import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.Builtin;
import org.apache.tapestry.ioc.services.ServiceActivity;
import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
import org.apache.tapestry.ioc.services.Status;
import org.apache.tapestry.ioc.services.TypeCoercer;
-import org.apache.tapestry.ioc.services.TapestryIOCModule.Builtin;
import org.testng.Assert;
import org.testng.annotations.Test;