All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.guicedee.guicedservlets.jsf.GuiceELResolverWrapper Maven / Gradle / Ivy

There is a newer version: 62
Show newest version
package com.guicedee.guicedservlets.jsf;

import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
import com.guicedee.guicedinjection.GuiceContext;
import com.guicedee.logger.LogFactory;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.faces.FacesWrapper;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import java.beans.FeatureDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;

/**
 * A {@link FacesWrapper} implementation that wraps an {@link ELResolver} and
 * provides a mechanism to inject Guice {@link Injector} implementations.
 *
 * @author John Yeary
 * @version 1.0
 */
public class GuiceELResolverWrapper
		extends ELResolver
		implements FacesWrapper
{

	private static final Map, Class> PRIMITIVES_TO_WRAPPERS
			= new ImmutableMap.Builder, Class>()
					  .put(boolean.class, Boolean.class)
					  .put(byte.class, Byte.class)
					  .put(char.class, Character.class)
					  .put(double.class, Double.class)
					  .put(float.class, Float.class)
					  .put(int.class, Integer.class)
					  .put(long.class, Long.class)
					  .put(short.class, Short.class)
					  .put(void.class, Void.class)
					  .build();
	private ELResolver wrapped;

	/**
	 * Default constructor.
	 */
	public GuiceELResolverWrapper()
	{
		//No config required
	}

	/**
	 * Constructor that wraps an {@link ELResolver}.
	 *
	 * @param wrapped
	 * 		The resolver to wrap;
	 */
	public GuiceELResolverWrapper(ELResolver wrapped)
	{
		this.wrapped = wrapped;
	}

	/**
	 * {@inheritDoc}
	 * 

* Note: This implementation checks to see if the property * can be resolved using the wrapped instance. If the property is resolved, * this method will inject the Guice {@link Injector} implementations. */ @Override public Object getValue(ELContext context, Object base, Object property) { Object obj = null; if (base != null) { if (base instanceof Collections || base instanceof Map) { return null; } try { Field f = base.getClass() .getDeclaredField(property.toString()); f.setAccessible(true); obj = f.get(base); if (obj != null) { GuiceContext.inject() .injectMembers(obj); } } catch (IllegalAccessException e) { LogFactory.getLog(GuiceELResolverWrapper.class) .log(Level.FINE, "Could not access field " + property.toString() + " on " + " obj '" + base.getClass() .getCanonicalName() + "'", e); return getWrapped().getValue(context, base, property); } catch (NoSuchFieldException e) { return getWrapped().getValue(context, base, property); } } else { try { obj = GuiceContext.get(Key.get(Object.class, Names.named(property.toString()))); if (obj.getClass() .isAnnotationPresent(FacesConverter.class)) { javax.faces.convert.Converter conv = (Converter) obj; FacesContext fctx = (FacesContext) context.getContext(FacesContext.class); context.setPropertyResolved(true); return conv.getAsObject(fctx, null, null); } } catch (Throwable e) { try { return getWrapped().getValue(context, base, property); } catch (Throwable T) { LogFactory.getLog(GuiceELResolverWrapper.class) .log(Level.WARNING, "Could not locate jsf property " + property.toString() + " using" + " key '" + Key.get(Object.class, Names.named(property.toString())) + "'", e); } return null; } } context.setPropertyResolved(true); return obj; } /** @noinspection JavaReflectionInvocation */ @Override public Object invoke(ELContext context, Object base, Object method, Class[] paramTypes, Object... params) { try { if (paramTypes == null) { if (params != null && params.length > 0) { paramTypes = new Class[params.length]; for (Method declaredMethod : base.getClass() .getDeclaredMethods()) { if (declaredMethod.getName() .equals(method.toString()) && declaredMethod.getParameterTypes().length == params.length) { Class[] parameterTypes = declaredMethod.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { Class parameterType = parameterTypes[i]; Object o = params[i]; if (o == null) { paramTypes[i] = parameterType; continue; } parameterType = wrap(parameterType); if (o.getClass() .equals(parameterType)) { paramTypes[i] = parameterTypes[i]; } } } } } else { paramTypes = new Class[0]; } } Method m = base.getClass() .getMethod(method.toString(), paramTypes); return m.invoke(base, params); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { LogFactory.getLog(GuiceELResolverWrapper.class) .log(Level.FINE, "Could not locate jsf method " + method.toString() + " using" + " " + base.getClass() .getCanonicalName() + "'", e); } return super.invoke(context, base, method, paramTypes, params); } // safe because both Long.class and long.class are of type Class @SuppressWarnings("unchecked") private static Class wrap(Class c) { return c.isPrimitive() ? (Class) PRIMITIVES_TO_WRAPPERS.get(c) : c; } /** * {@inheritDoc} *

* Note: This returns the wrapped implementation.

*/ @Override public Class getType(ELContext context, Object base, Object property) { return getWrapped().getType(context, base, property); } /** * {@inheritDoc} *

* Note: This returns the wrapped implementation.

*/ @Override public void setValue(ELContext context, Object base, Object property, Object value) { getWrapped().setValue(context, base, property, value); } /** * {@inheritDoc} *

* Note: This returns the wrapped implementation.

*/ @Override public boolean isReadOnly(ELContext context, Object base, Object property) { return getWrapped().isReadOnly(context, base, property); } /** * {@inheritDoc} *

* Note: This returns the wrapped implementation.

*/ @Override public Iterator getFeatureDescriptors(ELContext context, Object base) { return getWrapped().getFeatureDescriptors(context, base); } /** * {@inheritDoc} *

* Note: This returns the wrapped implementation.

*/ @Override public Class getCommonPropertyType(ELContext context, Object base) { return getWrapped().getCommonPropertyType(context, base); } /** * {@inheritDoc} */ @Override public ELResolver getWrapped() { return wrapped; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy