Skip to content

Commit

Permalink
Services now use dynamic beans instead of a type-overridden producer …
Browse files Browse the repository at this point in the history
…method to do remote injection
  • Loading branch information
lincolnthree committed Jan 15, 2013
1 parent a4351c0 commit 5686a33
Show file tree
Hide file tree
Showing 22 changed files with 2,109 additions and 208 deletions.
14 changes: 7 additions & 7 deletions container/pom.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!-- ~ JBoss, by Red Hat. ~ 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. ~ ~ This is free software; you can redistribute it and/or
modify it ~ under the terms of the GNU Lesser General Public License as ~ published by the Free Software Foundation; either
version 2.1 of ~ the License, or (at your option) any later version. ~ ~ This software is distributed in the hope that it
will be useful, ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU ~ Lesser General Public License for more details. ~ ~ You should have received a copy of the GNU Lesser
General Public ~ License along with this software; if not, write to the Free ~ Software Foundation, Inc., 51 Franklin St,
<!-- ~ JBoss, by Red Hat. ~ 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. ~ ~ This is free software; you can redistribute it and/or
modify it ~ under the terms of the GNU Lesser General Public License as ~ published by the Free Software Foundation; either
version 2.1 of ~ the License, or (at your option) any later version. ~ ~ This software is distributed in the hope that it
will be useful, ~ but WITHOUT ANY WARRANTY; without even the implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU ~ Lesser General Public License for more details. ~ ~ You should have received a copy of the GNU Lesser
General Public ~ License along with this software; if not, write to the Free ~ Software Foundation, Inc., 51 Franklin St,
Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org. -->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;

import org.jboss.forge.container.services.RemoteServiceProxyBeanProducerMethod;

public class ContainerBeanRegistrant implements Extension
{
public void registerWeldSEBeans(@Observes BeforeBeanDiscovery event, BeanManager manager)
Expand All @@ -17,6 +15,5 @@ public void registerWeldSEBeans(@Observes BeforeBeanDiscovery event, BeanManager
event.addAnnotatedType(manager.createAnnotatedType(AddonRepositoryProducer.class));
event.addAnnotatedType(manager.createAnnotatedType(ForgeProducer.class));
event.addAnnotatedType(manager.createAnnotatedType(ServiceRegistryProducer.class));
event.addAnnotatedType(manager.createAnnotatedType(RemoteServiceProxyBeanProducerMethod.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,64 @@
*/
package org.jboss.forge.container.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessInjectionPoint;
import javax.enterprise.inject.spi.ProcessProducer;

import net.sf.cglib.proxy.Enhancer;

import org.jboss.forge.container.AddonRegistry;
import org.jboss.forge.container.events.CrossContainerObserverMethod;
import org.jboss.forge.container.exception.ContainerException;
import org.jboss.forge.container.services.Remote;
import org.jboss.forge.container.services.RemoteServiceInjectionPoint;
import org.jboss.forge.container.services.RemoteServiceProxyBeanProducer;
import org.jboss.forge.container.services.RemoteServiceProxyBeanCallback;
import org.jboss.forge.container.util.Annotations;
import org.jboss.forge.container.util.BeanManagerUtils;
import org.jboss.forge.container.util.Types;
import org.jboss.forge.container.util.cdi.BeanBuilder;
import org.jboss.forge.container.util.cdi.ContextualLifecycle;

/**
* One classloader/thread/weld container per plugin module. One primary executor container running, fires events to each
* plugin-container.
*
* Addons may depend on other addons beans, but these beans must be explicitly exposed via the {@link Remote} and
* {@link Service} API.
*/
public class ContainerServiceExtension implements Extension
{
private Logger logger = Logger.getLogger(getClass().getName());
private Set<Class<?>> services = new HashSet<Class<?>>();
private static Logger logger = Logger.getLogger(ContainerServiceExtension.class.getName());

public void wireCrossContainerEvents(@Observes AfterBeanDiscovery event)
{
event.addObserverMethod(new CrossContainerObserverMethod());
}
private Map<Class<?>, AnnotatedType<?>> services = new HashMap<Class<?>, AnnotatedType<?>>();
private Map<Class<?>, InjectionPoint> requestedServices = new HashMap<Class<?>, InjectionPoint>();
private static final ServiceLiteral SERVICE_LITERAL = new ServiceLiteral();

@SuppressWarnings({ "rawtypes", "unchecked" })
public void processRemotes(@Observes ProcessAnnotatedType<?> event) throws InstantiationException,
IllegalAccessException
{
Class<?> type = event.getAnnotatedType().getJavaClass();
if (Annotations.isAnnotationPresent(type, Remote.class))
{
event.setAnnotatedType(new RemoteAnnotatedType(event.getAnnotatedType()));
if (type.getClassLoader().equals(Thread.currentThread().getContextClassLoader()))
{
services.add(event.getAnnotatedType().getJavaClass());
services.put(event.getAnnotatedType().getJavaClass(), event.getAnnotatedType());
}
}
}

public void processRemoteInjectionPoint(@Observes ProcessInjectionPoint<?, ?> event, BeanManager manager)
public void processRemoteInjectionPointConsumer(@Observes ProcessInjectionPoint<?, ?> event, BeanManager manager)
{
Annotated annotated = event.getInjectionPoint().getAnnotated();

Expand All @@ -84,14 +83,8 @@ public void processRemoteInjectionPoint(@Observes ProcessInjectionPoint<?, ?> ev
}
else
{
event.setInjectionPoint(new RemoteServiceInjectionPoint(event.getInjectionPoint(), new Service()
{
@Override
public Class<? extends Annotation> annotationType()
{
return Service.class;
}
}));
event.setInjectionPoint(new RemoteServiceInjectionPoint(event.getInjectionPoint(), SERVICE_LITERAL));
requestedServices.put(injectionBeanValueType, event.getInjectionPoint());
}
}
else if (remote != null)
Expand All @@ -100,7 +93,6 @@ else if (remote != null)
}
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public void processProducerHooks(@Observes ProcessProducer<?, ?> event, BeanManager manager)
{
Class<?> type = Types.toClass(event.getAnnotatedMember().getJavaMember());
Expand All @@ -109,15 +101,70 @@ public void processProducerHooks(@Observes ProcessProducer<?, ?> event, BeanMana
{
if (Annotations.isAnnotationPresent(type, Remote.class))
{
event.setProducer(new RemoteServiceProxyBeanProducer(manager, event.getProducer(), type));
services.add(type);
services.put(type, manager.createAnnotatedType(type));
}
}
}

public void wireCrossContainerEvents(@Observes AfterBeanDiscovery event, final BeanManager manager)
{
event.addObserverMethod(new CrossContainerObserverMethod());

// needs to happen in the addon that is requesting the service
for (final Entry<Class<?>, InjectionPoint> entry : requestedServices.entrySet())
{
Bean<?> serviceBean = new BeanBuilder<Object>(manager)
.beanClass(entry.getKey())
.types(entry.getValue().getAnnotated().getTypeClosure())
.beanLifecycle(new ContextualLifecycle<Object>()
{
@Override
public void destroy(Bean<Object> bean, Object instance, CreationalContext<Object> creationalContext)
{
System.out.println();
}

@Override
public Object create(Bean<Object> bean, CreationalContext<Object> creationalContext)
{
return produceRemoteService(
BeanManagerUtils.getContextualInstance(manager, AddonRegistry.class), entry.getValue());
}

private Object produceRemoteService(AddonRegistry registry, InjectionPoint ip)
{
Member member = ip.getMember();
Class<?> type = null;
if (member instanceof Method)
{
type = ((Method) member).getReturnType();
}
else if (member instanceof Field)
{
type = ((Field) member).getType();
}
else
{
throw new ContainerException(
"Cannot handle producer for non-Field and non-Method member type: " + member);
}

return Enhancer.create((Class<?>) type, new RemoteServiceProxyBeanCallback(registry, type, ip));
}
})
.qualifiers(SERVICE_LITERAL)
.create();

event.addBean(serviceBean);
}
}

/*
* Helpers
*/
public Set<Class<?>> getServices()
{
return services;
return services.keySet();
}

private boolean isClassLocal(Class<?> reference, Class<?> type)
Expand All @@ -134,68 +181,4 @@ private Remote getRemote(Annotated annotated)
Class<?> clazz = Types.toClass(annotated.getBaseType());
return Annotations.getAnnotation(clazz, Remote.class);
}

private class RemoteAnnotatedType<R> implements AnnotatedType<R>
{
private AnnotatedType<R> wrapped;

public RemoteAnnotatedType(AnnotatedType<R> wrapped)
{
this.wrapped = wrapped;
}

@Override
public Type getBaseType()
{
return wrapped.getBaseType();
}

@Override
public Set<Type> getTypeClosure()
{
return wrapped.getTypeClosure();
}

@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationType)
{
return wrapped.getAnnotation(annotationType);
}

@Override
public Set<Annotation> getAnnotations()
{
return wrapped.getAnnotations();
}

@Override
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
{
return wrapped.isAnnotationPresent(annotationType);
}

@Override
public Class<R> getJavaClass()
{
return (Class<R>) wrapped.getJavaClass();
}

@Override
public Set<AnnotatedConstructor<R>> getConstructors()
{
return wrapped.getConstructors();
}

@Override
public Set<AnnotatedMethod<? super R>> getMethods()
{
return wrapped.getMethods();
}

@Override
public Set<AnnotatedField<? super R>> getFields()
{
return wrapped.getFields();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.jboss.forge.container.impl;

import java.lang.annotation.Annotation;

final class ServiceLiteral implements Service
{
@Override
public Class<? extends Annotation> annotationType()
{
return Service.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import org.jboss.forge.container.exception.ContainerException;
import org.jboss.forge.container.services.RemoteInstance;
import org.jboss.forge.container.services.RemoteInstanceImpl;
import org.jboss.forge.container.services.ServiceRegistry;
import org.jboss.forge.container.util.Sets;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,36 +452,6 @@ else if (!file.isDirectory())
systemPaths.add("org/codehaus/plexus/util/reflection");
systemPaths.add("org/codehaus/plexus/util/xml");
systemPaths.add("org/codehaus/plexus/util/xml/pull");
systemPaths.add("org/eclipse/jetty/continuation");
systemPaths.add("org/eclipse/jetty/http");
systemPaths.add("org/eclipse/jetty/http/gzip");
systemPaths.add("org/eclipse/jetty/http/ssl");
systemPaths.add("org/eclipse/jetty/io");
systemPaths.add("org/eclipse/jetty/io/bio");
systemPaths.add("org/eclipse/jetty/io/nio");
systemPaths.add("org/eclipse/jetty/security");
systemPaths.add("org/eclipse/jetty/security/authentication");
systemPaths.add("org/eclipse/jetty/server");
systemPaths.add("org/eclipse/jetty/server/bio");
systemPaths.add("org/eclipse/jetty/server/handler");
systemPaths.add("org/eclipse/jetty/server/handler/jmx");
systemPaths.add("org/eclipse/jetty/server/jmx");
systemPaths.add("org/eclipse/jetty/server/nio");
systemPaths.add("org/eclipse/jetty/server/session");
systemPaths.add("org/eclipse/jetty/server/session/jmx");
systemPaths.add("org/eclipse/jetty/server/ssl");
systemPaths.add("org/eclipse/jetty/servlet");
systemPaths.add("org/eclipse/jetty/servlet/jmx");
systemPaths.add("org/eclipse/jetty/servlet/listener");
systemPaths.add("org/eclipse/jetty/util");
systemPaths.add("org/eclipse/jetty/util/ajax");
systemPaths.add("org/eclipse/jetty/util/component");
systemPaths.add("org/eclipse/jetty/util/log");
systemPaths.add("org/eclipse/jetty/util/resource");
systemPaths.add("org/eclipse/jetty/util/security");
systemPaths.add("org/eclipse/jetty/util/ssl");
systemPaths.add("org/eclipse/jetty/util/statistic");
systemPaths.add("org/eclipse/jetty/util/thread");
systemPaths.add("org/hamcrest");
systemPaths.add("org/hamcrest/core");
systemPaths.add("org/hamcrest/internal");
Expand Down Expand Up @@ -568,6 +538,7 @@ else if (!file.isDirectory())
systemPaths.add("org/jboss/forge/container/modules/providers");
systemPaths.add("org/jboss/forge/container/services");
systemPaths.add("org/jboss/forge/container/util");
systemPaths.add("org/jboss/forge/container/util/cdi");
systemPaths.add("org/jboss/forge/parser");
systemPaths.add("org/jboss/forge/parser/xml");
systemPaths.add("org/jboss/forge/parser/xml/query");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jboss.forge.container.impl;
package org.jboss.forge.container.services;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;
Expand Down
Loading

0 comments on commit 5686a33

Please sign in to comment.