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/10/20 11:50:34 UTC
svn commit: r706174 - in /myfaces/orchestra/trunk/flow/src/main:
java/org/apache/myfaces/orchestra/flow/
java/org/apache/myfaces/orchestra/flow/components/ resources/META-INF/
Author: skitching
Date: Mon Oct 20 02:50:34 2008
New Revision: 706174
URL: http://svn.apache.org/viewvc?rev=706174&view=rev
Log:
Add clearOnCommit component, and invoke it on flow commit.
Added:
myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java (with props)
myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java (with props)
Modified:
myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/FlowHandler.java
myfaces/orchestra/trunk/flow/src/main/resources/META-INF/faces-config.xml
myfaces/orchestra/trunk/flow/src/main/resources/META-INF/myfaces_orchestra_flow.tld
Modified: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/FlowHandler.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/FlowHandler.java?rev=706174&r1=706173&r2=706174&view=diff
==============================================================================
--- myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/FlowHandler.java (original)
+++ myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/FlowHandler.java Mon Oct 20 02:50:34 2008
@@ -38,6 +38,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.orchestra.conversation.ConversationContext;
import org.apache.myfaces.orchestra.conversation.ConversationManager;
+import org.apache.myfaces.orchestra.flow.components.ClearOnCommit;
import org.apache.myfaces.orchestra.flow.components.ModalFlow;
import org.apache.myfaces.orchestra.flow.config.FlowAccept;
import org.apache.myfaces.orchestra.flow.config.FlowCall;
@@ -323,6 +324,13 @@
// Now restore the view tree of the caller.
restoreViewRoot(facesContext, callerViewId, callerViewRoot);
+ if (callerViewRoot != null)
+ {
+ // Clear any input components in the caller view which reference values that
+ // are return values.
+ ClearOnCommit.executeAllInstances(callerViewRoot, flowInfo.getCallerOutcome());
+ }
+
// And with the original context active, write parameters back then
// invoke any custom actions the caller wants to run.
//
Added: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java?rev=706174&view=auto
==============================================================================
--- myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java (added)
+++ myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java Mon Oct 20 02:50:34 2008
@@ -0,0 +1,197 @@
+/*
+ * 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.orchestra.flow.components;
+
+import java.util.Iterator;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+/**
+ * A component which handles clearing of cached user input (submittedValue) from
+ * input components whose model has been modified by an invoked flow.
+ * <p>
+ * When a flowcall is triggered by an immediate component, data entered by the user
+ * into input components is not pushed into the model before the call; it just gets
+ * stored in the "submittedValue" property of the input components. This view tree
+ * is then cached, and on return from the flow the original tree is deliberately restored
+ * so that user-entered data is not lost.
+ * <p>
+ * However this is a problem for input components whose model value has been modified by
+ * the flowcall (ie which map to something updated by a return-value from the flow). In
+ * this case we *do* want to discard the submittedValue in the component so that the
+ * new value in the model is displayed.
+ * <p>
+ * There is no automatic way to detect which input components in a page are affected by
+ * the return parameters from a flow. It *is* possible to detect input components whose
+ * value attribute is an EL expression that is identical to an EL expression for a return
+ * value, and that might be implemented in future. However there are many cases where a
+ * dependency cannot be detected with this simple test.
+ * <p>
+ * Instances of this component can be added to the page to explicitly mark components that
+ * need to be cleared on return from a specific flowcall.
+ * <p>
+ * Clearing of the submittedValue obviously does NOT need to be done on the first render
+ * of a view; it is something that is only relevant when a view has had at least one
+ * postback cycle and is then being re-rendered. And it is not relevant when a flowcall
+ * is triggered by a non-immediate command-component; in that case there is no _submittedValue
+ * cached in any input component, so updated model values cannot be "hidden" by the
+ * componenent cached value. In fact in this case, the original view is not even cached at
+ * all, as it can simply be recreated.
+ * <p>
+ * This component cannot be used with input components that are within a dataTable component;
+ * in that case the cached submitted-values are actually stored secretly within the dataTable
+ * and simply cannot be accessed by this component. In that case, the only solution is to
+ * apply this component to the entire table, ie clear all user data in all input fields
+ * within the table on flow return. This is not perfect, but is the best that can be done.
+ * <p>
+ * Note that this component does not simply "reset" the component; it actually deletes the
+ * component from the tree and relies on the rendering phase to recreate a new clean instance.
+ * This is done because UIInput has a resetValue method, but UIData does not.
+ */
+
+public class ClearOnCommit extends UIComponentBase
+{
+ public static final String COMPONENT_FAMILY = "javax.faces.Component";
+ public static final String COMPONENT_TYPE = "org.apache.myfaces.orchestra.flow.components.ClearOnCommit";
+
+ private String outcome;
+ private String target;
+
+ public String getFamily()
+ {
+ return COMPONENT_FAMILY;
+ }
+
+ /**
+ * The navigation outcome that causes this component to remove the target component
+ * from the component tree.
+ * <p>
+ * Static value only (EL expressions not supported).
+ */
+ public String getOutcome()
+ {
+ return outcome;
+ }
+
+ public void setOutcome(String outcome)
+ {
+ this.outcome = outcome;
+ }
+
+ /**
+ * Return the JSF component id of the target component to clear.
+ * <p>
+ * Static value only (EL expressions not supported).
+ */
+ public String getTarget()
+ {
+ return target;
+ }
+
+ public void setTarget(String target)
+ {
+ this.target = target;
+ }
+
+ /**
+ * If the specified navigation-outcome matches the outcome attribute of this component
+ * then delete the associated target component.
+ */
+ private void clearTargetComponent(String outcome)
+ {
+ if (!outcome.equals(this.outcome))
+ {
+ return;
+ }
+
+ if (this.getChildCount() > 0)
+ {
+ this.getChildren().clear();
+ }
+
+ if (target != null)
+ {
+ UIComponent targetComponent = this.findComponent(target);
+ if (targetComponent == null)
+ {
+ throw new FacesException("Target component for clearOnCommit does not exist:" + target);
+ }
+ targetComponent.getParent().getChildren().remove(targetComponent);
+ }
+ }
+
+ // ================ State Methods =================
+
+ public void restoreState(FacesContext context, Object state)
+ throws FacesException
+ {
+ Object[] states = (Object[]) state;
+ super.restoreState(context, states[0]);
+ outcome = (String) states[1];
+ target = (String) states[2];
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ return new Object[]
+ {
+ super.saveState(context),
+ outcome,
+ target
+ };
+ }
+
+ // ============ Static methods =================
+
+ /**
+ * Execute the clearTargetComponent method of each ClearOnCommit component in the specified view tree.
+ * <p>
+ * This clears any _submittedValue property from the "target" component of each clearOnCommit component
+ * in the tree which has an outcome that matches the specified outcome value.
+ */
+ public static void executeAllInstances(UIViewRoot viewRoot, String outcome)
+ {
+ applyToAll(viewRoot, outcome);
+ }
+
+ private static void applyToAll(UIComponent c, String outcome)
+ {
+ if (c instanceof ClearOnCommit)
+ {
+ ((ClearOnCommit) c).clearTargetComponent(outcome);
+ }
+
+ if (c.getChildCount() == 0)
+ {
+ return;
+ }
+
+ Iterator i = c.getChildren().iterator();
+ while (i.hasNext())
+ {
+ applyToAll((UIComponent) i.next(), outcome);
+ }
+ }
+
+}
Propchange: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommit.java
------------------------------------------------------------------------------
svn:executable = *
Added: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java?rev=706174&view=auto
==============================================================================
--- myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java (added)
+++ myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java Mon Oct 20 02:50:34 2008
@@ -0,0 +1,61 @@
+/*
+ * 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.orchestra.flow.components;
+
+import javax.faces.component.UIComponent;
+
+import org.apache.myfaces.shared_orchestra.taglib.UIComponentTagBase;
+
+/**
+ * Tag for ClearOnCommit component.
+ */
+public class ClearOnCommitTag extends UIComponentTagBase
+{
+ private String outcome;
+ private String target;
+
+ public String getComponentType()
+ {
+ return ClearOnCommit.COMPONENT_TYPE;
+ }
+
+ protected void setProperties(UIComponent component)
+ {
+ super.setProperties(component);
+
+ setStringProperty(component, "outcome", outcome);
+ setStringProperty(component, "target", target);
+ }
+
+ public void setOutcome(String outcome)
+ {
+ this.outcome = outcome;
+ }
+
+ public void setTarget(String target)
+ {
+ this.target = target;
+ }
+
+ public String getRendererType()
+ {
+ return null;
+ }
+}
Propchange: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/orchestra/trunk/flow/src/main/java/org/apache/myfaces/orchestra/flow/components/ClearOnCommitTag.java
------------------------------------------------------------------------------
svn:executable = *
Modified: myfaces/orchestra/trunk/flow/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/flow/src/main/resources/META-INF/faces-config.xml?rev=706174&r1=706173&r2=706174&view=diff
==============================================================================
--- myfaces/orchestra/trunk/flow/src/main/resources/META-INF/faces-config.xml (original)
+++ myfaces/orchestra/trunk/flow/src/main/resources/META-INF/faces-config.xml Mon Oct 20 02:50:34 2008
@@ -37,5 +37,10 @@
<component-type>org.apache.myfaces.orchestra.flow.components.ModalFlow</component-type>
<component-class>org.apache.myfaces.orchestra.flow.components.ModalFlow</component-class>
</component>
+
+ <component>
+ <component-type>org.apache.myfaces.orchestra.flow.components.ClearOnCommit</component-type>
+ <component-class>org.apache.myfaces.orchestra.flow.components.ClearOnCommit</component-class>
+ </component>
</faces-config>
Modified: myfaces/orchestra/trunk/flow/src/main/resources/META-INF/myfaces_orchestra_flow.tld
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/flow/src/main/resources/META-INF/myfaces_orchestra_flow.tld?rev=706174&r1=706173&r2=706174&view=diff
==============================================================================
--- myfaces/orchestra/trunk/flow/src/main/resources/META-INF/myfaces_orchestra_flow.tld (original)
+++ myfaces/orchestra/trunk/flow/src/main/resources/META-INF/myfaces_orchestra_flow.tld Mon Oct 20 02:50:34 2008
@@ -64,4 +64,28 @@
</description>
</attribute>
</tag>
+ <tag>
+ <name>clearOnCommit</name>
+ <tag-class>org.apache.myfaces.orchestra.flow.components.ClearOnCommitTag</tag-class>
+ <body-content>JSP</body-content>
+ <description>Clears input components when a returning flow modifies the underlying model.</description>
+
+ <attribute>
+ <name>outcome</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ <description>
+ The navigation outcome which triggered the flow call.
+ </description>
+ </attribute>
+ <attribute>
+ <name>target</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ <description>
+ The id of the input component to clear. Either this should be set, OR this component
+ should have child components.
+ </description>
+ </attribute>
+ </tag>
</taglib>