Here's the patch that implements HIVEMIND-96 and HIVEMIND-45. Let me know
what you guys think and I'll go ahead and commit them (separately with
appropriate comments of course).
-----Original Message-----
From: James Carman [mailto:[EMAIL PROTECTED]
Sent: Sunday, February 27, 2005 11:04 AM
To: [email protected]; 'Knut Wannheden'
Subject: RE: AOPAlliance Service Interceptors...
I went to the project level and did a Team -> Update. Then, I go to the
project level and I do a Team -> Create Patch, but it only recognizes my new
classes. This is getting on my nerves, because I have both of these issues
resolved with test cases and I would like to check it into the 1.1 codebase
for you folks to check out.
-----Original Message-----
From: Knut Wannheden [mailto:[EMAIL PROTECTED]
Sent: Sunday, February 27, 2005 11:01 AM
To: [email protected]
Subject: Re: AOPAlliance Service Interceptors...
Sounds strange... Only tips I have:
- Try resynchronizing the entire project
- Create the patch on the Project level
Sorry if this doesn't help, but I can't think of anything else...
--knut
On Sun, 27 Feb 2005 10:47:11 -0500, James Carman
<[EMAIL PROTECTED]> wrote:
> Well, I've got it implemented with test cases, but I can't get Eclipse to
> generate a patch for me! It sees my new classes, but fails to include the
> changes I have made to existing classes/interfaces. HELP!
>
> -----Original Message-----
> From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
> Sent: Sunday, February 27, 2005 10:47 AM
> To: [email protected]
> Subject: Re: AOPAlliance Service Interceptors...
>
> This works for me. Having the name default to the service id is a
> perfectly fine idea.
>
> On Sun, 27 Feb 2005 08:35:50 -0500, James Carman
> <[EMAIL PROTECTED]> wrote:
> >
> >
> >
> > Has anyone else come up with a way to do this cleanly? I think one big
> step
> > in the right direction would be support for overriding the interceptor's
> > name, replacing the factory's id with something else. This way, we
could
> > define ONE service interceptor factory which inserts a MethodInterceptor
> > defined elsewhere in the registry (or inline maybe) and the interceptors
> > could still be ordered, since they could have unique names. We could
> leave
> > it backward compatible, of course, defaulting the interceptor name to
the
> > service id of the interceptor factory.
> >
> >
> >
> > <interceptor service-id="hivemind.lib.MethodInterceptorFactory"
> > name="security">
> >
> > <impl object="service:mymodule.SecurityInterceptor" />
> >
> > </interceptor>
> >
> >
> >
> > <interceptor service-id="hivemind.lib.MethodInterceptorFactory"
> > name="logging" before="security">
> >
> > <impl
> object="instance:com.myco.myproject.interceptor.LoggingInterceptor"
> > />
> >
> > </interceptor>
> >
> >
> >
> > Here, we have defined a service interceptor using another service and
one
> > using just a plain ole object. What do you guys think?
> >
> >
> >
> >
> >
> > -----Original Message-----
> > From: James Carman [mailto:[EMAIL PROTECTED]
> > Sent: Saturday, February 05, 2005 7:35 AM
> > To: [email protected]
> > Subject: AOPAlliance Service Interceptors...
> >
> >
> >
> >
> > -->
> >
> >
> > Hello, All. Since the AOPAlliance Service Interceptors support didn't
> make
> > it into 1.1, when can we expect that to become available? I would like
to
> > discuss service interceptors in my article, but there is NO WAY that I'm
> > going to try to explain how to do it using Javassist. I would like to
use
> > the AOPAlliance stuff.
> >
> >
> >
> > James
>
> --
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
>
> Professional Tapestry training, mentoring, support
> and project work. http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
Index: .classpath
===================================================================
RCS file: /home/cvs/jakarta-hivemind/.classpath,v
retrieving revision 1.48
diff -u -r1.48 .classpath
--- .classpath 11 Feb 2005 01:55:41 -0000 1.48
+++ .classpath 27 Feb 2005 16:47:50 -0000
@@ -27,5 +27,6 @@
<classpathentry kind="lib"
path="ext-package/lib/groovy-all-1.0-beta-9.jar"/>
<classpathentry kind="lib" path="ext-package/lib/cglib-full-2.0.1.jar"/>
<classpathentry kind="lib"
path="ext-package/lib/easymockclassextension-1.1.jar"/>
+ <classpathentry kind="lib" path="ext-package/lib/aopalliance-1.0.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Index:
framework/src/java/org/apache/hivemind/impl/ServiceInterceptorContributionImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/ServiceInterceptorContributionImpl.java,v
retrieving revision 1.10
diff -u -r1.10 ServiceInterceptorContributionImpl.java
---
framework/src/java/org/apache/hivemind/impl/ServiceInterceptorContributionImpl.java
6 Jan 2005 01:45:12 -0000 1.10
+++
framework/src/java/org/apache/hivemind/impl/ServiceInterceptorContributionImpl.java
27 Feb 2005 16:47:51 -0000
@@ -47,6 +47,8 @@
private String _followingInterceptorIds;
+ private String _name;
+
public String toString()
{
ToStringBuilder builder = new ToStringBuilder(this);
@@ -54,10 +56,28 @@
builder.append("parameters", _parameters);
builder.append("precedingInterceptorIds", _precedingInterceptorIds);
builder.append("followingInterceptorIds", _followingInterceptorIds);
-
+ builder.append("name", _name );
return builder.toString();
}
+
+ /**
+ * @return Returns the _name.
+ */
+ public String getName()
+ {
+ if( _name == null )
+ {
+ return getFactoryServiceId();
+ }
+ return _name;
+ }
+
+ public void setName( String name )
+ {
+ _name = name;
+ }
+
public String getFactoryServiceId()
{
return _factoryServiceId;
Index: framework/src/java/org/apache/hivemind/impl/ServicePointImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/ServicePointImpl.java,v
retrieving revision 1.11
diff -u -r1.11 ServicePointImpl.java
--- framework/src/java/org/apache/hivemind/impl/ServicePointImpl.java 17 Feb
2005 19:46:44 -0000 1.11
+++ framework/src/java/org/apache/hivemind/impl/ServicePointImpl.java 27 Feb
2005 16:47:51 -0000
@@ -282,7 +282,7 @@
// the interceptor stack we'll apply them in reverse order,
// building outward from the core service implementation.
- orderer.add(sic, sic.getFactoryServiceId(),
sic.getPrecedingInterceptorIds(), sic
+ orderer.add(sic, sic.getName(), sic.getPrecedingInterceptorIds(),
sic
.getFollowingInterceptorIds());
}
Index:
framework/src/java/org/apache/hivemind/internal/ServiceInterceptorContribution.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ServiceInterceptorContribution.java,v
retrieving revision 1.4
diff -u -r1.4 ServiceInterceptorContribution.java
---
framework/src/java/org/apache/hivemind/internal/ServiceInterceptorContribution.java
19 Feb 2005 02:40:54 -0000 1.4
+++
framework/src/java/org/apache/hivemind/internal/ServiceInterceptorContribution.java
27 Feb 2005 16:47:51 -0000
@@ -24,6 +24,8 @@
*/
public interface ServiceInterceptorContribution extends Locatable
{
+ public String getName();
+
/**
* Returns the id of the factory that creates the interceptor. Interceptor
factories are simply
* another HiveMind service, one that implements
Index: framework/src/java/org/apache/hivemind/parse/DescriptorParser.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/parse/DescriptorParser.java,v
retrieving revision 1.48
diff -u -r1.48 DescriptorParser.java
--- framework/src/java/org/apache/hivemind/parse/DescriptorParser.java 19 Feb
2005 13:42:56 -0000 1.48
+++ framework/src/java/org/apache/hivemind/parse/DescriptorParser.java 27 Feb
2005 16:47:51 -0000
@@ -935,7 +935,7 @@
id.setBefore(getAttribute("before"));
id.setAfter(getAttribute("after"));
-
+ id.setName(getAttribute("name" ));
sd.addInterceptor(id);
}
Index: framework/src/java/org/apache/hivemind/parse/DescriptorParser.properties
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/parse/DescriptorParser.properties,v
retrieving revision 1.18
diff -u -r1.18 DescriptorParser.properties
--- framework/src/java/org/apache/hivemind/parse/DescriptorParser.properties
10 Feb 2005 01:04:34 -0000 1.18
+++ framework/src/java/org/apache/hivemind/parse/DescriptorParser.properties
27 Feb 2005 16:47:51 -0000
@@ -38,6 +38,7 @@
required.interceptor.before=false
required.interceptor.after=false
+required.interceptor.name=false
required.interceptor.service-id=true
required.element.name=true
Index: framework/src/java/org/apache/hivemind/parse/InterceptorDescriptor.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/parse/InterceptorDescriptor.java,v
retrieving revision 1.6
diff -u -r1.6 InterceptorDescriptor.java
--- framework/src/java/org/apache/hivemind/parse/InterceptorDescriptor.java
5 Jan 2005 18:05:37 -0000 1.6
+++ framework/src/java/org/apache/hivemind/parse/InterceptorDescriptor.java
27 Feb 2005 16:47:51 -0000
@@ -25,7 +25,8 @@
{
private String _before;
private String _after;
-
+ private String _name;
+
public String getAfter()
{
return _after;
@@ -46,10 +47,26 @@
_before = string;
}
+ /**
+ * @return Returns the name.
+ */
+ public String getName()
+ {
+ return _name;
+ }
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name)
+ {
+ this._name = name;
+ }
+
protected void extendDescription(ToStringBuilder builder)
{
builder.append("before", _before);
builder.append("after", _after);
+ builder.append("name", _name);
}
}
Index: framework/src/test/hivemind/test/parse/GenericModule.xml
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/parse/GenericModule.xml,v
retrieving revision 1.10
diff -u -r1.10 GenericModule.xml
--- framework/src/test/hivemind/test/parse/GenericModule.xml 5 Jan 2005
21:53:32 -0000 1.10
+++ framework/src/test/hivemind/test/parse/GenericModule.xml 27 Feb 2005
16:47:52 -0000
@@ -68,11 +68,11 @@
<service-point id="MyService1" interface="package.MyService">
Description of MyService1.
<create-instance class="package.impl.MyServiceImpl"/>
- <interceptor service-id="MyInterceptor"
before="OtherInterceptor"/>
- <interceptor service-id="OtherInterceptor"
after="MyInterceptor"/>
+ <interceptor service-id="MyInterceptor"
before="OtherInterceptor" name="MyInterceptorName"/>
+ <interceptor service-id="OtherInterceptor"
after="MyInterceptorName"/>
</service-point>
<implementation service-id="othermodule.OtherService">
- <interceptor service-id="MyInterceptor"/>
+ <interceptor service-id="MyInterceptor" />
</implementation>
<service-point id="MyServiceFactory"
interface="org.apache.hivemind.ServiceImplementationFactory"
Index: framework/src/test/hivemind/test/parse/TestDescriptorParser.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/parse/TestDescriptorParser.java,v
retrieving revision 1.31
diff -u -r1.31 TestDescriptorParser.java
--- framework/src/test/hivemind/test/parse/TestDescriptorParser.java 10 Feb
2005 01:04:33 -0000 1.31
+++ framework/src/test/hivemind/test/parse/TestDescriptorParser.java 27 Feb
2005 16:47:52 -0000
@@ -190,10 +190,12 @@
InterceptorDescriptor id = (InterceptorDescriptor) l.get(0);
assertEquals("MyInterceptor", id.getFactoryServiceId());
assertEquals("OtherInterceptor", id.getBefore());
-
+ assertEquals( "MyInterceptorName", id.getName() );
+
id = (InterceptorDescriptor) l.get(1);
assertEquals("OtherInterceptor", id.getFactoryServiceId());
- assertEquals("MyInterceptor", id.getAfter());
+ assertEquals("MyInterceptorName", id.getAfter());
+ assertNull(id.getName());
}
public void testImplementation() throws Exception
Index: framework/src/test/org/apache/hivemind/impl/TestServicePoint.java
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/framework/src/test/org/apache/hivemind/impl/TestServicePoint.java,v
retrieving revision 1.4
diff -u -r1.4 TestServicePoint.java
--- framework/src/test/org/apache/hivemind/impl/TestServicePoint.java 17 Feb
2005 19:46:45 -0000 1.4
+++ framework/src/test/org/apache/hivemind/impl/TestServicePoint.java 27 Feb
2005 16:47:52 -0000
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import org.apache.hivemind.ApplicationRuntimeException;
@@ -41,7 +42,7 @@
result.setClassResolver(new DefaultClassResolver());
result.setPackageName("");
-
+ result.setRegistry(new RegistryInfrastructureImpl( new
StrictErrorHandler(), Locale.getDefault()));
return result;
}
@@ -73,6 +74,90 @@
verifyControls();
}
+ public void testDefaultInterceptorOrdering()
+ {
+ Location l = fabricateLocation(12);
+ Module module = newModule();
+
+ replayControls();
+
+ ServicePointImpl sp = new ServicePointImpl();
+ sp.setModule(module);
+ sp.setServiceInterfaceName("foo.bar.Baz");
+ sp.setExtensionPointId("zip.zap");
+ sp.setLocation(l);
+ final ServiceInterceptorContributionImpl interceptor1 = new
ServiceInterceptorContributionImpl();
+ interceptor1.setFactoryServiceId( "SomeFactory1" );
+ sp.addInterceptorContribution( interceptor1 );
+ final ServiceInterceptorContributionImpl interceptor2 = new
ServiceInterceptorContributionImpl();
+ interceptor2.setFactoryServiceId( "SomeFactory2" );
+ sp.addInterceptorContribution( interceptor2 );
+ sp.setExtensionPointId( "ExtensionPointId" );
+ final List ordered = sp.getOrderedInterceptorContributions();
+ assertNotNull( ordered );
+ assertEquals( 2, ordered.size() );
+ assertEquals( interceptor1, ordered.get( 0 ) );
+ assertEquals( interceptor2, ordered.get( 1 ) );
+ verifyControls();
+ }
+
+ public void testCustomInterceptorOrdering()
+ {
+ Location l = fabricateLocation(12);
+ Module module = newModule();
+
+ replayControls();
+
+ ServicePointImpl sp = new ServicePointImpl();
+ sp.setModule(module);
+ sp.setServiceInterfaceName("foo.bar.Baz");
+ sp.setExtensionPointId("zip.zap");
+ sp.setLocation(l);
+ final ServiceInterceptorContributionImpl interceptor1 = new
ServiceInterceptorContributionImpl();
+ interceptor1.setFactoryServiceId( "SomeFactory1" );
+ sp.addInterceptorContribution( interceptor1 );
+ final ServiceInterceptorContributionImpl interceptor2 = new
ServiceInterceptorContributionImpl();
+ interceptor2.setFactoryServiceId( "SomeFactory2" );
+ interceptor2.setFollowingInterceptorIds("SomeFactory1");
+ sp.addInterceptorContribution( interceptor2 );
+ sp.setExtensionPointId( "ExtensionPointId" );
+ final List ordered = sp.getOrderedInterceptorContributions();
+ assertNotNull( ordered );
+ assertEquals( 2, ordered.size() );
+ assertEquals( interceptor2, ordered.get( 0 ) );
+ assertEquals( interceptor1, ordered.get( 1 ) );
+ verifyControls();
+ }
+
+ public void testInterceptorOrderingByName()
+ {
+ Location l = fabricateLocation(12);
+ Module module = newModule();
+
+ replayControls();
+
+ ServicePointImpl sp = new ServicePointImpl();
+ sp.setModule(module);
+ sp.setServiceInterfaceName("foo.bar.Baz");
+ sp.setExtensionPointId("zip.zap");
+ sp.setLocation(l);
+ final ServiceInterceptorContributionImpl interceptor1 = new
ServiceInterceptorContributionImpl();
+ interceptor1.setFactoryServiceId( "SomeFactory1" );
+ interceptor1.setName( "Interceptor1" );
+ sp.addInterceptorContribution( interceptor1 );
+ final ServiceInterceptorContributionImpl interceptor2 = new
ServiceInterceptorContributionImpl();
+ interceptor2.setFactoryServiceId( "SomeFactory2" );
+ interceptor2.setFollowingInterceptorIds("Interceptor1");
+ sp.addInterceptorContribution( interceptor2 );
+ sp.setExtensionPointId( "ExtensionPointId" );
+ final List ordered = sp.getOrderedInterceptorContributions();
+ assertNotNull( ordered );
+ assertEquals( 2, ordered.size() );
+ assertEquals( interceptor2, ordered.get( 0 ) );
+ assertEquals( interceptor1, ordered.get( 1 ) );
+ verifyControls();
+ }
+
public void testResultNotAssignableToServiceInterface()
{
Location l = fabricateLocation(187);
Index: library/build.xml
===================================================================
RCS file: /home/cvs/jakarta-hivemind/library/build.xml,v
retrieving revision 1.15
diff -u -r1.15 build.xml
--- library/build.xml 1 Feb 2005 11:59:01 -0000 1.15
+++ library/build.xml 27 Feb 2005 16:47:52 -0000
@@ -46,7 +46,7 @@
<ibiblio-dependency artifact="servletapi" version="2.3"
group="servletapi" use="test"/>
<ibiblio-dependency artifact="oro" version="2.0.6" group="oro"
use="test"/>
<ibiblio-dependency artifact="easymock" version="1.1"
group="easymock" use="test"/>
-
+ <ibiblio-dependency artifact="aopalliance" version="1.0"
group="aopalliance" />
<project-dependency artifact="hivemind"/>
<default-compile/>
Index: library/src/descriptor/META-INF/hivemodule.xml
===================================================================
RCS file:
/home/cvs/jakarta-hivemind/library/src/descriptor/META-INF/hivemodule.xml,v
retrieving revision 1.22
diff -u -r1.22 hivemodule.xml
--- library/src/descriptor/META-INF/hivemodule.xml 10 Feb 2005 01:04:34
-0000 1.22
+++ library/src/descriptor/META-INF/hivemodule.xml 27 Feb 2005 16:47:53
-0000
@@ -440,5 +440,22 @@
</parameters-schema>
</service-point>
-
+ <service-point id="MethodInterceptorFactory" parameters-occurs="1"
interface="org.apache.hivemind.ServiceInterceptorFactory">
+ <invoke-factory>
+ <construct class="org.apache.hivemind.lib.impl.MethodInterceptorFactory"
/>
+ </invoke-factory>
+
+ <parameters-schema>
+ <element name="impl">
+ <attribute name="object" required="true" translator="object">
+ The implementation object which implements the MethodInterceptor
interface.
+ </attribute>
+
+ <rules>
+ <push-attribute attribute="object" />
+ <invoke-parent method="addElement" />
+ </rules>
+ </element>
+ </parameters-schema>
+ </service-point>
</module>
Index:
framework/src/test/org/apache/hivemind/impl/TestServiceInterceptorContributionImpl.java
===================================================================
RCS file:
framework/src/test/org/apache/hivemind/impl/TestServiceInterceptorContributionImpl.java
diff -N
framework/src/test/org/apache/hivemind/impl/TestServiceInterceptorContributionImpl.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
framework/src/test/org/apache/hivemind/impl/TestServiceInterceptorContributionImpl.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+//Copyright 2004, 2005 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.hivemind.impl;
+
+import org.apache.hivemind.test.HiveMindTestCase;
+
+/**
+ * Tests for [EMAIL PROTECTED] ServiceInterceptorContributionImpl}.
+ * @author James Carman
+ */
+public class TestServiceInterceptorContributionImpl extends HiveMindTestCase
+{
+ private static final String NAME = "SomeName";
+ private static final String FACTORY_ID = "SomeFactoryId";
+
+ /**
+ * Tests to make sure that the name defaults to the factory id.
+ *
+ */
+ public void testNameDefault()
+ {
+ final ServiceInterceptorContributionImpl impl = new
ServiceInterceptorContributionImpl();
+ impl.setFactoryServiceId( FACTORY_ID );
+ assertEquals( FACTORY_ID, impl.getName() );
+ }
+
+ /**
+ * Tests to make sure that the name override works.
+ *
+ */
+ public void testNameOverride()
+ {
+ final ServiceInterceptorContributionImpl impl = new
ServiceInterceptorContributionImpl();
+ impl.setFactoryServiceId( FACTORY_ID );
+ impl.setName( NAME );
+ assertEquals( NAME, impl.getName() );
+ }
+}
Index:
library/src/java/org/apache/hivemind/lib/impl/MethodInterceptorFactory.java
===================================================================
RCS file:
library/src/java/org/apache/hivemind/lib/impl/MethodInterceptorFactory.java
diff -N
library/src/java/org/apache/hivemind/lib/impl/MethodInterceptorFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/java/org/apache/hivemind/lib/impl/MethodInterceptorFactory.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,149 @@
+//Copyright 2004, 2005 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.hivemind.lib.impl;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.hivemind.InterceptorStack;
+import org.apache.hivemind.ServiceInterceptorFactory;
+import org.apache.hivemind.internal.Module;
+
+/**
+ * A service interceptor factory supporting the AOP Alliance MethodInterceptor
interface.
+ * <b>Note:</b>The current implementation uses JDK proxies as opposed to
Javassist!
+ * @author James Carman
+ */
+public class MethodInterceptorFactory implements ServiceInterceptorFactory
+{
+
+ /**
+ *
+ * @see
org.apache.hivemind.ServiceInterceptorFactory#createInterceptor(org.apache.hivemind.InterceptorStack,
org.apache.hivemind.internal.Module, java.util.List)
+ */
+ public void createInterceptor(InterceptorStack stack, Module
invokingModule, List parameters)
+ {
+ final Class[] interfaces = new Class[]{stack.getServiceInterface()};
+ final ClassLoader classLoader =
invokingModule.getClassResolver().getClassLoader();
+ final InvocationHandler invocationHandler = new
MethodInterceptorInvocationHandler( ( MethodInterceptor )parameters.get( 0 ),
stack );
+ stack.push( Proxy.newProxyInstance( classLoader, interfaces,
invocationHandler ) );
+ }
+
+ /**
+ * A java proxy InvocationHandler implementation which allows a
MethodInterceptor to intercept the method invocation.
+ */
+ private final class MethodInterceptorInvocationHandler implements
InvocationHandler
+ {
+ private final MethodInterceptor methodInterceptor;
+ private final InterceptorStack stack;
+ private final Object target;
+
+ /**
+ * Constructs a MethodInterceptorInvocationHandler
+ *
+ * @param stack the interceptor stack
+ */
+ public MethodInterceptorInvocationHandler( MethodInterceptor
methodInterceptor, InterceptorStack stack )
+ {
+ this.stack = stack;
+ this.target = stack.peek();
+ this.methodInterceptor = methodInterceptor;
+ }
+
+ /**
+ * Calls the MethodInterceptor's invoke method.
+ * @param proxy a reference to the proxy instance
+ * @param method the method being invoked
+ * @param args the arguments to the method
+ * @return the value returned by the MethodInterceptor
+ * @throws Throwable
+ */
+ public Object invoke( Object proxy, Method method, Object[] args )
throws Throwable
+ {
+ return methodInterceptor.invoke( new MethodInvocationImpl( target,
method, args, stack.peek() ) );
+ }
+ }
+
+ /**
+ * A java reflection-based implementation of a MethodInvocation
+ */
+ private final class MethodInvocationImpl implements MethodInvocation
+ {
+ private final Object next;
+ private final Method method;
+ private final Object[] arguments;
+ private final Object proxy;
+
+ /**
+ * Constructs a MethodInvocationImpl object.
+ *
+ * @param next the next object
+ * @param method the method
+ * @param arguments the arguments
+ * @param proxy the outermost proxy object (allows calling another
method instead).
+ */
+ public MethodInvocationImpl( Object next, Method method, Object[]
arguments, Object proxy )
+ {
+ this.next = next;
+ this.method = method;
+ this.arguments = arguments;
+ this.proxy = proxy;
+ }
+
+ /**
+ * Invokes the method on the next object.
+ *
+ * @return value returned by invoking the method on the next object
+ * @throws Throwable throwable thrown by invoking method on the next
object
+ */
+ public final Object proceed() throws Throwable
+ {
+ try
+ {
+ return method.invoke( next, arguments );
+ }
+ catch( InvocationTargetException e )
+ {
+ throw e.getTargetException();
+ }
+ }
+
+ public final Method getMethod()
+ {
+ return method;
+ }
+
+ public final AccessibleObject getStaticPart()
+ {
+ return method;
+ }
+
+ public final Object getThis()
+ {
+ return proxy;
+ }
+
+ public final Object[] getArguments()
+ {
+ return arguments;
+ }
+ }
+}
Index: library/src/test/org/apache/hivemind/lib/impl/FortuneCookie.java
===================================================================
RCS file: library/src/test/org/apache/hivemind/lib/impl/FortuneCookie.java
diff -N library/src/test/org/apache/hivemind/lib/impl/FortuneCookie.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/test/org/apache/hivemind/lib/impl/FortuneCookie.java 1 Jan
1970 00:00:00 -0000
@@ -0,0 +1,23 @@
+//Copyright 2004, 2005 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.hivemind.lib.impl;
+
+/**
+ * @author James Carman
+ */
+public interface FortuneCookie
+{
+ public String generateFortune();
+}
Index: library/src/test/org/apache/hivemind/lib/impl/FortuneCookieImpl.java
===================================================================
RCS file: library/src/test/org/apache/hivemind/lib/impl/FortuneCookieImpl.java
diff -N library/src/test/org/apache/hivemind/lib/impl/FortuneCookieImpl.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/test/org/apache/hivemind/lib/impl/FortuneCookieImpl.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,29 @@
+//Copyright 2004, 2005 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.hivemind.lib.impl;
+
+/**
+ * @author James Carman
+ */
+public class FortuneCookieImpl implements FortuneCookie
+{
+ public static final String FORTUNE = "You will conquer obstacles to
achieve success";
+
+ public String generateFortune()
+ {
+ return FORTUNE;
+ }
+
+}
Index:
library/src/test/org/apache/hivemind/lib/impl/InstanceMethodInterceptor.xml
===================================================================
RCS file:
library/src/test/org/apache/hivemind/lib/impl/InstanceMethodInterceptor.xml
diff -N
library/src/test/org/apache/hivemind/lib/impl/InstanceMethodInterceptor.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/test/org/apache/hivemind/lib/impl/InstanceMethodInterceptor.xml
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2004, 2005 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.
+-->
+
+<module id="hivemind.lib.test" version="1.0.0">
+
+ <service-point id="FortuneCookie"
interface="org.apache.hivemind.lib.impl.FortuneCookie">
+ <create-instance class="org.apache.hivemind.lib.impl.FortuneCookieImpl"/>
+ <interceptor service-id="hivemind.lib.MethodInterceptorFactory">
+ <impl
object="instance:org.apache.hivemind.lib.impl.SuffixMethodInterceptor" />
+ </interceptor>
+ </service-point>
+
+</module>
Index:
library/src/test/org/apache/hivemind/lib/impl/ServiceMethodInterceptor.xml
===================================================================
RCS file:
library/src/test/org/apache/hivemind/lib/impl/ServiceMethodInterceptor.xml
diff -N
library/src/test/org/apache/hivemind/lib/impl/ServiceMethodInterceptor.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/test/org/apache/hivemind/lib/impl/ServiceMethodInterceptor.xml
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2004, 2005 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.
+-->
+
+<module id="hivemind.lib.test" version="1.0.0">
+
+ <service-point id="FortuneCookie"
interface="org.apache.hivemind.lib.impl.FortuneCookie">
+ <create-instance class="org.apache.hivemind.lib.impl.FortuneCookieImpl"/>
+ <interceptor service-id="hivemind.lib.MethodInterceptorFactory">
+ <impl object="service:SuffixMethodInterceptor" />
+ </interceptor>
+ </service-point>
+
+ <service-point id="SuffixMethodInterceptor"
interface="org.aopalliance.intercept.MethodInterceptor">
+ <create-instance
class="org.apache.hivemind.lib.impl.SuffixMethodInterceptor"/>
+ </service-point>
+
+</module>
Index:
library/src/test/org/apache/hivemind/lib/impl/SuffixMethodInterceptor.java
===================================================================
RCS file:
library/src/test/org/apache/hivemind/lib/impl/SuffixMethodInterceptor.java
diff -N
library/src/test/org/apache/hivemind/lib/impl/SuffixMethodInterceptor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ library/src/test/org/apache/hivemind/lib/impl/SuffixMethodInterceptor.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,31 @@
+//Copyright 2004, 2005 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.hivemind.lib.impl;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * @author James Carman
+ */
+public class SuffixMethodInterceptor implements MethodInterceptor
+{
+ public static final String SUFFIX = " in bed.";
+
+ public Object invoke(MethodInvocation invocation) throws Throwable
+ {
+ return invocation.proceed() + SUFFIX;
+ }
+}
Index:
library/src/test/org/apache/hivemind/lib/impl/TestMethodInterceptorFactory.java
===================================================================
RCS file:
library/src/test/org/apache/hivemind/lib/impl/TestMethodInterceptorFactory.java
diff -N
library/src/test/org/apache/hivemind/lib/impl/TestMethodInterceptorFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
library/src/test/org/apache/hivemind/lib/impl/TestMethodInterceptorFactory.java
1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,41 @@
+//Copyright 2004, 2005 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.hivemind.lib.impl;
+
+import org.apache.hivemind.Registry;
+import org.apache.hivemind.test.HiveMindTestCase;
+
+/**
+ * Tests for [EMAIL PROTECTED] MethodInterceptorFactory}.
+ *
+ * @author James Carman
+ */
+public class TestMethodInterceptorFactory extends HiveMindTestCase
+{
+
+ public void testWithInstanceMethodInterceptor() throws Exception
+ {
+ Registry registry =
buildFrameworkRegistry("InstanceMethodInterceptor.xml");
+ final FortuneCookie cookie = (FortuneCookie)
registry.getService(FortuneCookie.class);
+ assertEquals( FortuneCookieImpl.FORTUNE +
SuffixMethodInterceptor.SUFFIX, cookie.generateFortune());
+ }
+
+ public void testWithServiceMethodInterceptor() throws Exception
+ {
+ Registry registry =
buildFrameworkRegistry("ServiceMethodInterceptor.xml");
+ final FortuneCookie cookie = (FortuneCookie)
registry.getService(FortuneCookie.class);
+ assertEquals( FortuneCookieImpl.FORTUNE +
SuffixMethodInterceptor.SUFFIX, cookie.generateFortune());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]