You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mf...@apache.org on 2009/06/10 22:10:05 UTC

svn commit: r783483 - in /myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces: application/ bridge/ context/ el/ util/

Author: mfreedman
Date: Wed Jun 10 20:10:04 2009
New Revision: 783483

URL: http://svn.apache.org/viewvc?rev=783483&view=rev
Log:
PORTLETBRIDGE-81: JSP writeAfter (buffer) not working.
PORTLETBRIDGE-80: Update EL variable names for portlet 2.0 
PORTLETBRIDGE-79: Process JSP EL differently than JSF_IMPL_TITLE
PORTLETBRIDGE-78: ELResolver returns wrong PortletConfig
PORTLETBRIDGE-77: detect versions for version dependent workarounds.

Added:
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/util/FacesVersionUtil.java
Modified:
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerRenderResponseWrapper.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerResourceResponseWrapper.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELContextImpl.java
    myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java Wed Jun 10 20:10:04 2009
@@ -364,11 +364,23 @@
       context.setResponseWriter(oldWriter);
     }
 
-    MimeResponse wrappedResponse = (MimeResponse) extContext.getRequestMap().get(Bridge.AFTER_VIEW_CONTENT);
-    if (wrappedResponse != null)
+    Object content = extContext.getRequestMap().get(Bridge.AFTER_VIEW_CONTENT);
+    if (content != null)
     {
-      wrappedResponse.flushBuffer();
+      if (content instanceof char[])
+      {
+        mimeResponse.getWriter().write(new String((char[]) content));
+      }
+      else if (content instanceof byte[])
+      {
+        mimeResponse.getWriter().write(new String((byte[]) content));
+      }
+      else
+      {
+        throw new IOException("PortletViewHandlerImpl: invalid" + "AFTER_VIEW_CONTENT buffer type");
+      }
     }
+    mimeResponse.flushBuffer();
   }
   
 
@@ -390,15 +402,20 @@
 
       // replace the response with our wrapper
       //TODO:  need a separate response wrapper for resources
+      PortletViewHandlerResourceResponseWrapper resourceResponseWrapper = null;
+      PortletViewHandlerRenderResponseWrapper renderResponseWrapper = null;
       PortletResponseWrapper wrapped = null;
       if (BridgeUtil.getPortletRequestPhase() == Bridge.PortletPhase.RESOURCE_PHASE)
       {
-        wrapped = new PortletViewHandlerResourceResponseWrapper((ResourceResponse)originalResponse/*, context.getViewRoot().getLocale()*/);
+        resourceResponseWrapper = new PortletViewHandlerResourceResponseWrapper((ResourceResponse)originalResponse/*, context.getViewRoot().getLocale()*/);
+        wrapped =  resourceResponseWrapper; 
       }
       else
       {
-        wrapped = new PortletViewHandlerRenderResponseWrapper((RenderResponse) originalResponse/*, context.getViewRoot().getLocale()*/);
+        renderResponseWrapper = new PortletViewHandlerRenderResponseWrapper((RenderResponse) originalResponse/*, context.getViewRoot().getLocale()*/);
+        wrapped = renderResponseWrapper;
       }
+      
       if (!(wrapped instanceof PortletResponseWrapper))
         throw new IOException();
       
@@ -415,190 +432,28 @@
       // replace the original response
       extContext.setResponse(originalResponse);
 
-      // Put the AFTER_VIEW_CONTENT into request scope
-      // temporarily
-      extContext.getRequestMap().put(
-            Bridge.AFTER_VIEW_CONTENT,
-            wrapped);
+      // Check to see if the portlet 1.0 bridge filter already put the content
+      // into the attribute
 
-  }
-
-  
-/*
-  
-  @Override
-  public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException,
-                                                                       FacesException
-  {
-    // Do nothing when not running in portlet request
-    if (!BridgeUtil.isPortletRequest())
-    {
-      super.renderView(context, viewToRender);
-      return;
-    }
-
-    // If first time -- Get the renderPolicy from the context init parameter 
-    if (mRenderPolicy == null)
-    {
-      PortletContext pCtx = (PortletContext) context.getExternalContext().getContext();
-      String policy = pCtx.getInitParameter(Bridge.RENDER_POLICY);
-      if (policy != null)
+      if (extContext.getRequestMap().get(Bridge.AFTER_VIEW_CONTENT) == null)
       {
-        mRenderPolicy = Bridge.BridgeRenderPolicy.valueOf(policy);
-      }
-      else
-      {
-        mRenderPolicy = Bridge.BridgeRenderPolicy.DEFAULT;
-      }
-    }
-
-    if (mRenderPolicy == Bridge.BridgeRenderPolicy.ALWAYS_DELEGATE)
-    {
-      super.renderView(context, viewToRender);
-      return;
-    }
-    else if (mRenderPolicy == Bridge.BridgeRenderPolicy.DEFAULT)
-    {
-      try
-      {
-        super.renderView(context, viewToRender);
-        return;
-      }
-      catch (Throwable t)
-      {
-        // catch all throws and swallow -- falling through to our own
-        // render
-      }
-    }
-
-    // suppress rendering if "rendered" property on the component is
-    // false
-    if (!viewToRender.isRendered())
-    {
-      return;
-    }
-
-    ExternalContext extContext = context.getExternalContext();
-    MimeResponse mimeResponse = (MimeResponse) extContext.getResponse();
-
-    try
-    {
-
-      // set request attribute indicating we can deal with content
-      // that is supposed to be delayed until after JSF tree is ouput.
-      extContext.getRequestMap().put(Bridge.RENDER_CONTENT_AFTER_VIEW, Boolean.TRUE);
-      // TODO JSF 1.2 - executePageToBuildView() creates
-      // ViewHandlerResponseWrapper
-      // to handle error page and text that exists after the <f:view> tag
-      // among other things which have lots of servlet dependencies -
-      // we're skipping this for now for portlet
-      
-      
-      // Bridge has had to set this attribute so  Faces RI will skip servlet dependent
-      // code when mapping from request paths to viewIds -- however we need to remove it
-      // as it screws up the dispatch
-      extContext.getRequestMap().remove("javax.servlet.include.servlet_path");
-      extContext.dispatch(viewToRender.getViewId());
-      /*
-       * if (executePageToBuildView(context, viewToRender)) { response.flushBuffer(); return; }
-       */
-  
-/*
-    }
-    catch (IOException e)
-    {
-      throw new FacesException(e);
-    }
-    
-    // If a redirect occurred -- merely return
-    // check here to see if a redirect occurred -- if so rerun doFacesRequest
-    // for this new view
-    QueryString redirectParams = (QueryString) context.getExternalContext()
-                      .getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
-    if ((redirectParams != null))
-    {
-      return;
-    }
-
-    // set up the ResponseWriter
-    RenderKitFactory renderFactory = (RenderKitFactory) FactoryFinder
-                                                                     .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
-    RenderKit renderKit = renderFactory.getRenderKit(context, viewToRender.getRenderKitId());
-
-    ResponseWriter oldWriter = context.getResponseWriter();
-    StringBuilderWriter strWriter = new StringBuilderWriter(context, 4096);
-    ResponseWriter newWriter;
-    if (null != oldWriter)
-    {
-      newWriter = oldWriter.cloneWithWriter(strWriter);
-    }
-    else
-    {
-      newWriter = renderKit.createResponseWriter(strWriter, null,
-                                                 mimeResponse.getCharacterEncoding());
-    }
-    context.setResponseWriter(newWriter);
-
-    newWriter.startDocument();
-
-    doRenderView(context, viewToRender);
-
-    newWriter.endDocument();
-
-    // replace markers in the body content and write it to response.
-
-    ResponseWriter responseWriter;
-
-    // Dispatch may have output to an OutputStream instead of a Writer
-    Writer renderResponseWriter = null;
-    try {
-      renderResponseWriter = mimeResponse.getWriter();
-    } 
-    catch (IllegalStateException ise) {     
-      // got this exception because we've called getOutputStream() previously
-      renderResponseWriter = new BufferedWriter(
-                          new OutputStreamWriter(
-                               mimeResponse.getPortletOutputStream(),
-                               mimeResponse.getCharacterEncoding()));
-    }
-    if (null != oldWriter)
-    {
-      responseWriter = oldWriter.cloneWithWriter(renderResponseWriter);
-    }
-    else
-    {
-      responseWriter = newWriter.cloneWithWriter(renderResponseWriter);
-    }
-    context.setResponseWriter(responseWriter);
-
-    strWriter.write(responseWriter);
-    renderResponseWriter.flush();
-
-    if (null != oldWriter)
-    {
-      context.setResponseWriter(oldWriter);
-    }
-
-    Object content = extContext.getRequestMap().get(Bridge.AFTER_VIEW_CONTENT);
-    if (content != null)
-    {
-      if (content instanceof char[])
-      {
-        mimeResponse.getWriter().write(new String((char[]) content));
-      }
-      else if (content instanceof byte[])
-      {
-        mimeResponse.getWriter().write(new String((byte[]) content));
-      }
-      else
-      {
-        throw new IOException("PortletViewHandlerImpl: invalid" + "AFTER_VIEW_CONTENT buffer type");
+        // Put the AFTER_VIEW_CONTENT into request scope
+        // temporarily    
+        if (renderResponseWrapper != null)
+        {               
+          extContext.getRequestMap().put(
+              Bridge.AFTER_VIEW_CONTENT,
+              (renderResponseWrapper.isChars()) ? (Object) renderResponseWrapper.getChars() : (Object) renderResponseWrapper.getBytes());
+        }
+        else if (resourceResponseWrapper != null)
+        {
+          extContext.getRequestMap().put(
+              Bridge.AFTER_VIEW_CONTENT,
+              (resourceResponseWrapper.isChars()) ? (Object) resourceResponseWrapper.getChars() : (Object) resourceResponseWrapper.getBytes());
+        }
       }
-    }
-    mimeResponse.flushBuffer();
   }
 
-*/
 
   /**
    * <p>

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerRenderResponseWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerRenderResponseWrapper.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerRenderResponseWrapper.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerRenderResponseWrapper.java Wed Jun 10 20:10:04 2009
@@ -21,6 +21,7 @@
 
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -31,101 +32,119 @@
 import javax.portlet.RenderResponse;
 
 
-public class PortletViewHandlerRenderResponseWrapper
-  extends RenderResponseWrapper
+public class PortletViewHandlerRenderResponseWrapper extends RenderResponseWrapper
+{
+  private static final int WRITE_BUFFER_SIZE = 4096;
+
+  private int mBufferSize = WRITE_BUFFER_SIZE;
+  private ByteArrayOutputStream mBytes;
+  private CharArrayWriter mCharWriter;
+  private boolean mIsWritingBytes;
+  private PrintWriter mPrintWriter;
+  private boolean mIsWritingChars;
+
+  public PortletViewHandlerRenderResponseWrapper(RenderResponse response)
   {
-    private static final int WRITE_BUFFER_SIZE = 1024;
+    super(response);
+  }
 
-    private int mBufferSize = WRITE_BUFFER_SIZE;
-    private ByteArrayOutputStream mBytes;
-    private boolean mIsWritingBytes;
-    private PrintWriter mPrintWriter;
-    private boolean mIsWritingChars;
-    
-    public PortletViewHandlerRenderResponseWrapper(RenderResponse response)
+
+  public PrintWriter getWriter() throws java.io.IOException
+  {
+    if (mIsWritingBytes)
     {
-      super(response);
+      throw new IllegalStateException();
     }
-    
-    public PrintWriter getWriter() throws java.io.IOException
+
+    if (mPrintWriter == null)
     {
-      if (mBytes == null)
-      {
-          mBytes = new ByteArrayOutputStream(mBufferSize);
-      }
-      if (mPrintWriter == null)
-      {
-          mPrintWriter = new PrintWriter(new OutputStreamWriter(mBytes, this.getCharacterEncoding()),true);
-      }
-      
-      mIsWritingChars = true;
-      mIsWritingBytes = false;
-      
-      return mPrintWriter;
+      mCharWriter = new CharArrayWriter(4096);
+      mPrintWriter = new PrintWriter(mCharWriter);
     }
-    
-    public OutputStream getPortletOutputStream() throws IOException
+
+    mIsWritingChars = true;
+    mIsWritingBytes = false;
+
+    return mPrintWriter;
+  }
+
+  public OutputStream getPortletOutputStream() throws IOException
+  {
+    if (mIsWritingChars)
     {
-        if (mBytes == null)
-        {
-            mBytes = new ByteArrayOutputStream(mBufferSize);
-        }
-        
-      mIsWritingChars = false;
-      mIsWritingBytes = true;
-        
-        return mBytes;
+      throw new IllegalStateException();
     }
     
-    public void resetBuffer()
+    if (mBytes == null)
     {
-
-        if (mPrintWriter != null) 
-        {
-            mPrintWriter.close();
-            mPrintWriter = null;
-        }
-        
-        reset();
-            
-        mIsWritingBytes = false;
-        mIsWritingChars = false;
+      mBytes = new ByteArrayOutputStream(mBufferSize);
     }
+
+    mIsWritingChars = false;
+    mIsWritingBytes = true;
+
+    return mBytes;
+  }
+
+  public void resetBuffer()
+  {
     
-    public void reset()
+    super.resetBuffer();
+
+    if (mIsWritingChars)
     {
-      if (mBytes != null)
-          mBytes.reset();
+      mPrintWriter.close();
+      mPrintWriter = null;
     }
     
-    
-    public void flushBuffer() throws java.io.IOException
+    if (mIsWritingBytes)
     {
-      if (mBytes == null) return; // nothing to do!
-      
-      
-      // Move the data from the buffer to the response
-      
-      // First determine whether response has used a writer or outputstream
-      try {
-        copyToWriter(this.getResponse().getWriter());
-      } 
-      catch (IllegalStateException ise) {     
-        mBytes.writeTo(this.getResponse().getPortletOutputStream());
-      }
+      mBytes.reset();
     }
+
+    mIsWritingBytes = false;
+    mIsWritingChars = false;
+  }
+
+  public void reset()
+  {
+    resetBuffer();
     
-    private void copyToWriter(PrintWriter writer) throws java.io.IOException
+    super.reset();
+  }
+
+
+  public void flushBuffer() throws java.io.IOException
+  {
+    // noop
+  }
+
+  public boolean isChars()
+  {
+    return mIsWritingChars;
+  }
+
+  public byte[] getBytes()
+  {
+    if (!isChars())
+    {
+      return mBytes.toByteArray();
+    } else
     {
-      try {
-        writer.write(mBytes.toString(this.getCharacterEncoding()));
-      }
-      catch (Exception e)
-      {
-        throw new IOException(e.toString());        
-      }
+      return null;
     }
-      
-  
-    
   }
+
+  public char[] getChars()
+  {
+    if (isChars())
+    {
+      return mCharWriter.toCharArray();
+    } else
+    {
+      return null;
+    }
+  }
+
+
+}

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerResourceResponseWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerResourceResponseWrapper.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerResourceResponseWrapper.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerResourceResponseWrapper.java Wed Jun 10 20:10:04 2009
@@ -19,112 +19,130 @@
 
 package org.apache.myfaces.portlet.faces.application;
 
-import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.io.StringWriter;
 
-import javax.portlet.filter.ResourceResponseWrapper;
 import javax.portlet.ResourceResponse;
-
+import javax.portlet.filter.ResourceResponseWrapper;
 
 public class PortletViewHandlerResourceResponseWrapper
   extends ResourceResponseWrapper
   {
-    private static final int WRITE_BUFFER_SIZE = 1024;
+    private static final int WRITE_BUFFER_SIZE = 4096;
 
     private int mBufferSize = WRITE_BUFFER_SIZE;
     private ByteArrayOutputStream mBytes;
+    private CharArrayWriter mCharWriter;
     private boolean mIsWritingBytes;
     private PrintWriter mPrintWriter;
     private boolean mIsWritingChars;
-    
+
     public PortletViewHandlerResourceResponseWrapper(ResourceResponse response)
     {
       super(response);
     }
-    
+
+
     public PrintWriter getWriter() throws java.io.IOException
     {
-      if (mBytes == null)
+      if (mIsWritingBytes)
       {
-          mBytes = new ByteArrayOutputStream(mBufferSize);
+        throw new IllegalStateException();
       }
+
       if (mPrintWriter == null)
       {
-          mPrintWriter = new PrintWriter(new OutputStreamWriter(mBytes, this.getCharacterEncoding()),true);
+        mCharWriter = new CharArrayWriter(4096);
+        mPrintWriter = new PrintWriter(mCharWriter);
       }
-      
+
       mIsWritingChars = true;
       mIsWritingBytes = false;
-      
+
       return mPrintWriter;
     }
-    
+
     public OutputStream getPortletOutputStream() throws IOException
     {
-        if (mBytes == null)
-        {
-            mBytes = new ByteArrayOutputStream(mBufferSize);
-        }
-        
+      if (mIsWritingChars)
+      {
+        throw new IllegalStateException();
+      }
+      
+      if (mBytes == null)
+      {
+        mBytes = new ByteArrayOutputStream(mBufferSize);
+      }
+
       mIsWritingChars = false;
       mIsWritingBytes = true;
-        
-        return mBytes;
+
+      return mBytes;
     }
-    
+
     public void resetBuffer()
     {
+      
+      super.resetBuffer();
+
+      if (mIsWritingChars)
+      {
+        mPrintWriter.close();
+        mPrintWriter = null;
+      }
+      
+      if (mIsWritingBytes)
+      {
+        mBytes.reset();
+      }
 
-        if (mPrintWriter != null) 
-        {
-            mPrintWriter.close();
-            mPrintWriter = null;
-        }
-        
-        reset();
-            
-        mIsWritingBytes = false;
-        mIsWritingChars = false;
+      mIsWritingBytes = false;
+      mIsWritingChars = false;
     }
-    
+
     public void reset()
     {
-      if (mBytes != null)
-          mBytes.reset();
+      resetBuffer();
+      
+      super.reset();
     }
-    
-    
+
+
     public void flushBuffer() throws java.io.IOException
     {
-      if (mBytes == null) return; // nothing to do!
-      
-      
-      // Move the data from the buffer to the response
-      
-      // First determine whether response has used a writer or outputstream
-      try {
-        copyToWriter(this.getResponse().getWriter());
-      } 
-      catch (IllegalStateException ise) {     
-        mBytes.writeTo(this.getResponse().getPortletOutputStream());
-      }
+      // noop
     }
-    
-    private void copyToWriter(PrintWriter writer) throws java.io.IOException
+
+    public boolean isChars()
+    {
+      return mIsWritingChars;
+    }
+
+    public byte[] getBytes()
     {
-      try {
-        writer.write(mBytes.toString(this.getCharacterEncoding()));
+      if (!isChars())
+      {
+        return mBytes.toByteArray();
+      } else
+      {
+        return null;
       }
-      catch (Exception e)
+    }
+
+    public char[] getChars()
+    {
+      if (isChars())
+      {
+        return mCharWriter.toCharArray();
+      } else
       {
-        throw new IOException(e.toString());        
+        return null;
       }
     }
+
       
   
     

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java Wed Jun 10 20:10:04 2009
@@ -105,6 +105,8 @@
 import org.apache.myfaces.portlet.faces.bridge.wrapper.BridgePortletRequestWrapper;
 import org.apache.myfaces.portlet.faces.bridge.wrapper.BridgeRenderRequestWrapper;
 import org.apache.myfaces.portlet.faces.context.PortletExternalContextImpl;
+import org.apache.myfaces.portlet.faces.el.PortletELContextImpl;
+import org.apache.myfaces.portlet.faces.el.PortletELResolver;
 import org.apache.myfaces.portlet.faces.util.QueryString;
 import org.apache.myfaces.portlet.faces.util.config.FacesConfigurationProcessor;
 import org.apache.myfaces.portlet.faces.util.config.WebConfigurationProcessor;
@@ -211,17 +213,16 @@
         portletContext.setAttribute(REQUEST_SCOPE_LOCK, new Object());
       }
     }
-
-    // Add self as ELContextListener to the Faces App so we can add the
-    // portletConfig to any newly created contexts.
-    ApplicationFactory appFactory = 
-      (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
     
-
     // Wrapped desired Application with our own to override createComponent and
-    // insert our NamingContainerUIViewRoot component.
-    Application app = appFactory.getApplication();
-    app.addELContextListener(this);
+    // insert our NamingContainerUIViewRoot component.  This was done through
+    // configuration via the META-INF/service/javax.faces.application.ApplicationFactory
+    
+    // Add self as ELContextListener to the Faces App so we can add the
+    // portletConfig to any newly created contexts.    
+    ((ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
+        .getApplication().addELContextListener(this);
+
 
     // Process and cache the FacesServlet mappings for use by
     // ExternalContext
@@ -1109,19 +1110,48 @@
 
     mPortletConfig = null;
   }
-
+  
   /**
    * ELContextListener impl
    */
+  
   public void contextCreated(ELContextEvent ece)
   {
     // Add the portletConfig to the ELContext so it is evaluated
     ELContext elContext = ece.getELContext();
 
-    // Only add if not already there
-    if (elContext.getContext(PortletConfig.class) == null)
-    {
-      elContext.putContext(PortletConfig.class, mPortletConfig);
+    // FacesContext (where the Faces/Bridge ELContext is created doesn't have
+    // access to the PortletConfig which the Bridge ELResolver needs.
+    // The config object is added as an attribute here in the ContextListener.
+    // However only add to a EL context created within Faces as the JSP
+    // ELContext/Resolver will naturally resolve the config (as long as the
+    // page devleper has used the <portlet:defineObjects> tag.
+    // Because listeners are called at app scope we must ensure that only
+    // the active portlet's config is added to the ELContext.  To do this, check
+    // the portletName previously stored as a request attribute against the config.
+    
+    // Make sure our bridge instance is handling this context
+    String portletName = (String) ((FacesContext) elContext.getContext(FacesContext.class)).getExternalContext().getRequestMap().get(PORTLET_NAME_ATTRIBUTE);
+    if (portletName != null && portletName.equals(mPortletConfig.getPortletName()))
+    {
+      PortletELContextImpl portletELContext;
+      if (elContext instanceof PortletELContextImpl)
+      {
+        // Grr -- turns out that by the time my resolver is called the ELContext may
+        // have been wrapped -- so mark here as a FacesResolver and then do a put context
+        portletELContext = (PortletELContextImpl) elContext;
+        portletELContext.setFacesResolved(true);
+        // Put the portletConfig object into this Map
+        portletELContext.setPortletConfig(mPortletConfig);
+
+      }
+      else
+      {
+        // create a PortletELContext to hold future resolver state and place on this context
+        portletELContext = new PortletELContextImpl(elContext.getELResolver());
+        portletELContext.setFacesResolved(false);
+      }
+      elContext.putContext(PortletELContextImpl.class, portletELContext);
     }
   }
 

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java Wed Jun 10 20:10:04 2009
@@ -65,6 +65,7 @@
 import javax.portlet.faces.BridgeInvalidViewPathException;
 
 import org.apache.myfaces.portlet.faces.bridge.BridgeImpl;
+import org.apache.myfaces.portlet.faces.util.FacesVersionUtil;
 import org.apache.myfaces.portlet.faces.util.QueryString;
 import org.apache.myfaces.portlet.faces.util.URLUtils;
 import org.apache.myfaces.portlet.faces.util.map.EnumerationIterator;
@@ -89,6 +90,12 @@
 
   public static final String FACES_MAPPING_ATTRIBUTE = 
     "org.apache.myfaces.portlet.faces.context.facesMapping";
+  
+  // Note: be careful -- as this attribute is prefixed to a value containg '.' it
+  // wouldn't be exlcuded using normal logic -- so instead BridgeImpl specially
+  // exlcudes/treats this package. -- i.e. all attrbiutes beginning with 
+  // "org.apache.myfaces.portlet.faces.context." are excluded -- so beware if
+  // you try and add an attribute you don't want exlcuded within this package.
   private static final String ENCODED_ACTION_URL_ATTRIBUTE_PREFIX =
     "org.apache.myfaces.portlet.faces.context.";
 
@@ -99,6 +106,9 @@
   public static final String JSF_TARGET_VIEWID_RENDER_PARAMETER = "__jpfbJSFTARGET";
   public static final String JSF_RESOURCE_TARGET_VIEWID_RENDER_PARAMETER = "__jpfbJSF_RESTARGET";
   public static final String NO_SCOPE = "org.apache.myfaces.portlet.faces.noScope";
+  
+  public static final String SERVLET_INCLUDED_PATHINFO_ATTRIBUTE = "javax.servlet.include.path_info";
+  public static final String SERVLET_INCLUDED_SERVLETPATH_ATTRIBUTE = "javax.servlet.include.servlet_path";
 
 
   private PortletContext mPortletContext;
@@ -131,8 +141,11 @@
   private List<String> mFacesMappings = null;
   private String mServletPath = null;
   private String mPathInfo = null;
-
-
+  private String mIncludedServletPath = null;
+  private String mIncludedPathInfo = null;
+  
+  private boolean mUseIncludeAttributeServletDependencyWorkaround;
+  
   @SuppressWarnings("unchecked")
   public PortletExternalContextImpl(PortletContext portletContext, PortletRequest portletRequest, 
                                     PortletResponse portletResponse)
@@ -146,13 +159,72 @@
 
     mFacesMappings = (List<String>) mPortletRequest.getAttribute(FACES_MAPPING_ATTRIBUTE);
     
+    setFacesVersionDependencyFlags();
+    
+    // Local portals commonly use the servlet dispatcher to execute the portlet container
+    // A side effect of this is the javax.servlet.include path attributes are set
+    // Unfortunately, Faces resolves viewId targets by first looking at these attributes 
+    // prior to consulting the externalContext (request info).  To avoid Faces
+    // from using these bad values -- clear them by caching them (we restore on release)
+    mIncludedPathInfo = (String) mPortletRequest.getAttribute(SERVLET_INCLUDED_PATHINFO_ATTRIBUTE);
+    mIncludedServletPath = (String) mPortletRequest.getAttribute(SERVLET_INCLUDED_SERVLETPATH_ATTRIBUTE);
+    mPortletRequest.removeAttribute(SERVLET_INCLUDED_PATHINFO_ATTRIBUTE);
+    mPortletRequest.removeAttribute(SERVLET_INCLUDED_SERVLETPATH_ATTRIBUTE);
+    
     // Because determining the view accesses request parameters -- delay until its demanded
     // so clients can still set request character encoding.
   }
-
+  
+  /**
+   * Sometimes the bridge has to workaround issues related to specific versions of a Faces
+   * implementation that can't be done in a generic/unobtrusive way.  Here we try to determine
+   * which workarounds should be enabled.  Currently there is only one: Faces RI (Mojarra) versions
+   * before 1.2_13 contained some servlet dependent code that gets hit during view resolution unless
+   * the bridge has set the ServletPath include attribute.  Unfortunately, Liferay (5.2) portlet container
+   * also writes/uses this attribute.  
+   */
+  private void setFacesVersionDependencyFlags()
+  {
+    mUseIncludeAttributeServletDependencyWorkaround = true;
+    // First check to see if there is a web.xml init parameter setting 
+    String disable = mPortletContext.getInitParameter("org.apache.myfaces.portlet.bridge.disableMojarraViewResolutionWorkaround");
+    if (disable != null)
+    {
+      mUseIncludeAttributeServletDependencyWorkaround = !Boolean.valueOf(disable).booleanValue();
+    }
+    else
+    {
+    switch (FacesVersionUtil.getFacesType())
+      {
+        case MOJARRA:
+          if (FacesVersionUtil.getFacesImplPatchVersion() >= 13)
+          {
+            mUseIncludeAttributeServletDependencyWorkaround = false;
+          }
+          break;
+        case MYFACES:
+          mUseIncludeAttributeServletDependencyWorkaround = false;
+          break;
+        default:
+          mUseIncludeAttributeServletDependencyWorkaround = true;
+          break;
+      }
+    }
+  }
+  
   public void release()
   {
 
+    // Restore the included path attributes if we unset them
+    if (mIncludedPathInfo != null)
+    {
+      mPortletRequest.setAttribute(SERVLET_INCLUDED_PATHINFO_ATTRIBUTE, mIncludedPathInfo);
+    }
+    if (mIncludedServletPath != null)
+    {
+      mPortletRequest.setAttribute(SERVLET_INCLUDED_SERVLETPATH_ATTRIBUTE, mIncludedServletPath);
+    }
+                                                                                                           
     mPortletContext = null;
     mPortletRequest = null;
     mPortletResponse = null;
@@ -1603,7 +1675,8 @@
       mPathInfo = null;
 
       // Workaround Faces RI that has Servlet dependencies if this isn't set
-      mPortletRequest.setAttribute("javax.servlet.include.servlet_path", mServletPath);
+      if (mUseIncludeAttributeServletDependencyWorkaround)
+        mPortletRequest.setAttribute(SERVLET_INCLUDED_SERVLETPATH_ATTRIBUTE, mServletPath);
     }
     else
     {

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELContextImpl.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELContextImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELContextImpl.java Wed Jun 10 20:10:04 2009
@@ -19,11 +19,16 @@
 
 package org.apache.myfaces.portlet.faces.el;
 
+import java.util.Map;
+
 import javax.el.ELContext;
 import javax.el.ELResolver;
 import javax.el.FunctionMapper;
 import javax.el.VariableMapper;
 
+import javax.portlet.PortletConfig;
+import javax.portlet.faces.preference.Preference;
+
 /**
  * Concrete implementation of {@link javax.el.ELContext}. ELContext's constructor is protected to
  * control creation of ELContext objects through their appropriate factory methods. This version of
@@ -36,6 +41,11 @@
   private FunctionMapper mFunctionMapper;
   private VariableMapper mVariableMapper;
   private ELResolver     mResolver;
+  private PortletConfig  mPortletConfig;
+  private Map<String, Object> mHttpSessionMap;
+  private Map<String, Preference> mMutablePortletPreferencesMap;
+  private boolean mIsFacesResolved = false;
+  
 
   /**
    * Constructs a new ELContext associated with the given ELResolver.
@@ -72,5 +82,46 @@
   {
     return mResolver;
   }
+  
+  public PortletConfig getPortletConfig()
+  {
+    return mPortletConfig;
+  }
+  
+  public void setPortletConfig(PortletConfig config)
+  {
+    mPortletConfig = config;
+  }
+  
+  public Map<String, Object> getHttpSessionMap()
+  {
+    return mHttpSessionMap;
+  }
+  
+  public void setHttpSessionMap(Map<String, Object> m)
+  {
+    mHttpSessionMap = m;
+  }
+  
+  public Map<String, Preference> getMutablePortletPreferencesMap()
+  {
+    return mMutablePortletPreferencesMap;
+  }
+  
+  public void setMutablePortletPreferencesMap(Map<String, Preference> m)
+  {
+    mMutablePortletPreferencesMap = m;
+  }
+  
+  public boolean isFacesResolved()
+  {
+    return mIsFacesResolved;
+  }
+  
+  public void setFacesResolved(boolean facesResolved)
+  {
+    mIsFacesResolved = facesResolved;
+  }
+  
 
 }

Modified: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java?rev=783483&r1=783482&r2=783483&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java (original)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java Wed Jun 10 20:10:04 2009
@@ -34,12 +34,20 @@
 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;
 
@@ -49,20 +57,33 @@
 public class PortletELResolver extends ELResolver
 {
 
-  // Important preserve index (order) between array and constants
-  // Just as important -- we binary search this array
-  // So it must be in alphabetic order
-  public static final String[] IMPLICIT_OBJECTS = new String[] {"portletConfig",
-      "portletPreferences",
-      "renderRequest", "renderResponse", 
-      "sessionApplicationScope", "sessionPortletScope"};
-
-  public static final int      PORTLET_CONFIG            = 0;
-  public static final int      PORTLET_PREFERENCES       = 1;
-  public static final int      RENDER_REQUEST            = 2;
-  public static final int      RENDER_RESPONSE           = 3;
-  public static final int      SESSION_APPLICATION_SCOPE = 4;
-  public static final int      SESSION_PORTLET_SCOPE     = 5;
+  // 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()
   {
@@ -77,55 +98,190 @@
     {
       throw new PropertyNotFoundException("Null property");
     }
-
-    FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
-    ExternalContext extCtx = facesContext.getExternalContext();
-
+    
     // only process if running in a portlet request
     if (!BridgeUtil.isPortletRequest() || base != null)
     {
       return null;
     }
-
-    int index = -1;
-    if (property instanceof String)
+    
+    // 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)
     {
-      index = Arrays.binarySearch(IMPLICIT_OBJECTS, property);
+      return null;
     }
-    switch (index)
+    
+    if (portletELContext.isFacesResolved())
     {
-      case RENDER_REQUEST:
-        context.setPropertyResolved(true);
-        return extCtx.getRequest();
-      case RENDER_RESPONSE:
-        context.setPropertyResolved(true);
-        return extCtx.getResponse();
-      case PORTLET_CONFIG:
-         context.setPropertyResolved(true);
-        return context.getContext(PortletConfig.class);
-      case SESSION_APPLICATION_SCOPE:
-        context.setPropertyResolved(true);
-        Map m = (Map) extCtx.getRequestMap().get("javax.portlet.faces.SessionApplicationScopeMap");
-        if (m == null)
+      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))
         {
-          m = new PortletSessionMap(extCtx.getRequest(), PortletSession.APPLICATION_SCOPE);
-          extCtx.getRequestMap().put("javax.portlet.faces.SessionApplicationScopeMap", m);
+          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;
         }
-        return m;
-      case SESSION_PORTLET_SCOPE:
-        context.setPropertyResolved(true);
-        return extCtx.getSessionMap();
-      case PORTLET_PREFERENCES:
-        context.setPropertyResolved(true);
-        m = (Map) extCtx.getRequestMap().get("javax.portlet.faces.PreferenceMap");
-        if (m == 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))
         {
-          m = getPreferenceMap(((PortletRequest) extCtx.getRequest()).getPreferences());
-          extCtx.getRequestMap().put("javax.portlet.faces.SessionApplicationScopeMap", m);
+          case httpSessionScope:
+            context.setPropertyResolved(true);
+            return getHttpSessionMap(extCtx, bridgeContext);
+
+          case mutablePortletPreferencesValues:
+            context.setPropertyResolved(true);
+            return getMutablePortletPreferencesValues(extCtx, bridgeContext);
+          default:
+            return null;
         }
-        return m;
-        default:
-          return null;
+      } catch (IllegalArgumentException e)
+      {
+        return null;
+      }
+    } else
+    {
+      return null;
     }
   }
 
@@ -145,16 +301,21 @@
     {
       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)
     {
-      index = Arrays.binarySearch(IMPLICIT_OBJECTS, property);
-    }
-    
-    if (index >= 0)
-    {
-      throw new PropertyNotWritableException((String) property);
+      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
+      }
     }
   }
 
@@ -172,16 +333,23 @@
       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)
     {
-      index = Arrays.binarySearch(IMPLICIT_OBJECTS, property);
-    }
-    if (index >= 0)
-    {
-      context.setPropertyResolved(true);
-      return true;
+      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;
   }
 
@@ -200,22 +368,22 @@
     }
 
     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)
     {
-      index = Arrays.binarySearch(IMPLICIT_OBJECTS, property);
+      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
+      }
     }
    
-    switch (index)
-    {
-      case RENDER_REQUEST:
-      case RENDER_RESPONSE:
-      case PORTLET_CONFIG:
-      case SESSION_APPLICATION_SCOPE:
-      case SESSION_PORTLET_SCOPE:
-      case PORTLET_PREFERENCES:
-          context.setPropertyResolved(true);
-    }
-    
     return null;
   }
   
@@ -227,22 +395,40 @@
     {
       return null;
     }
-    ArrayList<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>(14);
+    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("portletConfig", "portletConfig", "portletConfig", false, false,
-                                  true, PortletConfig.class, Boolean.TRUE));
-    list.add(getFeatureDescriptor("sessionApplicationScope", "sessionApplicationScope",
-                                  "sessionApplicationScope", false, false, true, Map.class,
-                                  Boolean.TRUE));
-    list.add(getFeatureDescriptor("sessionPortletScope", "sessionPortletScope",
-                                  "sessionPortletScope", false, false, true, Map.class,
-                                  Boolean.TRUE));
-    list.add(getFeatureDescriptor("portletPreferences", "portletPreferences",
-                                  "portletPreferences", false, false, true, Map.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();
 
@@ -328,5 +514,32 @@
     
     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;
+  }
 
 }
\ No newline at end of file

Added: myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/util/FacesVersionUtil.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/util/FacesVersionUtil.java?rev=783483&view=auto
==============================================================================
--- myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/util/FacesVersionUtil.java (added)
+++ myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/util/FacesVersionUtil.java Wed Jun 10 20:10:04 2009
@@ -0,0 +1,129 @@
+/* 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.util;
+
+import java.io.IOException;
+
+import java.net.URL;
+
+import java.util.Enumeration;
+import java.util.jar.Manifest;
+
+/**
+ * <a href="FacesUtil.java.html"><b><i>View Source</i></b></a>
+ * 
+ * @author Atul Patel
+ * @author Neil Griffin
+ * 
+ */
+public class FacesVersionUtil
+{
+
+  public static final String FACES_IMPL_NAME_MOJARRA = "mojarra";
+  public static final String FACES_IMPL_NAME_SUN = "sun";
+  public static final String FACES_IMPL_NAME_MYFACES = "myfaces";
+
+  private static final String JSF_IMPL_TITLE = "Implementation-Title";
+  private static final String JSF_IMPL_VERSION = "Implementation-Version";
+
+  private static String mFacesImplTitle;
+  private static int mFacesImplMajorVersion = -1;
+  private static int mFacesImplMinorVersion = -1;
+  private static int mFacesImplPatchVersion = -1;
+  private static FACES_TYPE mFacesType = FACES_TYPE.UNKNOWN;
+
+  public static enum FACES_TYPE
+  {
+    MOJARRA, // Sun RI
+    MYFACES, // Apache Faces
+    UNKNOWN  // couldn't determine
+  }
+
+  static {
+    try
+    {
+      Class c = Class.forName("javax.faces.webapp.FacesServlet");
+      mFacesImplTitle = c.getPackage().getImplementationTitle();
+
+      // Try and determine the FACES_TYPE based on the Title
+      if (mFacesImplTitle != null)
+      {
+        String title = mFacesImplTitle.toLowerCase();
+        if (title.indexOf(FACES_IMPL_NAME_MYFACES) >= 0)
+        {
+          mFacesType = FACES_TYPE.MYFACES;
+        } else if (title.indexOf(FACES_IMPL_NAME_MOJARRA) >= 0 || 
+                   title.indexOf(FACES_IMPL_NAME_SUN) >= 0)
+        {
+          mFacesType = FACES_TYPE.MOJARRA;
+        }
+        // Otherwise -- unknown
+      }
+
+      // Try and determine the Impl version number.
+      String implVersion = c.getPackage().getImplementationVersion();
+
+      if (implVersion != null)
+      {
+        String[] versions = implVersion.split("[\\-_\\.a-z]");
+        try {
+          mFacesImplMajorVersion = (versions.length < 1? -1: Integer.parseInt(versions[0]));
+          mFacesImplMinorVersion = (versions.length < 1? -2: Integer.parseInt(versions[1]));
+          // return -1 if a patch version can not be determined
+          mFacesImplPatchVersion = (versions.length < 3? -1: Integer.parseInt(versions[2]));
+        } 
+        catch (NumberFormatException e)
+        {
+          // do nothing -- can't parse the version
+        }
+      }
+    }
+    catch (ClassNotFoundException e)
+    {
+      // Do nothing -- can't determine the impl/version
+    }
+  }
+
+  public static int getFacesImplMajorVersion()
+  {
+    return mFacesImplMajorVersion;
+  }
+
+  public static int getFacesImplMinorVersion()
+  {
+    return mFacesImplMinorVersion;
+  }
+
+  public static String getFacesImplName()
+  {
+    return mFacesImplTitle;
+  }
+
+  public static int getFacesImplPatchVersion()
+  {
+    return mFacesImplPatchVersion;
+  }
+  
+  public static FACES_TYPE getFacesType()
+  {
+    return mFacesType;
+  }
+
+}