Here are the diffs for the change to remove the LayoutViewRoot and to
remove the dynfaces dependency that JSFT currently has. The code
changes are done, but I have not finished cleaning up the javadoc (which
I'm doing now). Please review these changes and get back to me w/ any
questions / concerns.
I have tested this w/ dynafaces present, and w/o dynafaces present.
Both work fine. Only remaining regression is that the "decode" event
now no longer works for "pages." However, I think we can live w/o this
feature... if not, let me know and I'll find a way to make it work again.
Ken
? diff
? layout/ViewRootUtil.java
Index: component/factory/ComponentFactoryBase.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/component/factory/ComponentFactoryBase.java,v
retrieving revision 1.23
diff -u -r1.23 ComponentFactoryBase.java
--- component/factory/ComponentFactoryBase.java 16 Aug 2007 23:21:38 -0000 1.23
+++ component/factory/ComponentFactoryBase.java 2 Feb 2008 01:10:15 -0000
@@ -32,7 +32,6 @@
import javax.el.ValueExpression;
import javax.faces.component.ActionSource;
import javax.faces.component.UIComponent;
-import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import com.sun.jsftemplating.component.ComponentUtil;
Index: handlers/ComponentHandlers.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/handlers/ComponentHandlers.java,v
retrieving revision 1.13
diff -u -r1.13 ComponentHandlers.java
--- handlers/ComponentHandlers.java 20 Nov 2007 19:15:34 -0000 1.13
+++ handlers/ComponentHandlers.java 2 Feb 2008 01:10:15 -0000
@@ -33,6 +33,7 @@
import java.util.Map;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import com.sun.jsftemplating.annotation.Handler;
@@ -41,7 +42,6 @@
import com.sun.jsftemplating.component.ComponentUtil;
import com.sun.jsftemplating.layout.LayoutDefinitionManager;
import com.sun.jsftemplating.layout.LayoutViewHandler;
-import com.sun.jsftemplating.layout.LayoutViewRoot;
import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
import com.sun.jsftemplating.layout.descriptors.LayoutElement;
import com.sun.jsftemplating.layout.descriptors.LayoutElementBase;
@@ -178,8 +178,8 @@
// If they didn't give us a parent, make one one up...
if (parent == null) {
- parent = new LayoutViewRoot();
- ((LayoutViewRoot) parent).setViewId("fake");
+ parent = new UIViewRoot();
+ ((UIViewRoot) parent).setViewId("fake");
}
// Build it...
Index: handlers/MetaDataHandlers.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/handlers/MetaDataHandlers.java,v
retrieving revision 1.10
diff -u -r1.10 MetaDataHandlers.java
--- handlers/MetaDataHandlers.java 19 Apr 2007 01:19:25 -0000 1.10
+++ handlers/MetaDataHandlers.java 2 Feb 2008 01:10:15 -0000
@@ -36,7 +36,7 @@
import com.sun.jsftemplating.annotation.HandlerInput;
import com.sun.jsftemplating.annotation.HandlerOutput;
import com.sun.jsftemplating.layout.LayoutDefinitionManager;
-import com.sun.jsftemplating.layout.LayoutViewRoot;
+import com.sun.jsftemplating.layout.ViewRootUtil;
import com.sun.jsftemplating.layout.descriptors.ComponentType;
import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
import com.sun.jsftemplating.layout.descriptors.LayoutDefinition;
@@ -157,15 +157,14 @@
/**
* <p> This handler finds the (closest) requested
- * <code>LayoutComponent</code> for the given <code>viewId</code> /
+ * {_at_link LayoutComponent} for the given <code>viewId</code> /
* <code>clientId</code>. If the <code>viewId</code> is not supplied,
- * the current <code>UIViewRoot</code> will be used (NOTE: it must be
- * a {_at_link LayoutViewRoot}). The {_at_link LayoutComponent} is returned
- * via the <code>component</code> output parameter. If an exact match
- * is not found, it will return the last {_at_link LayoutComponent} found
- * while searching the tree -- this should be the last
- * {_at_link LayoutComponent} in the hierarchy of the specified
- * component.</p>
+ * the current <code>UIViewRoot</code> will be used. The
+ * {_at_link LayoutComponent} is returned via the <code>component</code>
+ * output parameter. If an exact match is not found, it will return
+ * the last {_at_link LayoutComponent} found while searching the tree --
+ * this should be the last {_at_link LayoutComponent} in the hierarchy
+ * of the specified component.</p>
*
* <p> This is not an easy process since JSF components may not all be
* <code>NamingContainer</code>s, so the clientId is not sufficient to
@@ -203,19 +202,7 @@
String viewId = (String) ctx.getInputValue("viewId");
// Find the LayoutDefinition
- LayoutDefinition def = null;
- if (viewId == null) {
- // Determine from the current LayoutViewRoot (if possible)
- Object viewRoot = ctx.getFacesContext().getViewRoot();
- if (viewRoot instanceof LayoutViewRoot) {
- def = ((LayoutViewRoot) viewRoot).
- getLayoutDefinition(ctx.getFacesContext());
- }
- } else {
- // viewId specified, use that...
- def = LayoutDefinitionManager.getLayoutDefinition(
- ctx.getFacesContext(), viewId);
- }
+ LayoutDefinition def = ViewRootUtil.getLayoutDefinition(viewId);
// Set the result
ctx.setOutputValue("layoutDefinition", def);
Index: layout/LayoutDefinitionManager.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/layout/LayoutDefinitionManager.java,v
retrieving revision 1.39
diff -u -r1.39 LayoutDefinitionManager.java
--- layout/LayoutDefinitionManager.java 20 Nov 2007 22:06:19 -0000 1.39
+++ layout/LayoutDefinitionManager.java 2 Feb 2008 01:10:16 -0000
@@ -160,6 +160,7 @@
}
/**
+// FIXME: Javadoc
* <p> This method finds the (closest) requested
* <code>LayoutComponent</code> for the given <code>clientId</code>.
* If the <code>viewId</code> is not supplied, the current
@@ -191,7 +192,8 @@
"Unable to find LayoutDefinition ('" + ldKey + "')");
}
} else {
- layElt = ((LayoutViewRoot) ctx.getViewRoot()).getLayoutDefinition(ctx);
+ layElt = ViewRootUtil.getLayoutDefinition(
+ FacesContext.getCurrentInstance().getViewRoot());
}
// Save the current LayoutComposition Stack
Index: layout/LayoutViewHandler.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/layout/LayoutViewHandler.java,v
retrieving revision 1.34
diff -u -r1.34 LayoutViewHandler.java
--- layout/LayoutViewHandler.java 18 Oct 2007 06:21:24 -0000 1.34
+++ layout/LayoutViewHandler.java 2 Feb 2008 01:10:16 -0000
@@ -78,13 +78,13 @@
* <code>layout.dtd</code>.</p>
*
* <p> Besides the default <code>ViewHandler</code> behavior, this class is
- * responsible for instantiating a {_at_link LayoutViewRoot} and using the
- * given <code>viewId</code> as the {_at_link LayoutDefinition} key. It
- * will obtain the {_at_link LayoutDefinition}, initialize the declared
- * {_at_link Resource}s, and instantiate <code>UIComponent</code> tree using
- * the {_at_link LayoutDefinition}'s declared {_at_link LayoutComponent}
- * structure. During rendering, it delegates to the
- * {_at_link LayoutDefinition}.</p>
+ * responsible for using the given <code>viewId</code> as the
+ * {_at_link LayoutDefinition} key and setting it on the UIViewRoot that is
+ * created. It will obtain the {_at_link LayoutDefinition}, initialize the
+ * declared {_at_link Resource}s, and instantiate <code>UIComponent</code>
+ * tree using the {_at_link LayoutDefinition}'s declared
+ * {_at_link LayoutComponent} structure. During rendering, it delegates to
+ * the {_at_link LayoutDefinition}.</p>
*
* @author Ken Paulsen (ken.paulsen_at_sun.com)
*/
@@ -128,7 +128,7 @@
// Check to see if jsftemplating should create the view
if(!this.isMappedView(viewId)) {
- UIViewRoot viewRoot = this._oldViewHandler.createView(context, viewId);
+ UIViewRoot viewRoot = _oldViewHandler.createView(context, viewId);
return viewRoot;
}
@@ -140,22 +140,21 @@
// one for the initial case.
if (context.getViewRoot() != null) {
UIViewRoot oldViewRoot = context.getViewRoot();
- if ((oldViewRoot instanceof LayoutViewRoot)
- && oldViewRoot.getViewId().equals(viewId)) {
+ LayoutDefinition oldLD = ViewRootUtil.getLayoutDefinition(oldViewRoot);
+ if ((oldLD != null) && oldViewRoot.getViewId().equals(viewId)) {
// If you navigate to the page you are already on, JSF will
// re-create the UIViewRoot of the current page. The initPage
// event needs to be reset so that it will re-execute itself.
- ((LayoutViewRoot) oldViewRoot).getLayoutDefinition(context).
- setInitPageExecuted(context, Boolean.FALSE);
+ oldLD.setInitPageExecuted(context, Boolean.FALSE);
}
locale = context.getViewRoot().getLocale();
renderKitId = context.getViewRoot().getRenderKitId();
}
- // Create the LayoutViewRoot
- LayoutViewRoot viewRoot = new LayoutViewRoot();
+ // Create the ViewRoot
+ UIViewRoot viewRoot = _oldViewHandler.createView(context, viewId);
viewRoot.setViewId(viewId);
- viewRoot.setLayoutDefinitionKey(viewId);
+ ViewRootUtil.setLayoutDefinitionKey(viewRoot, viewId);
// if there was no locale from the previous view, calculate the locale
// for this view.
@@ -185,7 +184,7 @@
// Initialize Resources / Create Tree
LayoutDefinition def = null;
try {
- def = viewRoot.getLayoutDefinition(context);
+ def = ViewRootUtil.getLayoutDefinition(viewRoot);
} catch (LayoutDefinitionException ex) {
if (LogUtil.configEnabled()) {
LogUtil.config("JSFT0005", (Object) viewId);
@@ -278,7 +277,7 @@
context.responseComplete();
// Create dummy UIViewRoot
- UIViewRoot root = new LayoutViewRoot();
+ UIViewRoot root = new UIViewRoot();
root.setRenderKitId("dummy");
// Setup the FacesStreamerContext
@@ -566,7 +565,7 @@
// Perform default behavior...
UIViewRoot root = _oldViewHandler.restoreView(context, viewId);
- // Return the UIViewRoot (LayoutViewRoot most likely)
+ // Return the UIViewRoot
return root;
}
@@ -575,11 +574,7 @@
*/
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException {
// Make sure we have a def
- LayoutDefinition def = null;
- if (viewToRender instanceof LayoutViewRoot) {
- def = ((LayoutViewRoot) viewToRender).getLayoutDefinition(context);
- }
-
+ LayoutDefinition def = ViewRootUtil.getLayoutDefinition(viewToRender);
if (def == null) {
// No def, fall back to default behavior
_oldViewHandler.renderView(context, viewToRender);
@@ -588,16 +583,8 @@
ResponseWriter writer = setupResponseWriter(context);
writer.startDocument();
-// BEGIN EXPERIMENTAL CODE...
- UIComponent target = (UIComponent) context.getExternalContext().
- getRequestMap().get(AJAX_REQ_TARGET_KEY);
- if (target != null) {
- renderComponent(context, target);
- } else {
-// END EXPERIMENTAL CODE...
- // Render content
- def.encode(context, viewToRender);
- }
+ // Render content
+ def.encode(context, viewToRender);
// End document
writer.endDocument();
@@ -700,9 +687,8 @@
public void writeState(FacesContext context) throws IOException {
// Check to see if we should delegate back to the legacy ViewHandler
UIViewRoot root = context.getViewRoot();
- if ((root == null) || !(root instanceof LayoutViewRoot)
- || (((LayoutViewRoot) root).
- getLayoutDefinition(context) == null)) {
+ if ((root == null)
+ || (ViewRootUtil.getLayoutDefinition(root) == null)) {
// Use old behavior...
_oldViewHandler.writeState(context);
} else {
Index: layout/descriptors/LayoutComponent.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/layout/descriptors/LayoutComponent.java,v
retrieving revision 1.11
diff -u -r1.11 LayoutComponent.java
--- layout/descriptors/LayoutComponent.java 7 Aug 2007 22:45:08 -0000 1.11
+++ layout/descriptors/LayoutComponent.java 2 Feb 2008 01:10:16 -0000
@@ -29,13 +29,14 @@
import java.util.Map;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import com.sun.jsftemplating.component.ChildManager;
import com.sun.jsftemplating.component.ComponentUtil;
import com.sun.jsftemplating.component.TemplateComponent;
import com.sun.jsftemplating.el.VariableResolver;
-import com.sun.jsftemplating.layout.LayoutViewRoot;
+import com.sun.jsftemplating.layout.ViewRootUtil;
import com.sun.jsftemplating.layout.descriptors.handler.Handler;
import com.sun.jsftemplating.layout.event.AfterCreateEvent;
import com.sun.jsftemplating.layout.event.AfterEncodeEvent;
@@ -423,9 +424,10 @@
== getLayoutDefinition()) {
name = getUnevaluatedId();
}
- } else if (parent instanceof LayoutViewRoot) {
- // NOTE: I am not checking for UIViewRoot b/c I don't want to
- // use a facet unless we're using JSFT's LayoutViewRoot
+ } else if ((parent instanceof UIViewRoot) && (ViewRootUtil.
+ getLayoutDefinition((UIViewRoot) parent) != null)) {
+
+ // NOTE: Only set the name if its a JSFT ViewRoot
name = getUnevaluatedId();
}
}
Index: layout/descriptors/LayoutDefinition.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/layout/descriptors/LayoutDefinition.java,v
retrieving revision 1.13
diff -u -r1.13 LayoutDefinition.java
--- layout/descriptors/LayoutDefinition.java 16 Aug 2007 23:04:21 -0000 1.13
+++ layout/descriptors/LayoutDefinition.java 2 Feb 2008 01:10:16 -0000
@@ -28,16 +28,17 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.lang.reflect.Method;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
-import com.sun.faces.extensions.avatar.lifecycle.AsyncResponse;
import com.sun.jsftemplating.component.TemplateComponent;
import com.sun.jsftemplating.layout.descriptors.handler.Handler;
import com.sun.jsftemplating.layout.event.DecodeEvent;
import com.sun.jsftemplating.layout.event.InitPageEvent;
+import com.sun.jsftemplating.util.Util;
/**
* <p> This represents the top-level {_at_link LayoutElement}, it is the
@@ -219,13 +220,12 @@
public void encode(FacesContext context, UIComponent component) throws IOException {
if (component instanceof UIViewRoot) {
component.encodeBegin(context);
- AsyncResponse async = AsyncResponse.getInstance(false);
- if ((async == null) || !AsyncResponse.isAjaxRequest() || async.isRenderAll()) {
- // This is not an ajax request... behave normal
- super.encode(context, component);
- } else {
+ if (isDynaFacesRequest()) {
// Dynamic Faces is now overriding this, so this is required...
component.encodeChildren(context);
+ } else {
+ // This is not an ajax request... behave normal
+ super.encode(context, component);
}
component.encodeEnd(context);
} else {
@@ -234,6 +234,41 @@
}
/**
+ * <p> This method reflectively calls dyna-faces to determine if this
+ * request will be handled by dynafaces.</p>
+ */
+ private boolean isDynaFacesRequest() {
+ if (_asyncResponseClass == null) {
+ // DynamicFaces not installed, abort
+ return false;
+ }
+
+ // Check the request...
+ boolean result = false;
+ try {
+ // See if this is an DynaFaces Ajax request
+ result = ((Boolean) _asyncResponseIsAjaxRequest.invoke(null)).
+ booleanValue();
+ if (result) {
+ // See if this is a "render all" ajax request, in which case
+ // we'll consider it NOT to be an Ajax request.
+ Object async = _asyncResponseGetInstance.invoke(null,
+ Boolean.FALSE);
+ result = !((Boolean) _asyncResponseIsRenderAll.invoke(async)).
+ booleanValue();
+ }
+ } catch (Exception ex) {
+// FIXME: Log
+System.out.println("Incorrect Dynafaces Version?");
+ex.printStackTrace();
+ return false;
+ }
+
+ // Return the answer
+ return result;
+ }
+
+ /**
* <p> The <code>LayoutDefinition</code> does not encode anything for
* itself, this method simply returns true.</p>
*
@@ -349,6 +384,20 @@
ctx.getExternalContext().getRequestMap().put(key, value);
}
+ /**
+ * <p> This method eats the exception that might be thrown when locating
+ * a class.</p>
+ */
+ private static Class loadClass(String className, Object obj) {
+ Class result = null;
+ try {
+ result = Util.loadClass(className, obj);
+ } catch (ClassNotFoundException ex) {
+ // Eat it.
+ }
+ return result;
+ }
+
/**
*
@@ -399,4 +448,30 @@
* information about the <code>LayoutDefinition</code>.</p>
*/
private Map<String, Object> _attributes = new HashMap<String, Object>();
+
+ /**
+ * <p> The DynamicFaces AsyncResponse Class.</p>
+ */
+ private static final Class _asyncResponseClass;
+ private static final Method _asyncResponseGetInstance;
+ private static final Method _asyncResponseIsAjaxRequest;
+ private static final Method _asyncResponseIsRenderAll;
+
+ static {
+ // Initialize the DynamicFaces variables
+ _asyncResponseClass = loadClass(
+ "com.sun.faces.extensions.avatar.lifecycle.AsyncResponse", null);
+ if (_asyncResponseClass != null) {
+ _asyncResponseGetInstance =
+ Util.getMethod(_asyncResponseClass, "getInstance", Boolean.TYPE);
+ _asyncResponseIsAjaxRequest =
+ Util.getMethod(_asyncResponseClass, "isAjaxRequest");
+ _asyncResponseIsRenderAll =
+ Util.getMethod(_asyncResponseClass, "isRenderAll");
+ } else {
+ _asyncResponseGetInstance = null;
+ _asyncResponseIsAjaxRequest = null;
+ _asyncResponseIsRenderAll = null;
+ }
+ }
}
Index: util/Util.java
===================================================================
RCS file: /cvs/jsftemplating/src/java/com/sun/jsftemplating/util/Util.java,v
retrieving revision 1.12
diff -u -r1.12 Util.java
--- util/Util.java 25 Apr 2007 20:58:14 -0000 1.12
+++ util/Util.java 2 Feb 2008 01:10:17 -0000
@@ -23,6 +23,7 @@
package com.sun.jsftemplating.util;
import java.io.InputStream;
+import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
@@ -140,6 +141,24 @@
}
/**
+ * <p> This method locates the requested <code>Method</code> on the
+ * given <code>Class</code>, with the given <code>params</code>. This
+ * method does not throw any exceptions. Instead it will return
+ * <code>null</code> if unable to locate the method.</p>
+ */
+ public static Method getMethod(Class cls, String name, Class ... prms) {
+ Method method = null;
+ try {
+ method = cls.getMethod(name, prms);
+ } catch (NoSuchMethodException ex) {
+ // Do nothing, we're eating the exception
+ } catch (SecurityException ex) {
+ // Do nothing, we're eating the exception
+ }
+ return method;
+ }
+
+ /**
* <p> This method converts the given Map into a Properties Map (if it is
* already one, then it simply returns the given Map).</p>
*/