You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/03/04 12:02:51 UTC
svn commit: r633423 - in /myfaces/orchestra/trunk/core: pom.xml
src/main/java/org/apache/myfaces/orchestra/lib/jsf/FacesContextWrapper.java
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");
+ }
}
- */
}