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

org.picocontainer.web.jsf.PicoVariableResolver Maven / Gradle / Ivy

There is a newer version: 2.5.1
Show newest version
/*******************************************************************************
 * Copyright (C) PicoContainer Organization. All rights reserved. 
 * ---------------------------------------------------------------------------
 * The software in this package is published under the terms of the BSD style
 * license a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 ******************************************************************************/
package org.picocontainer.web.jsf;

import java.util.Map;

import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.VariableResolver;

import org.picocontainer.PicoContainer;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.web.PicoServletContainerFilter;

/**
 * This is a variable resolver implementation for Java ServerFaces.
 * 

Installation

*

* Add install this variable resolver by adding setting the application's * variable resolver to * org.picocontainer.web.jsf.NanoWarDelegatingVariableResolver. An * example follows: *

*
* *
 *   <faces-config>
 *      <application>
 *          <strong>
 *          <variable-resolver>
 *              org.picocontainer.web.jsf.NanoWarDelegatingVariableResolver
 *          </variable-resolver>
 *          </strong>
 *      </application>
 *      ....
 *   </faces-config>
 * 
* *
*

Usage

*

Part 1 - Write your Constructor Dependency Injection (CDI) - based * backing bean:

*

* Even though you are writing a backing bean, you can utilize PicoContainers * CDI capabilities to the fullest. Example: *

* *
 *    //Imports and variables...
 *    
 *    public ListCheeseController(<strong>CheeseService service</strong>) {
 *       this.service = service;       
 *    }
 *    
 *    //The rest of the class.
 * 
* *

Part 2 - Set up your NanoWAR services.

*

* (This assumes you have installed NanoWAR properly. Please see the NanoWAR * documentation for specific instructions) *

*

* You need to name your services with the name you will be giving your * Backing Bean. Example: * *

 *    pico = builder.container(parent: parent) {
 *        if(assemblyScope instanceof javax.servlet.ServletContext) {
 *          // Application Services would go here.
 *        } else if (assemblyScope instanceof javax.servlet.ServletRequest) {
 *            <strong>addComponent(key: 'cheeseBean', class: 'org.picocontainer.web.samples.jsf.ListCheeseController')</strong>
 *        }
 *    }
 * 
* *

Part 3 - Set up your managed beans for JSF

*

* Set the managed bean names in your faces-config to equal the names * given to the backing beans in the nanowar composition script. Example: *

* *
 *    <managed-bean>
 *        <description>CDI Injected Bean</description>
 *        <strong><managed-bean-name>cheeseBean</managed-bean-name></strong>
 *        <managed-bean-class>
 *            org.picocontainer.web.samples.jsf.CheeseController
 *        </managed-bean-class>
 *        <managed-bean-scope>request</managed-bean-scope>
 *    </managed-bean>
 * 
* *

* Notice how the same names were used in the faces-config as in the * nanowar configuration. When the JSF page asks for the bean named * 'addCheeseBean', the Nano variable resolver will take that name and check * nanocontainer for an object of that instance. If it finds one, it will send * it back to the page. *

* Note: *

* This class currently has only been tested using MyFaces. There are reports * that this technique doesn't work on all reference implementation versions. We * welcome success or failure feedback! *

* * @author Michael Rimov */ public class PicoVariableResolver extends VariableResolver { public static class ServletFilter extends PicoServletContainerFilter { private static ThreadLocal currentRequestContainer = new ThreadLocal(); private static ThreadLocal currentSessionContainer = new ThreadLocal(); private static ThreadLocal currentAppContainer = new ThreadLocal(); protected void setAppContainer(MutablePicoContainer container) { currentAppContainer.set(container); } protected void setRequestContainer(MutablePicoContainer container) { currentRequestContainer.set(container); } protected void setSessionContainer(MutablePicoContainer container) { currentSessionContainer.set(container); } protected static MutablePicoContainer getRequestContainerForThread() { return currentRequestContainer.get(); } protected static MutablePicoContainer getSessionContainerForThread() { return currentSessionContainer.get(); } protected static MutablePicoContainer getApplicationContainerForThread() { return currentAppContainer.get(); } } /** * The nested variable resolver. */ private VariableResolver nested; /** * Decorated Variable resolver. * * @param decorated */ public PicoVariableResolver(VariableResolver decorated) { super(); if (decorated == null) { throw new NullPointerException("decorated"); } nested = decorated; } /** * Retrieve the delegated value. * * @return the wrapped variable resolver. */ protected VariableResolver getNested() { return nested; } /** * {@inheritDoc} * * @param facesContext * @param name * @return the resulting object, either resolved through NanoWAR, or passed * onto the delegate resolver. * @throws EvaluationException * @see javax.faces.el.VariableResolver#resolveVariable(javax.faces.context.FacesContext, * java.lang.String) */ public Object resolveVariable(FacesContext facesContext, String name) { PicoContainer nano = getPicoContainer(facesContext); Object result = nano.getComponent(name); if (result == null) { return nested.resolveVariable(facesContext, name); } return result; } /** * Tries to locate the nanocontainer first at request level, and then if it * doesn't find it there. (Filter might not be installed), it tries * Application level. If that fails it throws an exception since you * wouldn't expect the NanoWarDelegatingVariableResolver * * @param facesContext * @return NanoContainer instance. * @throws EvaluationException if it cannot find a NanoWAR instance. */ protected PicoContainer getPicoContainer(FacesContext facesContext) { Map requestAttributeMap = facesContext.getExternalContext().getRequestMap(); PicoContainer container = null; // First check request map. if (requestAttributeMap != null) { container = ServletFilter.getRequestContainerForThread(); } if (requestAttributeMap == null || container == null) { // If that fails, check session for container. Map sessionMap = facesContext.getExternalContext().getSessionMap(); if (sessionMap != null) { // If there is a session. container = ServletFilter.getSessionContainerForThread(); } if (sessionMap == null || container == null) { // If that fails, check for App level container. container = ServletFilter.getApplicationContainerForThread(); if (container == null) { // If that fails... Fail. throw new EvaluationException( "The NanoWar delegating variable resolver is installed, however no NanoWar " + "container was found in the request or application scope."); } } } return container; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy