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.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
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.ResourceRequest;
import javax.portlet.ResourceResponse;
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
    actionRequest,
    actionResponse,
    eventRequest,
    eventResponse,
    renderRequest,
    renderResponse,
    resourceRequest,
    resourceResponse,
   
    // session related
    httpSessionScope, // also supported in a JSP EL resolve
    portletSession,
    portletSessionScope,
   
    // preference related
    mutablePortletPreferencesValues,  // also supported in a JSP EL resolve
    portletPreferences,
    portletPreferencesValues
  }
 

  public PortletELResolver()
  {
  }

  @Override
  public Object getValue(ELContext context, Object base, Object property) throws ELException
  {   
    // only process if running in a portlet request
    if (!BridgeUtil.isPortletRequest() || base != null)
    {
      return null;
    }
   
    // variable resolution is a special case of property resolution
    // where the base is null.
    if (property == null)
    {
      throw new PropertyNotFoundException("Null property");
    }
   
    // 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;
    }
   
    if (portletELContext.isFacesResolved())
    {
      return getFacesResolvedValue(context, portletELContext, base, property);
    }
    else
    {
      return getJSPResolvedValue(context, portletELContext, base, property);
    }
  }
 
  private Object getFacesResolvedValue(ELContext context, PortletELContextImpl bridgeContext, Object base, Object property) 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:
            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.");
            }
          case actionRequest:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.ACTION_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getRequest();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve actionRequest in a non-action request");
            }
          case actionResponse:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.ACTION_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getResponse();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve actionResponse in a non-action request");
            }
          case eventRequest:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.EVENT_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getRequest();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve eventRequest in a non-event request");
            }
          case eventResponse:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.EVENT_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getResponse();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve eventResponse in a non-event request");
            }
          case renderRequest:
            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");
            }
          case renderResponse:
            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");
            }
          case resourceRequest:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.RESOURCE_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getRequest();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve resourceRequest in a non-resource request");
            }
          case resourceResponse:
            if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.RESOURCE_PHASE)
            {
              context.setPropertyResolved(true);
              return extCtx.getResponse();
            } else
            {
              throw new ELException("EL Resolve failed: can't resolve resourceResponse in a non-resource request");
            }
          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:
            return null;
        }
      } catch (IllegalArgumentException e)
      {
        return null;
      }
    }
    else
    {
      return null;
    }
}

 
  private Object getJSPResolvedValue(ELContext context, PortletELContextImpl bridgeContext, Object base, Object property) 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 httpSessionScope:
            context.setPropertyResolved(true);
            return getHttpSessionMap(extCtx, bridgeContext);

          case mutablePortletPreferencesValues:
            context.setPropertyResolved(true);
            return getMutablePortletPreferencesValues(extCtx, bridgeContext);
          default:
            return null;
        }
      } catch (IllegalArgumentException e)
      {
        // 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);
        }
        else
        {
          return null;
        }
      }
    } else
    {
      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
  {  
    // only process if running in a portlet request
    if (!BridgeUtil.isPortletRequest() || base != null)
    {
      return null;
    }
   
    if (property == null)
    {
      throw new PropertyNotFoundException("Null property");
    }

    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>(15);
    list.add(getFeatureDescriptor("actionRequest", "actionRequest", "actionRequest", false, false,
                                  true, ActionRequest.class, Boolean.TRUE));
    list.add(getFeatureDescriptor("actionResponse", "actionResponse", "actionResponse", false, false,
                                  true, ActionResponse.class, Boolean.TRUE));
    list.add(getFeatureDescriptor("eventRequest", "eventRequest", "eventRequest", false, false,
                                  true, EventRequest.class, Boolean.TRUE));
    list.add(getFeatureDescriptor("eventResponse", "eventResponse", "eventResponse", false, false,
                                  true, EventResponse.class, Boolean.TRUE));
    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));
    list.add(getFeatureDescriptor("resourceRequest", "resourceRequest", "resourceRequest", false, false,
                                  true, ResourceRequest.class, Boolean.TRUE));
    list.add(getFeatureDescriptor("resourceResponse", "resourceResponse", "resourceResponse", false, false,
                                  true, ResourceResponse.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.