webtier@glassfish.java.net

[Fwd: JSF 2.0 PR ScopedAttributeELResolver/FacesContext/PhaseListener Issue?]

From: Lincoln Baxter, III <lincolnbaxter_at_gmail.com>
Date: Thu, 08 Jan 2009 22:31:20 -0500

This seems to at least make request/session/application scoped variables
accessible.
See changes below. Sorry for pasting it in. But

-----------------------------------------------------------------------------------------------------------------

package com.sun.faces.el;

import java.beans.FeatureDescriptor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.PropertyNotFoundException;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import com.sun.faces.util.MessageUtils;
import com.sun.faces.util.Util;

public class ScopedAttributeELResolver extends ELResolver
{

    public ScopedAttributeELResolver()
    {}

    @Override
    public Object getValue(final ELContext context, final Object base,
final Object property) throws ELException
    {
        if (base != null)
        {
            return null;
        }
        if (property == null)
        {
            String message =
MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID,
                    "base and property"); // ?????
            throw new PropertyNotFoundException(message);
        }
        context.setPropertyResolved(true);
        String attribute = (String) property;
        FacesContext facesContext = (FacesContext)
context.getContext(FacesContext.class);
        ExternalContext ec = facesContext.getExternalContext();
        Object result;
        if (null == (result = ec.getRequestMap().get(attribute)))
        {
            if (null == (result = ec.getSessionMap().get(attribute)))
            {
                UIViewRoot viewRoot = facesContext.getViewRoot();
                if (null != viewRoot)
                {
                    Map<String, Object> viewMap =
viewRoot.getViewMap(false);
                    if (null == (result = ((viewMap != null) ?
viewMap.get(attribute) : null)))
                    {
                        result = ec.getApplicationMap().get(attribute);
                    }
                }
            }
        }

        return result;
    }

    @Override
    public Class<?> getType(final ELContext context, final Object base,
final Object property) throws ELException
    {
        if (base != null)
        {
            return null;
        }
        if (property == null)
        {
            String message =
MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID,
                    "base and property"); // ?????
            throw new PropertyNotFoundException(message);
        }

        context.setPropertyResolved(true);
        return Object.class;
    }

    @Override
    public void setValue(final ELContext context, final Object base,
final Object property, final Object val)
            throws ELException
    {
        if (base != null)
        {
            return;
        }
        if (property == null)
        {
            String message =
MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID,
                    "base and property"); // ?????
            throw new PropertyNotFoundException(message);
        }

        context.setPropertyResolved(true);

        String attribute = (String) property;
        FacesContext facesContext = (FacesContext)
context.getContext(FacesContext.class);
        ExternalContext ec = facesContext.getExternalContext();
        if ((ec.getRequestMap().get(attribute)) != null)
        {
            ec.getRequestMap().put(attribute, val);
        }
        else if ((ec.getSessionMap().get(attribute)) != null)
        {
            ec.getSessionMap().put(attribute, val);
        }
        else if ((ec.getApplicationMap().get(attribute)) != null)
        {
            ec.getApplicationMap().put(attribute, val);
        }
        else if ((null != facesContext.getViewRoot()) &&
(facesContext.getViewRoot().getViewMap().get(attribute)) != null)
        {
            facesContext.getViewRoot().getViewMap().put(attribute, val);
        }
        else
        {
            // if the property doesn't exist in any of the scopes, put
it in
            // request scope.
            ec.getRequestMap().put(attribute, val);
        }

    }

    @Override
    public boolean isReadOnly(final ELContext context, final Object
base, final Object property) throws ELException
    {
        if (base != null)
        {
            return false;
        }
        if (property == null)
        {
            String message =
MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID,
                    "base and property"); // ?????
            throw new PropertyNotFoundException(message);
        }
        context.setPropertyResolved(true);
        return false;
    }

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(final
ELContext context, final Object base)
    {

        ArrayList<FeatureDescriptor> list = new
ArrayList<FeatureDescriptor>();

        FacesContext facesContext = (FacesContext)
context.getContext(FacesContext.class);
        ExternalContext ec = facesContext.getExternalContext();

        // add attributes in request scope.
        Set<Entry<String, Object>> attrs =
ec.getRequestMap().entrySet();
        for (Entry<String, Object> entry : attrs)
        {
            String attrName = entry.getKey();
            Object attrValue = entry.getValue();
            list.add(Util.getFeatureDescriptor(attrName, attrName,
"request scope attribute", false, false, true,
                    attrValue.getClass(), Boolean.TRUE));
        }

        // add attributes in view scope.
        Map<String, Object> viewMap =
facesContext.getViewRoot().getViewMap(false);
        if ((viewMap != null) && (viewMap.size() != 0))
        {
            attrs = facesContext.getViewRoot().getViewMap().entrySet();
            for (Entry<String, Object> entry : attrs)
            {
                String attrName = entry.getKey();
                Object attrValue = entry.getValue();
                list.add(Util.getFeatureDescriptor(attrName, attrName,
"view scope attribute", false, false, true,
                        attrValue.getClass(), Boolean.TRUE));
            }
        }

        // add attributes in session scope.
        attrs = ec.getSessionMap().entrySet();
        for (Entry<String, Object> entry : attrs)
        {
            String attrName = entry.getKey();
            Object attrValue = entry.getValue();
            list.add(Util.getFeatureDescriptor(attrName, attrName,
"session scope attribute", false, false, true,
                    attrValue.getClass(), Boolean.TRUE));
        }

        // add attributes in application scope.
        attrs = ec.getApplicationMap().entrySet();
        for (Entry<String, Object> entry : attrs)
        {
            String attrName = entry.getKey();
            Object attrValue = entry.getValue();
            list.add(Util.getFeatureDescriptor(attrName, attrName,
"application scope attribute", false, false, true,
                    attrValue.getClass(), Boolean.TRUE));
        }

        return list.iterator();
    }

    @Override
    public Class<?> getCommonPropertyType(final ELContext context, final
Object base)
    {
        if (base != null)
        {
            return null;
        }
        return Object.class;
    }

}



-------- Forwarded Message --------
From: Lincoln Baxter, III <lincolnbaxter_at_gmail.com>
Reply-to: lincolnbaxter_at_gmail.com
To: webtier_at_glassfish.dev.java.net
Subject: JSF 2.0 PR ScopedAttributeELResolver/FacesContext/PhaseListener
Issue?
Date: Thu, 08 Jan 2009 22:00:25 -0500


Hey Guys,

So I am doing some work in Phase Listeners, but before the RESTORE_VIEW
phase. I am attempting to access EL values, but since the
FacesContext.getViewRoot() returns null at this point, ScopedAttributeELResolver
bombs at line 80 when attempting to retrieve the viewMap() and I get a NullPointerException.

Is FacesContext supposed to have a ViewRoot before the RESTORE_VIEW
phase? It seems like it should probably not crash at least, unless you
attempt to access the ViewScope attributes.

This didn't happen in 1.2, which I can deduce is because 1.2 did not
have the ViewScope. I'm trying to patch it but having some issues with
my build path in wonderful eclipse. I'll send you what I come up with
if you're interested.

Thoughts?

Thanks,
Lincoln