Package org.apache.myfaces.portlet.faces.el

Source Code of org.apache.myfaces.portlet.faces.el.PortletELResolver

/* 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.myfaces.portlet.faces.el;

import java.beans.FeatureDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

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

import javax.portlet.PortletConfig;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.faces.Bridge;
import javax.portlet.faces.BridgeUtil;
import javax.portlet.faces.preference.Preference;

import org.apache.myfaces.portlet.faces.util.map.PortletSessionMap;
import org.apache.myfaces.portlet.faces.preference.PreferenceImpl;

public class PortletELResolver extends ELResolver
  {

    // All are recognized/processed when its a Faces EL resolve
    // While only those that are marked are recognized/processed when its a JSP EL resolve
    public static enum BRIDGE_IMPLICT_OBJECTS_ENUM
    {
      portletConfig,
     
      // request releated
      renderRequest,
      renderResponse,
     
      // session related
      httpSessionScope, // also supported in a JSP EL resolve
      portletSession, // also supported in a JSF EL resolve
      portletSessionScope, // also supported in a JSF EL resolve
     
      // preference related
      mutablePortletPreferencesValues,  // also supported in a JSP EL resolve
      portletPreferences, // also supported in a JSF EL resolve
      portletPreferencesValues // also supported in a JSF EL resolve
    }
   

    public PortletELResolver()
    {
    }

    @Override
    public Object getValue(ELContext context, Object base, Object property) throws ELException
    {
      // variable resolution is a special case of property resolution
      // where the base is null.
      if (property == null)
      {
        throw new PropertyNotFoundException("Null property");
      }
     
      // only process if running in a portlet request
      if (!BridgeUtil.isPortletRequest() || base != null)
      {
        return null;
      }
     
      // Recognize whether we are resolving in a Faces context or JSP context
      // as the resolution differs.  I.e. in the JSP context we defer to
      // its implicit object resolver to resolve the <portlet:defineObjects> objects.
      PortletELContextImpl portletELContext = (PortletELContextImpl) context.getContext(PortletELContextImpl.class);
     
      if (portletELContext == null)
      {
        return null;
      }
     
      return getResolvedValue(context, portletELContext, base, property, portletELContext.isFacesResolved());
    }
   
    private Object getResolvedValue(ELContext context,
                                         PortletELContextImpl bridgeContext,
                                         Object base,
                                         Object property,
                                         boolean isFacesResolved)
    throws ELException
    {
   
      FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
      ExternalContext extCtx = facesContext.getExternalContext();
     
      if (property instanceof String)
      {
        try
        {
          switch (Enum.valueOf(BRIDGE_IMPLICT_OBJECTS_ENUM.class, (String) property))
          {
            case portletConfig:
              // only resolved in a Faces expression
              if (isFacesResolved)
              {
                PortletConfig config = bridgeContext.getPortletConfig();
                if (config != null)
                {
                  context.setPropertyResolved(true);
                  return config;
                } else
                {
                  throw new ELException("EL Resolve failed: can't resolve portletConfig because its not set on this Faces EL Resolver.");
                }
              }
              else
              {
                return null;
              }
            case renderRequest:
              // only resolved in a Faces expression
              if (isFacesResolved)
              {
                if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.RENDER_PHASE)
                {
                  context.setPropertyResolved(true);
                  return extCtx.getRequest();
                } else
                {
                  throw new ELException("EL Resolve failed: can't resolve renderRequest in a non-render request");
                }
              }
              else
              {
                return null;
              }
            case renderResponse:
              // only resolved in a Faces expression
              if (isFacesResolved)
              {
                if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.RENDER_PHASE)
                {
                  context.setPropertyResolved(true);
                  return extCtx.getResponse();
                } else
                {
                  throw new ELException("EL Resolve failed: can't resolve renderResponse in a non-render request");
                }
              }
              else
              {
                return null;
              }
            case httpSessionScope:
              context.setPropertyResolved(true);
              return getHttpSessionMap(extCtx, bridgeContext);
            case portletSession:
              context.setPropertyResolved(true);
              return extCtx.getSession(false);
            case portletSessionScope:
              context.setPropertyResolved(true);
              return extCtx.getSessionMap();
            case mutablePortletPreferencesValues:
              context.setPropertyResolved(true);
              return getMutablePortletPreferencesValues(extCtx, bridgeContext);

            case portletPreferences:
              context.setPropertyResolved(true);
              return ((PortletRequest) extCtx.getRequest()).getPreferences();
            case portletPreferencesValues:
              context.setPropertyResolved(true);
              return ((PortletRequest) extCtx.getRequest()).getPreferences().getMap();
            default:

          }
        } catch (IllegalArgumentException e)
        {
          if (!isFacesResolved)
          {
            // Faces defers to the implicit object resolver when evaluating
            // in a JSP context.  Alas, this means that Faces doesn't resolve
            // session scoped ManagedBeans in a JSP context if the managed bean
            // is already created rather it defers to the JSP Implicit resolver
            // which accesses the http session not the protlet session.  I.e.
            // though the managed bean resolver sees that the session scoped bean
            // exists it can't be retrieved because its in the portlet session
            // not the http session.
            // So its up to us to see if the bean is in the session
            if (extCtx.getSessionMap().containsKey(property))
            {
              context.setPropertyResolved(true);
              return extCtx.getSessionMap().get(property);
            }
          }
        }
      }
      return null;
   }

   

    @Override
    public void setValue(ELContext context, Object base, Object property, Object val)
                                                                                     throws ELException
    {
     
      // only process if running in a portlet request
      if (!BridgeUtil.isPortletRequest() || base != null)
      {
        return;
      }


      if (property == null)
      {
        throw new PropertyNotFoundException("Null property");
      }
        
      // As these properties aren't writable in either the Faces or JSP resolver
      // don't distinguish in what context we are running.
      if (property instanceof String)
      {
        try
        {
          // If exception not thrown then we had a hit
          Enum.valueOf(BRIDGE_IMPLICT_OBJECTS_ENUM.class, (String) property);
          throw new PropertyNotWritableException((String) property);
        }
        catch (IllegalArgumentException e)
        {
          ; // do nothing
        }
      }
    }

    @Override
    public boolean isReadOnly(ELContext context, Object base, Object property) throws ELException
    {
      // only process if running in a portlet request
      if (!BridgeUtil.isPortletRequest() || base != null)
      {
        return false;
      }
     
      if (property == null)
      {
        throw new PropertyNotFoundException("Null property");
      }
     
      // As these properties aren't writable in either the Faces or JSP resolver
      // don't distinguish in what context we are running.
      if (property instanceof String)
      {
        try
        {
          // If exception not thrown then we had a hit
          Enum.valueOf(BRIDGE_IMPLICT_OBJECTS_ENUM.class, (String) property);
          context.setPropertyResolved(true);
          return true;
        }
        catch (IllegalArgumentException e)
        {
          return false;
        }
      }

      return false;
    }

    @Override
    public Class<?> getType(ELContext context, Object base, Object property) throws ELException
    {
      if (property == null)
      {
        throw new PropertyNotFoundException("Null property");
      }
     
      // only process if running in a portlet request
      if (!BridgeUtil.isPortletRequest() || base != null)
      {
        return null;
      }

      int index = -1;
      // As these properties aren't writable in either the Faces or JSP resolver
      // don't distinguish in what context we are running.
      if (property instanceof String)
      {
        try
        {
          // If exception not thrown then we had a hit
          Enum.valueOf(BRIDGE_IMPLICT_OBJECTS_ENUM.class, (String) property);
          context.setPropertyResolved(true);
        }
        catch (IllegalArgumentException e)
        {
          ; // do nothing
        }
      }
    
      return null;
    }
   

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base)
    {
      if (base != null)
      {
        return null;
      }
      ArrayList<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>(9);
      list.add(getFeatureDescriptor("httpSessionScope", "httpSessionScope",
                                    "httpSessionScope", false, false, true, Map.class,
                                    Boolean.TRUE));
      list.add(getFeatureDescriptor("mutablePortletPreferences", "mutablePortletPreferences",
                                    "mutablePortletPreferences", false, false, true, Map.class,
                                    Boolean.TRUE));
      list.add(getFeatureDescriptor("portletConfig", "portletConfig", "portletConfig", false, false,
                                    true, PortletConfig.class, Boolean.TRUE));
      list.add(getFeatureDescriptor("portletPreferences", "portletPreferences", "portletPreferences", false, false,
                                    true, PortletPreferences.class, Boolean.TRUE));
      list.add(getFeatureDescriptor("portletPreferencesValues", "portletPreferencesValues", "portletPreferencesValues", false, false,
                                    true, Map.class, Boolean.TRUE));
      list.add(getFeatureDescriptor("portletSession", "portletSession", "portletSession", false, false,
                                    true, PortletSession.class, Boolean.TRUE));
      list.add(getFeatureDescriptor("portletSessionScope", "portletSessionScope",
                                    "portletSessionScope", false, false, true, Map.class,
                                    Boolean.TRUE));
      list.add(getFeatureDescriptor("renderRequest", "renderRequest", "renderRequest", false, false,
                                    true, RenderRequest.class, Boolean.TRUE));
      list.add(getFeatureDescriptor("renderResponse", "renderResponse", "renderResponse", false, false,
                                    true, RenderResponse.class, Boolean.TRUE));
      return list.iterator();

    }

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

    private FeatureDescriptor getFeatureDescriptor(String name, String displayName, String desc,
                                                   boolean expert, boolean hidden, boolean preferred,
                                                   Object type, Boolean designTime)
    {

      FeatureDescriptor fd = new FeatureDescriptor();
      fd.setName(name);
      fd.setDisplayName(displayName);
      fd.setShortDescription(desc);
      fd.setExpert(expert);
      fd.setHidden(hidden);
      fd.setPreferred(preferred);
      fd.setValue(ELResolver.TYPE, type);
      fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, designTime);
      return fd;
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> getPreferencesValueMap(ExternalContext extCtx)
    {
      Map<String, String> m;

      PortletRequest portletRequest = (PortletRequest) extCtx.getRequest();
      Enumeration<String> e = portletRequest.getPreferences().getNames();
     
      if (e.hasMoreElements())
      {
        m = new HashMap<String, String>();
        while (e.hasMoreElements())
        {
          String name = e.nextElement();
          String value = portletRequest.getPreferences().getValue(name, null);
          if (value != null)
          {
            m.put(name, value);
          }
        }
      }
      else
      {
        m = Collections.emptyMap();
      }
     
      return m;
    }
   
    private Map<String, Preference> getPreferenceMap(PortletPreferences prefs)
    {
     
      Map <String, Preference> m;
     
      // construct a Map of Preference objects for each preference
      Enumeration<String> e = prefs.getNames();
     
      if (e.hasMoreElements())
      {
        m = new HashMap<String, Preference>();
        while (e.hasMoreElements())
        {
          String name = e.nextElement();
          m.put(name, new PreferenceImpl(prefs, name));
        }
      }
      else
      {
        m = Collections.emptyMap();
      }
     
      return m;
    }
   
    private Map<String, Object> getHttpSessionMap(ExternalContext extCtx, PortletELContextImpl bridgeContext)
    {

      Map<String, Object> sessionMap = bridgeContext.getHttpSessionMap();
      if (sessionMap == null)
      {
        sessionMap =
            new PortletSessionMap(extCtx.getRequest(), PortletSession.APPLICATION_SCOPE);
        bridgeContext.setHttpSessionMap(sessionMap);
      }
      return sessionMap;
    }
   
    private Map getMutablePortletPreferencesValues(ExternalContext extCtx, PortletELContextImpl bridgeContext)
    {

      Map<String, Preference> preferencesValuesMap =
        bridgeContext.getMutablePortletPreferencesMap();
      if (preferencesValuesMap == null)
      {
        preferencesValuesMap =
            getPreferenceMap(((PortletRequest) extCtx.getRequest()).getPreferences());
        bridgeContext.setMutablePortletPreferencesMap(preferencesValuesMap);
      }
      return preferencesValuesMap;
    }

}
TOP

Related Classes of org.apache.myfaces.portlet.faces.el.PortletELResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.