myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skitch...@apache.org
Subject svn commit: r633423 - in /myfaces/orchestra/trunk/core: pom.xml src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java
Date Tue, 04 Mar 2008 11:02:51 GMT
Author: skitching
Date: Tue Mar  4 03:02:45 2008
New Revision: 633423

URL: http://svn.apache.org/viewvc?rev=633423&view=rev
Log:
Make Orchestra work with MyFaces Core 1.2.2 when some other library provides a FacesContextFactory
that wraps the orchestra one.

Modified:
    myfaces/orchestra/trunk/core/pom.xml
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java

Modified: myfaces/orchestra/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/pom.xml?rev=633423&r1=633422&r2=633423&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/pom.xml (original)
+++ myfaces/orchestra/trunk/core/pom.xml Tue Mar  4 03:02:45 2008
@@ -54,6 +54,14 @@
     </dependency>
 
     <dependency>
+      <!-- Needed for JSF1.1/JSF1.2 compatibility  -->
+      <groupId>javax.el</groupId>
+      <artifactId>el-api</artifactId>
+      <version>1.0</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
       <groupId>javax.persistence</groupId>
       <artifactId>persistence-api</artifactId>
       <version>1.0</version>

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java?rev=633423&r1=633422&r2=633423&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java
(original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java
Tue Mar  4 03:02:45 2008
@@ -18,8 +18,11 @@
  */
 package org.apache.myfaces.orchestra.lib.jsf;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Iterator;
 
+import javax.el.ELContext;
 import javax.faces.application.Application;
 import javax.faces.application.FacesMessage;
 import javax.faces.component.UIViewRoot;
@@ -29,6 +32,9 @@
 import javax.faces.context.ResponseWriter;
 import javax.faces.render.RenderKit;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 
 /**
  * Convenient class to wrap the current FacesContext.
@@ -56,6 +62,7 @@
     //~ Instance fields -------------------------------------------------------
 
     private final FacesContext _facesContext;
+    private Method methodGetELContext = null;
 
     //~ Constructors ----------------------------------------------------------
 
@@ -180,15 +187,69 @@
         _facesContext.responseComplete();
     }
 
-    // This method is present in JSF1.1, but not JSF1.2 so must not
-    // exist in this JSF1.1-compatible wrapper class. The default
-    // implementation provided by the base FacesContext class in
-    // JSF1.2 should be adequate as long as this class does NOT
-    // use install=true in the constructor. See MYFACES-1820.
-    /*
+    /**
+     * Implement getELContext by delegating call to another instance.
+     * <p>
+     * Note that this method was added in JSF1.2. In order for a JSF1.2
+     * implementation to be backwards-compatible with JSF1.1, the base
+     * class FacesContext therefore has to automatically do the delegation.
+     * Without automatic delegation, any JSF1.1 class that applies the decorator
+     * pattern to a FacesContext will just break in JSF1.2; the getELContext
+     * method is there (inherited from the base class) but does not correctly
+     * delegate.
+     * <p>
+     * Unfortunately, due to a design flaw in JSF1.2 it is simply not possible
+     * for the base class to delegate; the object to delegate to is not known
+     * to the base class! A partial solution that works in most cases is for
+     * the base class to delegate to the "core" instance of FacesContext for
+     * methods that are not overridden; Sun's RI does this correctly but
+     * unfortunately MyFaces 1.2.0-1.2.2 do not. See MYFACES-1820 for details.
+     * <p>
+     * The solution *here* is to require that a javax.el implementation is in
+     * the classpath even when running JSF1.1. It is then possible for this
+     * wrapper to override the method defined in JSF1.2 even when being 
+     * compiled against the JSF1.1 implementation. It is mildly annoying to
+     * have to include javax.el in a JSF environment (ie when it will never
+     * be used) but better than the alternatives. Actually, for at least some
+     * JVMs, classes needed by a method are not loaded unless that method is
+     * actually referenced, so in some cases (including Sun Java 1.4-1.6) the
+     * el library *can* be omitted from the classpath with JSF1.1.
+     */
     public final ELContext getELContext()
     {
-        return _facesContext.getELContext();
+    	// Here, we cannot call getELContext on FacesContext as it does not
+    	// exist for JSF1.1; the solution is to use reflection instead. This
+    	// method will never be called unless we are in a JSF1.2 environment
+    	// so the target method will always exist when this is called.
+    	try
+    	{
+    		if (methodGetELContext == null)
+    		{
+    			// Performance optimisation: find method, and cache it for later.
+    			methodGetELContext = FacesContext.class.getDeclaredMethod("getELContext", (Class[])
null);
+    		}
+    		return (ELContext) methodGetELContext.invoke(_facesContext, (Object[]) null);
+    	}
+    	catch(NoSuchMethodException e)
+    	{
+    		// should never happen
+    		Log log = LogFactory.getLog(this.getClass());
+    		log.error("JSF1.2 method invoked in non-JSF-1.2 environment", e);
+    		throw new IllegalStateException("JSF1.2 method invoked in non-JSF-1.2 environment");
+    	}
+    	catch(InvocationTargetException e)
+    	{
+    		// should never happen
+    		Log log = LogFactory.getLog(this.getClass());
+    		log.error("Method getELContext on wrapped instance threw exception", e);
+    		throw new IllegalStateException("Method getELContext on wrapped instance threw exception");
+    	}
+    	catch(IllegalAccessException e)
+    	{
+    		// should never happen
+    		Log log = LogFactory.getLog(this.getClass());
+    		log.error("Method getElContext on wrapped instance is not accessable", e);
+    		throw new IllegalStateException("Method getElContext on wrapped instance is not accessable");
+    	}
     }
-    */
 }



Mime
View raw message