Author: hlship
Date: Mon Sep 8 17:27:32 2008
New Revision: 693326
URL: http://svn.apache.org/viewvc?rev=693326&view=rev
Log:
TAPESTRY-2554: When decorating a service using a decorate method, the
underlying service (or interceptor) should be available as a parameter of the
service type, not just java.lang.Object
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/SpecificDecoratorModule.java
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImplTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
Mon Sep 8 17:27:32 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -148,7 +148,6 @@
return result;
}
-
};
Arrays.sort(methods, c);
@@ -174,7 +173,6 @@
addContributionDef(m);
continue;
}
-
}
}
@@ -231,15 +229,6 @@
return;
}
- if (!methodContainsObjectParameter(method))
- {
-
logger.warn(IOCMessages.decoratorMethodNeedsDelegateParameter(method));
- return;
- }
-
- // TODO: Check that at least one parameter is type java.lang.Object,
- // since that's how the delegate is passed in.
-
Order orderAnnotation = method.getAnnotation(Order.class);
Match match = method.getAnnotation(Match.class);
@@ -247,7 +236,7 @@
// TODO: Validate constraints here?
- String[] patterns = match == null ? new String[]{decoratorId} :
match.value();
+ String[] patterns = match == null ? new String[] {decoratorId} :
match.value();
DecoratorDef def = new DecoratorDefImpl(decoratorId, method, patterns,
constraints, classFactory);
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
Mon Sep 8 17:27:32 2008
@@ -112,11 +112,6 @@
return MESSAGES.format("unknown-scope", name);
}
- static String decoratorMethodNeedsDelegateParameter(Method method)
- {
- return MESSAGES.format("decorator-method-needs-delegate-parameter",
asString(method));
- }
-
static String decoratorReturnedWrongType(Method method, String serviceId,
Object returned, Class serviceInterface)
{
return MESSAGES.format("decorator-returned-wrong-type",
asString(method), serviceId, returned,
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceDecoratorImpl.java
Mon Sep 8 17:27:32 2008
@@ -62,7 +62,6 @@
parameterDefaults.put(ServiceResources.class, resources);
parameterDefaults.put(Logger.class, logger);
parameterDefaults.put(Class.class, serviceInterface);
-
}
private String methodId()
@@ -76,6 +75,7 @@
Map<Class, Object> parameterDefaults = newMap(this.parameterDefaults);
parameterDefaults.put(Object.class, delegate);
+ parameterDefaults.put(serviceInterface, delegate);
if (logger.isDebugEnabled())
logger.debug(IOCMessages.invokingMethod(methodId()));
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
Mon Sep 8 17:27:32 2008
@@ -33,9 +33,6 @@
many-services-match-marker=Unable to locate a single service assignable to
type %s with marker annotation(s) %s. \
All of the following services match: %s.
unknown-scope=Unknown service scope '%s'.
-decorator-method-needs-delegate-parameter=Decorator methods must a parameter
for the service delegate \
- (i.e., the object the created interceptor will delegate to). \
- Method %s does not include such a parameter, and has been ignored.
decorator-returned-wrong-type=Decorator method %s (invoked for service '%s')
returned %s, \
which is not assignable to the %s service interface.
creating-service=Creating service '%s'.
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/decorator.apt Mon Sep 8
17:27:32 2008
@@ -91,9 +91,9 @@
The values that may be provided to a decorator method are exactly the same
as for a builder
method, with one addition: The underlying service will be passed in
as a parameter of type java.lang.Object (after type erasure, the <<<T
delegate>>> parameter
- becomes <<<Object delegate>>>). A decorator method must have one
- parameter for this purpose.
-
+ becomes <<<Object delegate>>>).
+
+
In the above example, the decorator method recieves the core service
implementation,
the service interface for the Indexer service, the Log for the Indexer
service,
and an interceptor factory that generates logging interceptors.
@@ -104,7 +104,22 @@
The return value of the method is the new interceptor. You may return null
if your
decorator method decides not to decorate the supplied service.
-
+
+
+ Alternately, when targetting services whose type is known at compile time,
you may provide
+ a parameter whose type matches the service interface. For example,
decorateIndexer() will
+ always be applied to the Indexer service, whose type (Indexer) is known. We
could therefore rewrite
+ decorateIndexer() as:
+
++---------------------+
+ public static Indexer decorateIndexer(Indexer delegate, Logger logger,
LoggingDecorator decorator)
+ {
+ return decorator.build(Indexer.class, delegate, "Indexer", logger);
+ }
++---------------------+
+
+
+
Of course, nothing stops you from combining building with decorating inside
the service builder method:
@@ -117,10 +132,9 @@
public class MyAppModule
{
- public static Indexer build(Class serviceInterface, Logger logger,
- LoggingDecorator decorator)
+ public static Indexer build(Logger logger, LoggingDecorator decorator)
{
- return decorator.build(serviceInterface, logger, new IndexerImpl());
+ return decorator.build(Indexer.class, logger, new IndexerImpl());
}
}
+---------------------+
@@ -205,6 +219,10 @@
and that is passed to the last decorator method. The interceptor created
there
is passed to the the next-to-last decorator method, and so forth.
+ It should now be evident that the delegate passed into a decorator method
is sometimes
+ the core service implementation, and some times an interceptor object
created by some other
+ decorator method.
+
Creating your own Decorators
Decorators are a limited form of Aspect Oriented Programming, so we have
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
Mon Sep 8 17:27:32 2008
@@ -183,7 +183,6 @@
List<String> names = service.getNames();
assertEquals(names, Arrays.asList("BARNEY", "FRED"));
-
}
@SuppressWarnings("unchecked")
@@ -903,4 +902,16 @@
r.shutdown();
}
+
+ @Test
+ public void decorator_receive_delegate_by_specific_type()
+ {
+ Registry r = buildRegistry(GreeterModule.class,
SpecificDecoratorModule.class);
+
+ Greeter g = r.getService("HelloGreeter", Greeter.class);
+
+ assertEquals(g.getGreeting(), "HELLO");
+
+ r.shutdown();
+ }
}
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/SpecificDecoratorModule.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/SpecificDecoratorModule.java?rev=693326&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/SpecificDecoratorModule.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/SpecificDecoratorModule.java
Mon Sep 8 17:27:32 2008
@@ -0,0 +1,29 @@
+// Copyright 2008 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.tapestry5.ioc;
+
+public class SpecificDecoratorModule
+{
+ public Greeter decorateHelloGreeter(final Greeter delegate)
+ {
+ return new Greeter()
+ {
+ public String getGreeting()
+ {
+ return delegate.getGreeting().toUpperCase();
+ }
+ };
+ }
+}
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImplTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImplTest.java?rev=693326&r1=693325&r2=693326&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImplTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImplTest.java
Mon Sep 8 17:27:32 2008
@@ -233,25 +233,6 @@
}
@Test
- public void decorator_method_does_not_include_delegate_parameter() throws
Exception
- {
- Class moduleClass = NoDelegateDecoratorMethodModule.class;
- Method m = moduleClass.getMethod("decorateNoDelegate");
-
- Logger logger = mockLogger();
-
- logger.warn(IOCMessages.decoratorMethodNeedsDelegateParameter(m));
-
- replay();
-
- ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, null);
-
- assertTrue(md.getDecoratorDefs().isEmpty());
-
- verify();
- }
-
- @Test
public void contribution_without_annotation()
{
attemptConfigurationMethod(SimpleModule.class, "Barney",
"contributeBarney(Configuration)");