You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2014/06/30 15:00:26 UTC
[1/2] git commit: DELTASPIKE-650 optional proxies for converters and
validators with properties
Repository: deltaspike
Updated Branches:
refs/heads/master fe8f62401 -> 0584be0cf
DELTASPIKE-650 optional proxies for converters and validators with properties
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/a411ec71
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/a411ec71
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/a411ec71
Branch: refs/heads/master
Commit: a411ec7161fff842dc261969692fd10abc99ad57
Parents: fe8f624
Author: gpetracek <gp...@apache.org>
Authored: Mon Jun 30 14:48:43 2014 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Mon Jun 30 14:48:43 2014 +0200
----------------------------------------------------------------------
.../InjectionAwareApplicationWrapper.java | 12 ++
.../proxy/ConverterAndValidatorLifecycle.java | 132 +++++++++++++++
.../ConverterAndValidatorProxyExtension.java | 169 +++++++++++++++++++
.../proxy/ConverterInvocationHandler.java | 43 +++++
.../proxy/DefaultPartialStateHolder.java | 71 ++++++++
.../proxy/DelegatingMethodHandler.java | 45 +++++
.../injection/proxy/MethodHandlerProxy.java | 42 +++++
.../jsf/impl/injection/proxy/ProxyMarker.java | 23 +++
.../proxy/ValidatorInvocationHandler.java | 43 +++++
.../javax.enterprise.inject.spi.Extension | 3 +-
10 files changed, 582 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java
index b18b36a..a229f3d 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java
@@ -18,7 +18,9 @@
*/
package org.apache.deltaspike.jsf.impl.injection;
+import org.apache.deltaspike.core.util.ProxyUtils;
import org.apache.deltaspike.jsf.api.config.JsfModuleConfig;
+import org.apache.deltaspike.jsf.impl.injection.proxy.ProxyMarker;
import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler;
import javax.faces.FacesException;
@@ -77,6 +79,11 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper
{
return defaultResult;
}
+
+ if (result instanceof ProxyMarker || ProxyUtils.isProxiedClass(result.getClass()))
+ {
+ return result;
+ }
else
{
return new ConverterWrapper(result, this.fullStateSavingFallbackEnabled);
@@ -106,6 +113,11 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper
{
return defaultResult;
}
+
+ if (result instanceof ProxyMarker || ProxyUtils.isProxiedClass(result.getClass()))
+ {
+ return result;
+ }
else
{
return new ValidatorWrapper(result, this.fullStateSavingFallbackEnabled);
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java
new file mode 100644
index 0000000..90a3e6e
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ExceptionUtils;
+import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
+import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.faces.component.PartialStateHolder;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class ConverterAndValidatorLifecycle<T, H extends InvocationHandler> implements ContextualLifecycle<T>
+{
+ private final Class<? extends T> generatedProxyClass;
+
+ private final InjectionTarget<T> injectionTargetForGeneratedProxy;
+ private final Class<H> handlerClass;
+
+ ConverterAndValidatorLifecycle(Class<T> originalClass, Class<H> handlerClass, BeanManager beanManager)
+ {
+ this.handlerClass = handlerClass;
+
+ AnnotatedTypeBuilder<T> typeBuilder = new AnnotatedTypeBuilder<T>().readFromType(originalClass);
+ this.injectionTargetForGeneratedProxy = beanManager.createInjectionTarget(typeBuilder.create());
+
+ try
+ {
+ Object proxyFactory = ClassUtils.tryToInstantiateClassForName("javassist.util.proxy.ProxyFactory");
+
+ Method setSuperclassMethod = proxyFactory.getClass().getDeclaredMethod("setSuperclass", Class.class);
+ setSuperclassMethod.invoke(proxyFactory, originalClass);
+
+ List<Class> interfaces = new ArrayList<Class>();
+ Collections.addAll(interfaces, originalClass.getInterfaces());
+ interfaces.add(ProxyMarker.class);
+
+ if (!interfaces.contains(PartialStateHolder.class))
+ {
+ interfaces.add(PartialStateHolder.class);
+ }
+
+ Method method = proxyFactory.getClass().getMethod("setInterfaces", new Class[]{new Class[]{}.getClass()});
+ method.invoke(proxyFactory, new Object[] {interfaces.toArray(new Class[interfaces.size()])});
+
+ Method createClassMethod = proxyFactory.getClass().getDeclaredMethod("createClass");
+
+ this.generatedProxyClass = ((Class<?>) createClassMethod.invoke(proxyFactory)).asSubclass(originalClass);
+ }
+ catch (Exception e)
+ {
+ throw ExceptionUtils.throwAsRuntimeException(e);
+ }
+ }
+
+ public T create(Bean bean, CreationalContext creationalContext)
+ {
+ try
+ {
+ H handlerInstance = ClassUtils.tryToInstantiateClass(this.handlerClass);
+ T instance = createProxyInstance(handlerInstance);
+
+ if (this.injectionTargetForGeneratedProxy != null)
+ {
+ this.injectionTargetForGeneratedProxy.inject(instance, creationalContext);
+ this.injectionTargetForGeneratedProxy.postConstruct(instance);
+ }
+
+ return instance;
+ }
+ catch (Exception e)
+ {
+ ExceptionUtils.throwAsRuntimeException(e);
+ }
+ //can't happen
+ return null;
+ }
+
+ private T createProxyInstance(H handlerInstance) throws Exception
+ {
+ T instance = this.generatedProxyClass.newInstance();
+
+ Class methodHandlerClass = ClassUtils.tryToLoadClassForName("javassist.util.proxy.MethodHandler");
+ Method setHandlerMethod = ClassUtils.tryToLoadClassForName("javassist.util.proxy.ProxyObject")
+ .getDeclaredMethod("setHandler", methodHandlerClass);
+
+
+ MethodHandlerProxy methodHandlerProxy = new MethodHandlerProxy();
+ methodHandlerProxy.setDelegatingMethodHandler(new DelegatingMethodHandler<H>(handlerInstance));
+
+ Object methodHandler = Proxy.newProxyInstance(
+ ClassUtils.getClassLoader(this), new Class[]{methodHandlerClass}, methodHandlerProxy);
+
+ setHandlerMethod.invoke(instance, methodHandler);
+ return instance;
+ }
+
+ public void destroy(Bean<T> bean, T instance, CreationalContext<T> creationalContext)
+ {
+ if (this.injectionTargetForGeneratedProxy != null)
+ {
+ this.injectionTargetForGeneratedProxy.preDestroy(instance);
+ }
+
+ creationalContext.release();
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
new file mode 100644
index 0000000..dff508f
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.bean.BeanBuilder;
+import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.faces.convert.Converter;
+import javax.faces.validator.Validator;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+public class ConverterAndValidatorProxyExtension implements Extension, Deactivatable
+{
+ private static final Logger LOG = Logger.getLogger(ConverterAndValidatorProxyExtension.class.getName());
+
+ private Boolean isActivated = true;
+ private Set<Class<?>> classesToProxy = new HashSet<Class<?>>();
+
+ protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery)
+ {
+ this.isActivated = ClassDeactivationUtils.isActivated(getClass());
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public <X> void findConverterAndValidatorsWhichNeedProxiesForDependencyInjectionSupport(
+ @Observes ProcessAnnotatedType<X> pat)
+ {
+ if (!this.isActivated)
+ {
+ return;
+ }
+
+ Class<X> beanClass = pat.getAnnotatedType().getJavaClass();
+
+ if (!(Converter.class.isAssignableFrom(beanClass) || (Validator.class.isAssignableFrom(beanClass))))
+ {
+ return;
+ }
+
+ //converters/validators without properties for tags, will be handled by the corresponding manual wrapper
+ if (!hasPublicProperty(beanClass))
+ {
+ return;
+ }
+
+ Object proxyFactory = ClassUtils.tryToInstantiateClassForName("javassist.util.proxy.ProxyFactory");
+
+ if (proxyFactory == null)
+ {
+ LOG.warning("To use dependency-injection in converters/validators with properties, " +
+ "you have to add javassist to the application.");
+ return;
+ }
+
+ if (!(Modifier.isFinal(beanClass.getModifiers())))
+ {
+ this.classesToProxy.add(beanClass);
+ pat.veto();
+ }
+ else
+ {
+ LOG.warning("To use dependency-injection in converters/validators with properties, " +
+ "you they aren't allowed to be 'final'.");
+ }
+ }
+
+ protected <X> boolean hasPublicProperty(Class<X> beanClass)
+ {
+ for (Method currentMethod : beanClass.getMethods())
+ {
+ if (currentMethod.getName().startsWith("set") && currentMethod.getName().length() > 3
+ && currentMethod.getParameterTypes().length == 1 &&
+ hasGetterMethod(beanClass, currentMethod.getName().substring(3)))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected boolean hasGetterMethod(Class beanClass, String name)
+ {
+ try
+ {
+ if (beanClass.getMethod("get" + name) != null || beanClass.getMethod("is") + name != null)
+ {
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ return false;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public <X> void createBeans(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+ {
+ if (!this.isActivated)
+ {
+ return;
+ }
+
+ for (Class<?> originalClass : this.classesToProxy)
+ {
+ Bean bean = createBean(originalClass, beanManager);
+
+ if (bean != null)
+ {
+ afterBeanDiscovery.addBean(bean);
+ }
+ }
+
+ this.classesToProxy.clear();
+ }
+
+ protected <T> Bean<T> createBean(Class<T> beanClass, BeanManager beanManager)
+ {
+ Class<? extends InvocationHandler> invocationHandlerClass =
+ Converter.class.isAssignableFrom(beanClass) ?
+ ConverterInvocationHandler.class : ValidatorInvocationHandler.class;
+
+ AnnotatedType<T> annotatedType = new AnnotatedTypeBuilder<T>().readFromType(beanClass).create();
+
+ ConverterAndValidatorLifecycle beanLifecycle =
+ new ConverterAndValidatorLifecycle(beanClass, invocationHandlerClass, beanManager);
+
+ BeanBuilder<T> beanBuilder = new BeanBuilder<T>(beanManager)
+ .readFromType(annotatedType)
+ .passivationCapable(true)
+ .beanLifecycle(beanLifecycle)
+ .addType(ProxyMarker.class);
+
+ return beanBuilder.create();
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java
new file mode 100644
index 0000000..6bf457c
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import javax.faces.component.PartialStateHolder;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+public class ConverterInvocationHandler implements InvocationHandler
+{
+ private DefaultPartialStateHolder defaultPartialStateHolder = new DefaultPartialStateHolder();
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ // if the original class implements PartialStateHolder already, we won't get in here
+ if (PartialStateHolder.class.equals(method.getDeclaringClass()))
+ {
+ return method.invoke(defaultPartialStateHolder, args);
+ }
+ else
+ {
+ //shouldn't happen, because DelegatingMethodHandler delegates all methods to the real implementations
+ return method.invoke(proxy, args);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java
new file mode 100644
index 0000000..70b2e95
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import javax.faces.component.PartialStateHolder;
+import javax.faces.context.FacesContext;
+
+//the converter-/validator proxy needs to implement PartialStateHolder to force a special path of the jsf state handling
+//which forces a call to InjectionAwareApplicationWrapper on the postback.
+//this class provides the default behaviour for the reflection calls,
+//if the original converter-/validator doesn't implement the interface
+public class DefaultPartialStateHolder implements PartialStateHolder
+{
+ private boolean transientValue;
+ private boolean initialStateMarked;
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ return null; //not needed
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ //not needed
+ }
+
+ @Override
+ public boolean isTransient()
+ {
+ return this.transientValue;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ this.transientValue = newTransientValue;
+ }
+
+ public void clearInitialState()
+ {
+ this.initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return this.initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ this.initialStateMarked = true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java
new file mode 100644
index 0000000..4da76ff
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * Handler delegates to implemented methods, if they exist
+ */
+class DelegatingMethodHandler<T extends InvocationHandler>
+{
+ private final T handlerInstance;
+
+ DelegatingMethodHandler(T handlerInstance)
+ {
+ this.handlerInstance = handlerInstance;
+ }
+
+ //Signature given by javassist.util.proxy.MethodHandler#invoke
+ public Object invoke(Object target, Method method, Method proceedMethod, Object[] arguments) throws Throwable
+ {
+ if (proceedMethod != null)
+ {
+ return proceedMethod.invoke(target, arguments);
+ }
+ return this.handlerInstance.invoke(target, method, arguments);
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java
new file mode 100644
index 0000000..0c02a3a
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+//This indirection to create a proxy for javassist.util.proxy.MethodHandler is used as intermediate approach.
+//Further details see comments in PartialBeanLifecycle
+public class MethodHandlerProxy implements InvocationHandler
+{
+ private DelegatingMethodHandler delegatingMethodHandler;
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ //hardcoding the following parameters is ok since MethodHandlerProxy is only used for
+ //javassist.util.proxy.MethodHandler which has one method with those parameters.
+ return delegatingMethodHandler.invoke(args[0], (Method)args[1], (Method)args[2], (Object[])args[3]);
+ }
+
+ void setDelegatingMethodHandler(DelegatingMethodHandler delegatingMethodHandler)
+ {
+ this.delegatingMethodHandler = delegatingMethodHandler;
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java
new file mode 100644
index 0000000..2e1d9d3
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+public interface ProxyMarker
+{
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java
new file mode 100644
index 0000000..3a2db36
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.deltaspike.jsf.impl.injection.proxy;
+
+import javax.faces.component.PartialStateHolder;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+public class ValidatorInvocationHandler implements InvocationHandler
+{
+ private DefaultPartialStateHolder defaultPartialStateHolder = new DefaultPartialStateHolder();
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ // if the original class implements PartialStateHolder already, we won't get in here
+ if (PartialStateHolder.class.equals(method.getDeclaringClass()))
+ {
+ return method.invoke(defaultPartialStateHolder, args);
+ }
+ else
+ {
+ //shouldn't happen, because DelegatingMethodHandler delegates all methods to the real implementations
+ return method.invoke(proxy, args);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a411ec71/deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
index a634c99..8aa9295 100644
--- a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -20,4 +20,5 @@
org.apache.deltaspike.jsf.impl.scope.view.ViewScopedExtension
org.apache.deltaspike.jsf.impl.scope.mapped.MappedJsf2ScopeExtension
-org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension
\ No newline at end of file
+org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension
+org.apache.deltaspike.jsf.impl.injection.proxy.ConverterAndValidatorProxyExtension
\ No newline at end of file
[2/2] git commit: DELTASPIKE-654 veto converters and validators
without injection-points or normal-scope
Posted by gp...@apache.org.
DELTASPIKE-654 veto converters and validators without injection-points or normal-scope
Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/0584be0c
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/0584be0c
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/0584be0c
Branch: refs/heads/master
Commit: 0584be0cf1d55fafcf09163e28d0923aab095b1b
Parents: a411ec7
Author: gpetracek <gp...@apache.org>
Authored: Mon Jun 30 14:51:30 2014 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Mon Jun 30 14:54:25 2014 +0200
----------------------------------------------------------------------
.../ConverterAndValidatorProxyExtension.java | 22 +++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/0584be0c/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
index dff508f..7c6f58a 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java
@@ -34,6 +34,7 @@ import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.faces.convert.Converter;
import javax.faces.validator.Validator;
+import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -55,7 +56,7 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat
@SuppressWarnings("UnusedDeclaration")
public <X> void findConverterAndValidatorsWhichNeedProxiesForDependencyInjectionSupport(
- @Observes ProcessAnnotatedType<X> pat)
+ @Observes ProcessAnnotatedType<X> pat, BeanManager beanManager)
{
if (!this.isActivated)
{
@@ -69,6 +70,14 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat
return;
}
+ Bean<X> bean = new BeanBuilder<X>(beanManager).readFromType(pat.getAnnotatedType()).create();
+ //veto normal converters/validators -> they will get excluded from the special handling later on
+ if (!hasInjectionPoints(bean) && !hasNormalScopeAnnotation(bean, beanManager))
+ {
+ pat.veto();
+ return;
+ }
+
//converters/validators without properties for tags, will be handled by the corresponding manual wrapper
if (!hasPublicProperty(beanClass))
{
@@ -96,6 +105,17 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat
}
}
+ protected <X> boolean hasInjectionPoints(Bean<X> bean)
+ {
+ return !bean.getInjectionPoints().isEmpty();
+ }
+
+ protected <X> boolean hasNormalScopeAnnotation(Bean<X> bean, BeanManager beanManager)
+ {
+ Class<? extends Annotation> scopeAnnotationClass = bean.getScope();
+ return scopeAnnotationClass != null && beanManager.isNormalScope(scopeAnnotationClass);
+ }
+
protected <X> boolean hasPublicProperty(Class<X> beanClass)
{
for (Method currentMethod : beanClass.getMethods())