From 408a4ab3a96b9de59b77ebf122b74bee76f5d47c Mon Sep 17 00:00:00 2001 From: Cleverson Sacramento Date: Fri, 14 Sep 2012 11:13:24 -0300 Subject: [PATCH] Carregamento das classes de configuração via proxy utilizando Javassist --- impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ConfigurationBootstrap.java | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ProxyBean.java | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/StartupBootstrap.java | 8 -------- 3 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ProxyBean.java diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ConfigurationBootstrap.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ConfigurationBootstrap.java index 911a6c2..3328aa9 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ConfigurationBootstrap.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ConfigurationBootstrap.java @@ -40,12 +40,20 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.CtNewMethod; + import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.ProcessAnnotatedType; import br.gov.frameworkdemoiselle.configuration.Configuration; +import br.gov.frameworkdemoiselle.internal.configuration.ConfigurationLoader; public class ConfigurationBootstrap implements Extension { @@ -55,11 +63,50 @@ public class ConfigurationBootstrap implements Extension { final AnnotatedType annotatedType = event.getAnnotatedType(); if (annotatedType.getJavaClass().isAnnotationPresent(Configuration.class)) { - getCache().add(annotatedType.getJavaClass()); + cache.add(annotatedType.getJavaClass()); + event.veto(); + } + } + + public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) throws Exception { + Class proxy; + + for (Class config : cache) { + proxy = createProxy(config); + abd.addBean(new ProxyBean((Class) proxy, beanManager)); } } - public List> getCache() { - return cache; + @SuppressWarnings("unchecked") + private Class createProxy(Class type) throws Exception { + String superClassName = type.getCanonicalName(); + String chieldClassName = superClassName + "__DemoiselleProxy"; + ClassPool pool = ClassPool.getDefault(); + + CtClass ctChieldClass = pool.makeClass(chieldClassName); + CtClass ctSuperClass = pool.get(superClassName); + ctChieldClass.setSuperclass(ctSuperClass); + + StringBuffer buffer = new StringBuffer(); + buffer.append("new "); + buffer.append(ConfigurationLoader.class.getCanonicalName()); + buffer.append("().load(this);"); + + CtMethod ctChieldMethod; + for (CtMethod ctSuperMethod : ctSuperClass.getDeclaredMethods()) { + ctChieldMethod = CtNewMethod.delegator(ctSuperMethod, ctChieldClass); + ctChieldMethod.insertBefore(buffer.toString()); + + ctChieldClass.addMethod(ctChieldMethod); + } + + // CtConstructor ctChieldDefaultConstructor = CtNewConstructor.defaultConstructor(ctChieldClass); + // ctChieldClass.addConstructor(ctChieldDefaultConstructor); + // + // for (CtConstructor ctConstructor : ctChieldClass.getConstructors()) { + // ctConstructor.insertBefore(buffer.toString()); + // } + + return ctChieldClass.toClass(); } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ProxyBean.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ProxyBean.java new file mode 100644 index 0000000..2dea41d --- /dev/null +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/ProxyBean.java @@ -0,0 +1,130 @@ +/* + * Demoiselle Framework + * Copyright (C) 2010 SERPRO + * ---------------------------------------------------------------------------- + * This file is part of Demoiselle Framework. + * + * Demoiselle Framework is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License version 3 + * as published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 + * along with this program; if not, see + * or write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + * ---------------------------------------------------------------------------- + * Este arquivo é parte do Framework Demoiselle. + * + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação + * do Software Livre (FSF). + * + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português + * para maiores detalhes. + * + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título + * "LICENCA.txt", junto com esse programa. Se não, acesse + * ou escreva para a Fundação do Software Livre (FSF) Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. + */ +package br.gov.frameworkdemoiselle.internal.bootstrap; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.InjectionTarget; +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Singleton; + +/** + * @see http://docs.jboss.org/weld/reference/latest/en-US/html_single/#d0e5035 + */ +public class ProxyBean implements Bean { + + private Class proxy; + + private InjectionTarget injectionTarget; + + public ProxyBean(Class proxy, BeanManager beanManager) { + AnnotatedType annotatedType = beanManager.createAnnotatedType(proxy); + + this.injectionTarget = beanManager.createInjectionTarget(annotatedType); + this.proxy = proxy; + } + + public Object create(CreationalContext creationalContext) { + Object instance = injectionTarget.produce(creationalContext); + injectionTarget.inject(instance, creationalContext); + injectionTarget.postConstruct(instance); + return instance; + } + + public void destroy(Object instance, CreationalContext creationalContext) { + injectionTarget.preDestroy(instance); + injectionTarget.dispose(instance); + creationalContext.release(); + } + + public Set getTypes() { + Set types = new HashSet(); + types.add(proxy.getSuperclass()); + types.add(Object.class); + return types; + } + + @SuppressWarnings("serial") + public Set getQualifiers() { + Set qualifiers = new HashSet(); + qualifiers.add(new AnnotationLiteral() { + }); + qualifiers.add(new AnnotationLiteral() { + }); + + return qualifiers; + } + + public Class getScope() { + return Singleton.class; + } + + public String getName() { + return null; + } + + public Set> getStereotypes() { + return Collections.emptySet(); + } + + public Class getBeanClass() { + return proxy; + } + + public boolean isAlternative() { + return false; + } + + public boolean isNullable() { + return false; + } + + public Set getInjectionPoints() { + return injectionTarget.getInjectionPoints(); + } +} diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/StartupBootstrap.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/StartupBootstrap.java index 9f84125..410d25f 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/StartupBootstrap.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/StartupBootstrap.java @@ -40,11 +40,9 @@ import javax.enterprise.event.Observes; import org.slf4j.Logger; -import br.gov.frameworkdemoiselle.internal.configuration.ConfigurationLoader; import br.gov.frameworkdemoiselle.internal.producer.LoggerProducer; import br.gov.frameworkdemoiselle.lifecycle.AfterStartupProccess; import br.gov.frameworkdemoiselle.lifecycle.Startup; -import br.gov.frameworkdemoiselle.util.Beans; /** * This class is the bootstrap to execute the processes at load time. @@ -63,12 +61,6 @@ public class StartupBootstrap extends AbstractLifecycleBootstrap { } public void startup(@Observes AfterStartupProccess event) { - ConfigurationLoader loader = Beans.getReference(ConfigurationLoader.class); - ConfigurationBootstrap bootstrap = Beans.getReference(ConfigurationBootstrap.class); - for (Class clazz: bootstrap.getCache()) { - Object object = Beans.getReference(clazz); - loader.load(object); - } proccessEvent(); } } -- libgit2 0.21.2