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.
+ */
[EMAIL PROTECTED](
+{ PARAMETER, FIELD })
[EMAIL PROTECTED](RUNTIME)
[EMAIL PROTECTED]
+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.
*/
[EMAIL PROTECTED](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:
+
++---+
[EMAIL PROTECTED](Builtin.class)
+public final class TapestryIOCModule
+{
+ . . .
++---+
+
+ This references a particular annotation class, Builtin:
+
++---+
[EMAIL PROTECTED](
+{ PARAMETER, FIELD })
[EMAIL PROTECTED](RUNTIME)
[EMAIL PROTECTED]
+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;