You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/06/25 19:51:24 UTC
svn commit: r1139578 - in /myfaces/core/trunk/impl/src:
main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java
Author: lu4242
Date: Sat Jun 25 17:51:24 2011
New Revision: 1139578
URL: http://svn.apache.org/viewvc?rev=1139578&view=rev
Log:
MYFACES-3186 ui:repeat can lose dynamically added grandchild components
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java?rev=1139578&r1=1139577&r2=1139578&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java Sat Jun 25 17:51:24 2011
@@ -101,6 +101,8 @@ public class UIRepeat extends UIComponen
private transient Object _origValue;
private transient Object _origVarStatus;
+ private transient FacesContext _facesContext;
+
public UIRepeat()
{
setRendererType("facelets.ui.Repeat");
@@ -661,88 +663,155 @@ public class UIRepeat extends UIComponen
}
@Override
- public boolean invokeOnComponent(FacesContext faces, String clientId,
+ public boolean invokeOnComponent(FacesContext context, String clientId,
ContextCallback callback) throws FacesException
{
+ if (context == null || clientId == null || callback == null)
+ {
+ throw new NullPointerException();
+ }
- // get the index-less clientId
- pushComponentToEL(faces, this);
+ final String baseClientId = getClientId(context);
+
+ // searching for this component?
+ boolean returnValue = baseClientId.equals(clientId);
+
+ boolean isCachedFacesContext = isTemporalFacesContext();
+ if (!isCachedFacesContext)
+ {
+ setTemporalFacesContext(context);
+ }
+
+ pushComponentToEL(context, this);
try
{
- String indexLessId = getClientId(faces);
- if (clientId.startsWith(indexLessId))
+ if (returnValue)
{
- // the index for which the component should be invoked
- int invokeIndex = -1;
-
- // try to get the invokeIndex out of the given clientId.
- // Note that the clientId of UIRepeat contains the current index,
- // if the index is >= 0 (see getContainerClientId()).
- int idxStart = clientId.indexOf(UINamingContainer.getSeparatorChar(faces),
- indexLessId.length());
- if (idxStart != -1 && Character.isDigit(clientId.charAt(idxStart + 1)))
+ try
{
- int idxEnd = clientId.indexOf(UINamingContainer.getSeparatorChar(faces), idxStart + 1);
- if (idxEnd != -1)
- {
- invokeIndex = Integer.parseInt(clientId.substring(idxStart + 1, idxEnd));
- }
+ callback.invokeContextCallback(context, this);
+ return true;
}
-
- // safe the current index, count aside
- final int prevIndex = _index;
- final int prevCount = _count;
-
- try
+ catch (Exception e)
{
- // save the current scope values and set the right index
- _captureScopeValues();
- if (invokeIndex != -1)
- {
- // calculate count for RepeatStatus
- _count = _calculateCountForIndex(invokeIndex);
- }
- _setIndex(invokeIndex);
+ throw new FacesException(e);
+ }
+ }
+
+ // Now Look throught facets on this UIComponent
+ if (this.getFacetCount() > 0)
+ {
+ for (Iterator<UIComponent> it = this.getFacets().values().iterator(); !returnValue && it.hasNext();)
+ {
+ returnValue = it.next().invokeOnComponent(context, clientId, callback);
+ }
+ }
+
+ if (returnValue)
+ {
+ return returnValue;
+ }
+
+ // is the component an inner component?
+ if (clientId.startsWith(baseClientId))
+ {
+ // Check if the clientId for the component, which we
+ // are looking for, has a rowIndex attached
+ char separator = UINamingContainer.getSeparatorChar(context);
+ String subId = clientId.substring(baseClientId.length() + 1);
+ //If the char next to baseClientId is the separator one and
+ //the subId matches the regular expression
+ if (clientId.charAt(baseClientId.length()) == separator &&
+ subId.matches("[0-9]+"+separator+".*"))
+ {
+ String clientRow = subId.substring(0, subId.indexOf(separator));
+
+ // safe the current index, count aside
+ final int prevIndex = _index;
+ final int prevCount = _count;
- if (_isIndexAvailable())
- {
- return super.invokeOnComponent(faces, clientId, callback);
- }
- else if (clientId.equals(indexLessId))
+ try
{
- // the only proper case for invokeIndex == -1 (Note that for
- // a invokeIndex of -1 we must not invoke our children or facets)
- callback.invokeContextCallback(faces, this);
- return true;
+ int invokeIndex = Integer.parseInt(clientRow);
+ // save the current scope values and set the right index
+ _captureScopeValues();
+ if (invokeIndex != -1)
+ {
+ // calculate count for RepeatStatus
+ _count = _calculateCountForIndex(invokeIndex);
+ }
+ _setIndex(invokeIndex);
+
+ if (!_isIndexAvailable())
+ {
+ return false;
+ }
+
+ for (Iterator<UIComponent> it1 = getChildren().iterator();
+ !returnValue && it1.hasNext();)
+ {
+ //recursive call to find the component
+ returnValue = it1.next().invokeOnComponent(context, clientId, callback);
+ }
}
- else
+ finally
{
- // most likely no valid clientId
- return false;
+ // restore the previous count, index and scope values
+ _count = prevCount;
+ _setIndex(prevIndex);
+ _restoreScopeValues();
}
}
- finally
+ else
{
- // restore the previous count, index and scope values
- _count = prevCount;
- _setIndex(prevIndex);
- _restoreScopeValues();
+ // Searching for this component's children
+ if (this.getChildCount() > 0)
+ {
+ // Searching for this component's children/facets
+ for (Iterator<UIComponent> it = this.getChildren().iterator(); !returnValue && it.hasNext();) {
+ returnValue = it.next().invokeOnComponent(context, clientId, callback);
+ }
+ }
}
}
- else
- {
- // the clientId does not match to this component or one of its children
- return false;
- }
}
finally
{
//all components must call popComponentFromEl after visiting is finished
- popComponentFromEL(faces);
+ popComponentFromEL(context);
+ if (!isCachedFacesContext)
+ {
+ setTemporalFacesContext(null);
+ }
}
+
+ return returnValue;
}
@Override
+ protected FacesContext getFacesContext()
+ {
+ if (_facesContext == null)
+ {
+ return super.getFacesContext();
+ }
+ else
+ {
+ return _facesContext;
+ }
+ }
+
+ private boolean isTemporalFacesContext()
+ {
+ return _facesContext != null;
+ }
+
+ private void setTemporalFacesContext(FacesContext facesContext)
+ {
+ _facesContext = facesContext;
+ }
+
+ @Override
public boolean visitTree(VisitContext context, VisitCallback callback)
{
// override the behavior from UIComponent to visit
Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java?rev=1139578&r1=1139577&r2=1139578&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/ui/RepeatTestCase.java Sat Jun 25 17:51:24 2011
@@ -139,7 +139,7 @@ public class RepeatTestCase extends Face
// invokeOnComponent on a child of UIRepeat with invalid row (-1)
invokeId = "form:repeat:outputText";
- Assert.assertFalse(root.invokeOnComponent(facesContext, invokeId, callback));
+ Assert.assertTrue(root.invokeOnComponent(facesContext, invokeId, callback));
// after all these calls to invokeOnComponent, row and status still
// have to be the same like before