Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
735 additions
and
0 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
impl/src/main/java/org/jboss/weld/extensions/servicehandler/ServiceHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2010, Red Hat, Inc., and individual contributors | ||
* by the @authors tag. See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* 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.jboss.weld.extensions.servicehandler; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Meta annotation that is used to specify an invocation handler for an | ||
* automatically implmented bean. | ||
* | ||
* If the annotation that is annotated with this meta-annotation is applied to | ||
* an interface or abstract class then the container will automatically provide | ||
* a concrete implementation of the class/interface, and delegate all calls to | ||
* abstract methods through the handler class specified by this annotations. | ||
* | ||
* The handler class must have a method with the following signature: | ||
* | ||
* <pre> | ||
* @AroundInvoke public Object aroundInvoke(final InvocationContext invocation) throws Exception | ||
* </pre> | ||
* | ||
* This is the same as an intercepter class. This handler can be injected into | ||
* and use initializer methods, however @PreDestory methods are not availble | ||
* | ||
* @author Stuart Douglas <stuart.w.douglas@gmail.com> | ||
* | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.ANNOTATION_TYPE) | ||
@Documented | ||
public @interface ServiceHandler | ||
{ | ||
Class<?> value(); | ||
} |
93 changes: 93 additions & 0 deletions
93
impl/src/main/java/org/jboss/weld/extensions/servicehandler/ServiceHandlerBeanLifecycle.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2010, Red Hat, Inc., and individual contributors | ||
* by the @authors tag. See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* 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.jboss.weld.extensions.servicehandler; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
import javassist.util.proxy.MethodFilter; | ||
import javassist.util.proxy.ProxyFactory; | ||
import javassist.util.proxy.ProxyObject; | ||
|
||
import javax.enterprise.context.spi.CreationalContext; | ||
import javax.enterprise.inject.spi.Bean; | ||
import javax.enterprise.inject.spi.BeanManager; | ||
|
||
import org.jboss.weld.extensions.bean.BeanLifecycle; | ||
|
||
/** | ||
* Bean lifecycle for ServiceHandler beans | ||
* | ||
* @author Stuart Douglas | ||
* | ||
* @param <T> | ||
* @param <H> | ||
*/ | ||
public class ServiceHandlerBeanLifecycle<T, H> implements BeanLifecycle<T> | ||
{ | ||
private final ProxyFactory factory; | ||
private final Class<? extends T> proxyClass; | ||
private final ServiceHandlerManager<H> handler; | ||
|
||
public ServiceHandlerBeanLifecycle(Class<? extends T> classToImplement, Class<H> handlerClass, BeanManager manager) | ||
{ | ||
handler = new ServiceHandlerManager<H>(handlerClass, manager); | ||
|
||
// create the proxy | ||
factory = new ProxyFactory(); | ||
if (classToImplement.isInterface()) | ||
{ | ||
Class<?>[] interfaces = new Class[1]; | ||
interfaces[0] = classToImplement; | ||
factory.setInterfaces(interfaces); | ||
} | ||
else | ||
{ | ||
factory.setSuperclass(classToImplement); | ||
} | ||
factory.setFilter(new MethodFilter() | ||
{ | ||
public boolean isHandled(Method m) | ||
{ | ||
// ignore finalize() | ||
return !m.getName().equals("finalize"); | ||
} | ||
}); | ||
proxyClass = factory.createClass(); | ||
} | ||
|
||
public T create(Bean<T> bean, CreationalContext<T> creationalContext) | ||
{ | ||
try | ||
{ | ||
H handlerInstance = handler.create((CreationalContext) creationalContext); //not sure if this is ok | ||
ServiceHandlerMethodHandler<T, H> methodHandler = new ServiceHandlerMethodHandler<T, H>(handler, handlerInstance); | ||
T instance = proxyClass.newInstance(); | ||
((ProxyObject) instance).setHandler(methodHandler); | ||
return instance; | ||
} | ||
catch (Exception e) | ||
{ | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public void destroy(Bean<T> bean, T instance, CreationalContext<T> creationalContext) | ||
{ | ||
// handler.dispose(instance); | ||
} | ||
|
||
} |
69 changes: 69 additions & 0 deletions
69
impl/src/main/java/org/jboss/weld/extensions/servicehandler/ServiceHandlerExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2010, Red Hat, Inc., and individual contributors | ||
* by the @authors tag. See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* 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.jboss.weld.extensions.servicehandler; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import javax.enterprise.event.Observes; | ||
import javax.enterprise.inject.spi.AfterBeanDiscovery; | ||
import javax.enterprise.inject.spi.Bean; | ||
import javax.enterprise.inject.spi.BeanManager; | ||
import javax.enterprise.inject.spi.Extension; | ||
import javax.enterprise.inject.spi.ProcessAnnotatedType; | ||
|
||
import org.jboss.weld.extensions.bean.BeanBuilder; | ||
import org.jboss.weld.extensions.util.AnnotationInspector; | ||
|
||
/** | ||
* This extension automatically implements interfaces and abstract classes. | ||
* | ||
* @author Stuart Douglas | ||
* | ||
*/ | ||
public class ServiceHandlerExtension implements Extension | ||
{ | ||
Set<Bean<?>> beans = new HashSet<Bean<?>>(); | ||
|
||
public <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> event, BeanManager beanManager) | ||
{ | ||
ServiceHandler annotation = AnnotationInspector.getMetaAnnotation(event.getAnnotatedType(), ServiceHandler.class); | ||
if (annotation != null) | ||
{ | ||
Class<?> handlerClass = annotation.value(); | ||
try | ||
{ | ||
BeanBuilder builder = new BeanBuilder(beanManager); | ||
builder.defineBeanFromAnnotatedType(event.getAnnotatedType()); | ||
builder.setBeanLifecycle(new ServiceHandlerBeanLifecycle(event.getAnnotatedType().getJavaClass(), handlerClass, beanManager)); | ||
beans.add(builder.create()); | ||
} | ||
catch (IllegalArgumentException e) | ||
{ | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} | ||
|
||
public void afterBeanDiscovery(@Observes AfterBeanDiscovery event) | ||
{ | ||
for (Bean<?> b : beans) | ||
{ | ||
event.addBean(b); | ||
} | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
impl/src/main/java/org/jboss/weld/extensions/servicehandler/ServiceHandlerManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2010, Red Hat, Inc., and individual contributors | ||
* by the @authors tag. See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* 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.jboss.weld.extensions.servicehandler; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Set; | ||
|
||
import javax.enterprise.context.spi.CreationalContext; | ||
import javax.enterprise.inject.spi.BeanManager; | ||
import javax.enterprise.inject.spi.InjectionTarget; | ||
import javax.interceptor.AroundInvoke; | ||
import javax.interceptor.InvocationContext; | ||
|
||
import org.jboss.weld.extensions.annotated.AnnotatedTypeBuilder; | ||
import org.jboss.weld.extensions.util.Reflections; | ||
|
||
/** | ||
* Manages the handler class for the service handler extension. This class is | ||
* responsible for managing the lifecycle of the handler class instances | ||
* | ||
* @author Stuart Douglas | ||
* | ||
*/ | ||
public class ServiceHandlerManager<T> | ||
{ | ||
private final Class<T> handlerClass; | ||
private final Method handlerMethod; | ||
private final InjectionTarget<T> injectionTarget; | ||
|
||
/** | ||
* Creates a wrapper around an AutoProxy handler class | ||
* | ||
* @param handlerClass The handler class | ||
* @throws IllegalArgumentException if the handler class is does not have a | ||
* suitable @AroundInvoke method | ||
*/ | ||
public ServiceHandlerManager(Class<T> handlerClass, BeanManager beanManager) throws IllegalArgumentException | ||
{ | ||
this.handlerClass = handlerClass; | ||
Set<Method> methods = Reflections.getAllMethods(handlerClass); | ||
Method handler = null; | ||
//search for the handler method | ||
for (Method m : methods) | ||
{ | ||
if (m.isAnnotationPresent(AroundInvoke.class)) | ||
{ | ||
if (m.getParameterTypes().length != 1 || m.getParameterTypes()[0] != InvocationContext.class) | ||
{ | ||
throw new IllegalArgumentException("Could not find suitable AroundInvoke method on class " + handlerClass + " methods denoted @AroundInvoke must have a single InvokationContext parameter"); | ||
} | ||
handler = m; | ||
break; | ||
} | ||
} | ||
if (handler == null) | ||
{ | ||
throw new IllegalArgumentException("Could not find suitable AroundInvoke method on class " + handlerClass); | ||
} | ||
handlerMethod = handler; | ||
//now create the InjectionTarget | ||
AnnotatedTypeBuilder<T> typeBuilder = new AnnotatedTypeBuilder<T>().readFromType(handlerClass); | ||
injectionTarget = beanManager.createInjectionTarget(typeBuilder.create()); | ||
} | ||
|
||
public T create(CreationalContext<T> ctx) | ||
{ | ||
T instance = injectionTarget.produce(ctx); | ||
injectionTarget.inject(instance, ctx); | ||
injectionTarget.postConstruct(instance); | ||
return instance; | ||
} | ||
|
||
public Object invoke(Object instance, InvocationContext ctx) throws Exception | ||
{ | ||
return handlerMethod.invoke(instance, ctx); | ||
} | ||
|
||
public Class<?> getHandlerClass() | ||
{ | ||
return handlerClass; | ||
} | ||
|
||
} |
Oops, something went wrong.