Author: nbelaevski
Date: 2010-04-16 10:13:24 -0400 (Fri, 16 Apr 2010)
New Revision: 16767
Added:
root/framework/trunk/impl/src/main/java/org/richfaces/context/IdTreeNode.java
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExtendedPartialVisitContext.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/IdParser.java
root/framework/trunk/impl/src/test/java/org/richfaces/context/ExtendedPartialVisitContextTest.java
root/framework/trunk/impl/src/test/java/org/richfaces/context/IdParserTest.java
Log:
https://jira.jboss.org/jira/browse/RF-7856
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -21,6 +21,26 @@
package org.ajax4jsf.renderkit;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.PartialResponseWriter;
+import javax.faces.context.ResponseWriter;
+import javax.servlet.http.HttpServletResponse;
+
import org.ajax4jsf.Messages;
import org.ajax4jsf.component.AjaxClientBehavior;
import org.ajax4jsf.component.AjaxComponent;
@@ -36,25 +56,6 @@
import org.richfaces.log.RichfacesLogger;
import org.slf4j.Logger;
-import javax.faces.component.NamingContainer;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.context.PartialResponseWriter;
-import javax.faces.context.ResponseWriter;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
/**
* @author shura
* <p/>
@@ -346,7 +347,7 @@
// public static AjaxEventOptions buildEventOptions(FacesContext facesContext,
// UIComponent uiComponent, Map<String, Object> params) {
-//
+//
// return buildEventOptions(facesContext, uiComponent, params, false);
// }
@@ -396,7 +397,7 @@
// controlValue = clientId;
// parameters.put(controlName, controlValue);
// AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
-//
+//
// String ajaxActionURL = ajaxContext.getAjaxActionURL(facesContext);
// if (omitDefaultActionUrl) {
// UIComponent form = getNestingForm(uiComponent);
@@ -409,19 +410,19 @@
//
// if (ajaxActionURL != null) {
// // Setup action URL. For portlet environment, it will be different from
-// // page.
+// // page.
// options.put("actionUrl", ajaxActionURL);
// }
-//
+//
// // Add application-wide Ajax parameters
// parameters.putAll(ajaxContext.getCommonAjaxParameters());
// // add child parameters
// appendParameters(facesContext, uiComponent, parameters);
-//
+//
// if (params != null) {
// parameters.putAll(params);
// }
-//
+//
// if (!parameters.isEmpty()) {
// options.put("parameters", parameters);
// }
@@ -447,20 +448,20 @@
// if (null != oncomplete) {
// options.put(ONCOMPLETE_ATTR_NAME, buildAjaxOncomplete(oncomplete));
// }
-//
+//
// String beforeupdate = getAjaxOnBeforeDomUpdate(uiComponent);
// if (null != beforeupdate) {
// options.put(ONBEFOREDOMUPDATE_ATTR_NAME,
buildAjaxOnBeforeDomUpdate(beforeupdate));
// }
-//
-//
+//
+//
// String status = getAjaxStatus(uiComponent);
// if (null != status) {
// options.put("status", status);
// }
// String queue = (String) componentAttributes.get(AJAX_QUEUE_ATTR);
// String implicitQueue = null;
-//
+//
// Integer requestDelay = (Integer) componentAttributes
// .get(AJAX_DELAY_ATTR);
// if (null != requestDelay && requestDelay.intValue() > 0) {
@@ -489,14 +490,14 @@
// if (namespace != null && namespace.length() != 0) {
// options.put("namespace", namespace);
// }
-//
+//
// String similarityGroupingId = (String)
componentAttributes.get(SIMILARITY_GROUPING_ID_ATTR);
// if (similarityGroupingId == null || similarityGroupingId.length() == 0) {
// similarityGroupingId = clientId;
// } else {
// similarityGroupingId =
externalContext.encodeNamespace(similarityGroupingId);
// }
-//
+//
// options.put(SIMILARITY_GROUPING_ID_ATTR, similarityGroupingId);
//
// // request timeout.
@@ -513,7 +514,7 @@
// }
// /**
// * Create call to Ajax Submit function with first two parameters
-// *
+// *
// * @param uiComponent
// * @param facesContext
// * @param functionName
@@ -655,12 +656,21 @@
}
/**
+ * Split parameter string into array of strings.
+ * @param valuesSet
+ * @return
+ */
+ public static String[] asArray(String valuesSet) {
+ return valuesSet.trim().split("(\\s*,\\s*)|(\\s+)");
+ }
+
+ /**
* Convert parameter ( Collection, List, array, String, comma-separated
- * String ) to list of srings.
+ * String, whitespace-separate String) to set of strings.
*
* @param valueToSet -
- * obect for convert to List.
- * @return - list of strings.
+ * object for conversion to Set.
+ * @return - set of strings.
*/
@SuppressWarnings("unchecked")
public static Set<String> asSet(Object valueToSet) {
@@ -677,7 +687,13 @@
String areasString = ((String) valueToSet).trim();
if (areasString.contains(",") || areasString.contains("
")) {
- return new
LinkedHashSet<String>(Arrays.asList(areasString.split("(\\s*,\\s*)|(\\s+)")));
+ String[] values = asArray(areasString);
+ Set<String> result = new
LinkedHashSet<String>(values.length);
+ for (String value : values) {
+ result.add(value);
+ }
+
+ return result;
} else {
Set<String> areasSet = new LinkedHashSet<String>(5);
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -1003,8 +1003,11 @@
result.add(convertedId);
}
} else {
+ //TODO - review
LOGGER.warn(
MessageFormat.format("''{0}'' cannot
be resolved in the current context", id));
+
+ result.add(id);
}
}
}
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -160,6 +160,21 @@
return null;
}
+ public ComponentMatcherNode getOrCreateChild(String key, boolean isPatternNode) {
+ Map<String, ComponentMatcherNode> childrenMap =
getOrCreateChildrenMap(isPatternNode);
+ ComponentMatcherNode childNode = childrenMap.get(key);
+ if (childNode == null) {
+ childNode = new ComponentMatcherNode();
+
+ childNode.setPatternNode(isPatternNode);
+ childNode.setSource(key);
+
+ addChild(childNode);
+ }
+
+ return childNode;
+ }
+
public void addChild(ComponentMatcherNode child) {
child.setParentNode(this);
@@ -176,9 +191,11 @@
incrementKidPatternNodesCounter();
}
- if (isPatternNode() || this.hasParentPatternNode()) {
+ if (hasPatternNodeInChain()) {
child.setHasParentPatternNode(true);
}
+
+ addAllSubtreeIds(child.getSubtreeIds());
}
public void removeChild(ComponentMatcherNode child) {
@@ -192,6 +209,8 @@
if (child.isPatternNode() || child.hasKidPatternNodes()) {
decrementKidPatternNodesCounter();
}
+
+ removeAllSubtreeIds(child.getSubtreeIds());
} else {
//TODO - ?
}
@@ -230,22 +249,60 @@
return hasParentPatternNode;
}
+ public boolean hasPatternNodeInChain() {
+ return isPatternNode() || hasParentPatternNode();
+ }
+
public Collection<String> getSubtreeIds() {
return subtreeIds;
}
+ public void addAllSubtreeIds(Collection<String> ids) {
+ if (ids != null) {
+ if (subtreeIds == null) {
+ subtreeIds = new HashSet<String>();
+ }
+
+ subtreeIds.addAll(ids);
+
+ if (parentNode != null) {
+ parentNode.addAllSubtreeIds(ids);
+ }
+ }
+ }
+
public void addSubtreeId(String subtreeId) {
if (subtreeIds == null) {
subtreeIds = new HashSet<String>();
}
subtreeIds.add(subtreeId);
+
+ if (parentNode != null) {
+ parentNode.addSubtreeId(subtreeId);
+ }
}
+ public void removeAllSubtreeIds(Collection<String> ids) {
+ if (ids != null) {
+ if (subtreeIds != null) {
+ subtreeIds.removeAll(ids);
+ }
+
+ if (parentNode != null) {
+ parentNode.removeAllSubtreeIds(ids);
+ }
+ }
+ }
+
public void removeSubtreeId(String subtreeId) {
if (subtreeIds != null) {
subtreeIds.remove(subtreeId);
}
+
+ if (parentNode != null) {
+ parentNode.removeSubtreeId(subtreeId);
+ }
}
public Map<String, ComponentMatcherNode> getIdChildren() {
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExtendedPartialVisitContext.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExtendedPartialVisitContext.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExtendedPartialVisitContext.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -120,6 +121,72 @@
}
}
+ private interface NodeOperationCommand {
+
+ public ComponentMatcherNode getNextNode(ComponentMatcherNode currentNode, String
nodeId, boolean isPattern);
+
+ public boolean processLastNode(ComponentMatcherNode lastNode, String fullId);
+ }
+
+ private NodeOperationCommand addNodeOperation = new NodeOperationCommand() {
+
+ public boolean processLastNode(ComponentMatcherNode lastNode, String fullId) {
+ if (!directNodesMap.containsKey(fullId)) {
+ directNodesMap.put(fullId, lastNode);
+ lastNode.markAdded();
+
+ ComponentMatcherNode n = lastNode;
+ int addedSegmentsCount = 0;
+ while (n != null && addedSegmentsCount <
SHORT_ID_IN_CLIENTID_SEGMENTS_NUMBER) {
+ if (!n.isPatternNode()) {
+ String shortId = n.getSource();
+ if (shortId != null) {
+ addedSegmentsCount++;
+ //TODO filter meta component ids
+ shortIds.add(shortId);
+ }
+ }
+
+ n = n.getParentNode();
+ }
+
+ if (!lastNode.hasPatternNodeInChain()) {
+ lastNode.addSubtreeId(fullId);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public ComponentMatcherNode getNextNode(ComponentMatcherNode currentNode, String
nodeId, boolean isPattern) {
+ return currentNode.getOrCreateChild(nodeId, isPattern);
+ }
+ };
+
+ private NodeOperationCommand removeNodeOperation = new NodeOperationCommand() {
+
+ public boolean processLastNode(ComponentMatcherNode lastNode, String fullId) {
+ ComponentMatcherNode node = directNodesMap.remove(fullId);
+ if (node != null) {
+ if (!node.hasPatternNodeInChain()) {
+ node.removeSubtreeId(fullId);
+ }
+
+ removeNode(node);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public ComponentMatcherNode getNextNode(ComponentMatcherNode currentNode, String
nodeId, boolean isPattern) {
+ return currentNode.getChild(nodeId, isPattern);
+ }
+ };
+
private IdParser idParser;
private boolean limitRender;
@@ -179,7 +246,7 @@
this.limitRender = limitRender;
}
- private IdParser getIdParser(String id) {
+ private IdParser setupIdParser(String id) {
if (idParser == null) {
idParser = new
IdParser(UINamingContainer.getSeparatorChar(getFacesContext()),
META_COMPONENT_SEPARATOR_CHAR);
@@ -190,47 +257,22 @@
return idParser;
}
- private ComponentMatcherNode createNode(String patternId) {
+ private ComponentMatcherNode findMatchingNode(String clientId) {
ComponentMatcherNode node = rootNode;
- IdParser idParser = getIdParser(patternId);
+ IdParser idParser = setupIdParser(clientId);
- String idSegment;
- while ((idSegment = idParser.nextSegment()) != null) {
- boolean isPattern = ANY_WILDCARD.equals(idSegment);
- ComponentMatcherNode child = node.getChild(idSegment, isPattern);
- if (child == null) {
- child = new ComponentMatcherNode();
+ while (node != null && idParser.findNext()) {
+ String componentId = idParser.getComponentId();
+ String metadataComponentId = idParser.getMetadataComponentId();
- child.setPatternNode(isPattern);
- child.setSource(idSegment);
-
- node.addChild(child);
- }
-
- node = child;
- }
-
- node.markAdded();
-
- return node;
- }
-
- private ComponentMatcherNode findMatchingNode(String clientId) {
- ComponentMatcherNode node = rootNode;
-
- IdParser idParser = getIdParser(clientId);
-
- while (node != null) {
- String idSegment = idParser.nextSegment();
- if (idSegment != null) {
- if (idParser.containsSubComponentSeparator()) {
- node = node.getChild(idSegment, false);
- } else {
- node = node.getMatchedChild(idSegment);
+ if (metadataComponentId != null) {
+ node = node.getChild(componentId, false);
+ if (node != null) {
+ node = node.getChild(metadataComponentId, false);
}
} else {
- break;
+ node = node.getMatchedChild(componentId);
}
}
@@ -262,77 +304,82 @@
}
}
- private boolean addNode(String patternId) {
- ComponentMatcherNode node = directNodesMap.get(patternId);
- if (node == null) {
- node = createNode(patternId);
- directNodesMap.put(patternId, node);
+ private boolean invokeNodeOperation(NodeOperationCommand command,
ComponentMatcherNode currentNode,
+ IdTreeNode idTreeNode, StringBuilder sb) {
- ComponentMatcherNode n = node;
- int addedSegmentsCount = 0;
- while (n != null && addedSegmentsCount !=
SHORT_ID_IN_CLIENTID_SEGMENTS_NUMBER) {
- if (!n.isPatternNode()) {
- String shortId = n.getSource();
- if (shortId != null) {
- int sepIdx = shortId.indexOf(META_COMPONENT_SEPARATOR_CHAR);
- if (sepIdx > 0) {
- shortId = shortId.substring(0, sepIdx);
- }
+ String componentId = idTreeNode.getComponentId();
+ String metadataComponentId = idTreeNode.getMetadataComponentId();
- addedSegmentsCount++;
- shortIds.add(shortId);
- }
- }
+ ComponentMatcherNode nextNode;
- n = n.getParentNode();
+ if (metadataComponentId != null) {
+ nextNode = command.getNextNode(currentNode, componentId, false);
+ if (nextNode != null) {
+ nextNode = command.getNextNode(nextNode, metadataComponentId, false);
}
+ } else {
+ boolean isPattern = ANY_WILDCARD.equals(componentId);
+ nextNode = command.getNextNode(currentNode, componentId, isPattern);
+ }
- n = node;
- if (!n.hasParentPatternNode()) {
- n = n.getParentNode();
+ boolean result = false;
- while (n != null) {
- ComponentMatcherNode pNode = n.getParentNode();
- if (pNode != null) {
- n.addSubtreeId(patternId);
- }
+ if (nextNode != null) {
+ final int bufferLength = sb.length();
+ if (bufferLength != 0) {
+ //TODO replace with constant
+ sb.append(':');
+ }
+ sb.append(componentId);
- n = pNode;
+ List<IdTreeNode> idTreeChildNodes = idTreeNode.getChildNodes();
+ if (idTreeChildNodes != null) {
+ final int newBufferLength = sb.length();
+
+ for (IdTreeNode idTreeChildNode : idTreeChildNodes) {
+ result |= invokeNodeOperation(command, nextNode, idTreeChildNode,
sb);
+
+ sb.setLength(newBufferLength);
}
+ } else {
+ result |= command.processLastNode(nextNode, sb.toString());
}
-
- return true;
+ sb.setLength(bufferLength);
}
- return false;
+ return result;
}
- private boolean removeNode(String patternId) {
- ComponentMatcherNode node = directNodesMap.remove(patternId);
- if (node != null) {
- ComponentMatcherNode n = node;
- if (!n.hasParentPatternNode()) {
- n = n.getParentNode();
+ private boolean invokeRootNodeOperation(NodeOperationCommand command, IdTreeNode
idTreeNode) {
+ boolean result = false;
- while (n != null) {
- ComponentMatcherNode pNode = n.getParentNode();
- if (pNode != null) {
- n.removeSubtreeId(patternId);
- }
+ List<IdTreeNode> idTreeChildNodes = idTreeNode.getChildNodes();
+ if (idTreeChildNodes != null) {
+ StringBuilder sb = new StringBuilder();
- n = pNode;
- }
+ for (IdTreeNode idTreeChildNode : idTreeChildNodes) {
+ result |= invokeNodeOperation(command, rootNode, idTreeChildNode, sb);
}
+ }
- removeNode(node);
+ return result;
+ }
- return true;
- }
+ private boolean addNode(String patternId) {
+ IdTreeNode idTreeNode = new IdTreeNode();
+ idTreeNode.appendNodesFromParser(setupIdParser(patternId));
- return false;
+ return invokeRootNodeOperation(addNodeOperation, idTreeNode);
}
+ private boolean removeNode(String patternId) {
+ IdTreeNode idTreeNode = new IdTreeNode();
+ idTreeNode.appendNodesFromParser(setupIdParser(patternId));
+
+ return invokeRootNodeOperation(removeNodeOperation, idTreeNode);
+ }
+
/**
* @see VisitContext#getHints VisitContext.getHints
*/
@@ -371,25 +418,31 @@
String clientId = buildExtendedClientId(component);
ComponentMatcherNode node = findMatchingNode(clientId);
+
+ Collection<String> result = null;
+
+
if (node != null) {
if (node.hasKidPatternNodes()) {
- return VisitContext.ALL_IDS;
+ result = VisitContext.ALL_IDS;
} else {
Collection<String> subtreeIds = node.getSubtreeIds();
if (subtreeIds != null) {
- return Collections.unmodifiableCollection(subtreeIds);
+ result = Collections.unmodifiableCollection(subtreeIds);
} else {
//TODO nick - this code addresses the case of parent pattern nodes,
and can be optimized
if (node.hasDirectIdChildren()) {
- return VisitContext.ALL_IDS;
+ result = VisitContext.ALL_IDS;
} else {
- return Collections.emptySet();
+ result = Collections.emptySet();
}
}
}
+ } else {
+ result = Collections.emptySet();
}
- return Collections.emptySet();
+ return result;
}
public Collection<String>getDirectSubtreeIdsToVisit(UIComponent component) {
Modified: root/framework/trunk/impl/src/main/java/org/richfaces/context/IdParser.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/richfaces/context/IdParser.java 2010-04-16
10:31:58 UTC (rev 16766)
+++ root/framework/trunk/impl/src/main/java/org/richfaces/context/IdParser.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -28,134 +28,98 @@
*/
final class IdParser {
- private boolean isInShortId = true;
-
private String id;
- private int start;
+ private String componentId;
+ private String metadataComponentId;
+
private int idx;
- private boolean containsSubComponentSeparator;
-
private final char namingContainerSeparator;
private final char subComponentSeparator;
public IdParser(char namingContainerSeparator, char subComponentSeparator) {
super();
+
this.namingContainerSeparator = namingContainerSeparator;
this.subComponentSeparator = subComponentSeparator;
}
private void reset() {
this.id = null;
- this.start = 0;
+
+ this.componentId = null;
+ this.metadataComponentId = null;
+
this.idx = 0;
- this.containsSubComponentSeparator = false;
- this.isInShortId = true;
}
- /**
- * <p>
- * Finds shortId that satisfies the following conditions:
- * </p>
- *
- * <code>
- * nextIdx(c) := { return id.indexOf(c, idx) }
- * </code>
+ public void setId(String id) {
+ reset();
+ this.id = id;
+ }
- * <p></p>
- *
- * <code>
- * shortId := id.substring(idx, Math.min(nextIdx(namingContainerSeparator),
nextIdx(subComponentSeparator)))
- * </code>
- *
- * @return
- */
- private String findNextInShortId() {
- String segment = null;
- boolean found = false;
+ public boolean findNext() {
+ componentId = null;
+ metadataComponentId = null;
- for (int index = idx; !found && index < id.length(); index++) {
- char c = id.charAt(index);
- if (c == subComponentSeparator) {
- segment = id.substring(start, index);
- idx = index + 1;
- isInShortId = false;
- found = true;
- } else if (c == namingContainerSeparator) {
- segment = id.substring(start, index);
- idx = index + 1;
- start = idx;
- found = true;
- }
+ if (id == null) {
+ return false;
}
- if (!found) {
- segment = id.substring(start);
- this.id = null;
- }
+ int idLength = id.length();
- return segment;
- }
+ if (idx < idLength) {
+ boolean foundSeparator = false;
- /**
- * <p>
- * Finds fullId that satisfies the following conditions:
- * </p>
- *
- * <code>
- * nextIdx(c) := { return id.indexOf(c, idx) }
- * </code>
+ for (int i = idx; i < idLength && !foundSeparator; i++) {
+ char c = id.charAt(i);
- * <p></p>
- *
- * <code>
- * fullId := id.substring(idx, nextIdx(namingContainerSeparator))
- * </code>
- * @return
- */
- private String findNextInFullId() {
- String segment = null;
- int index = id.indexOf(namingContainerSeparator, idx);
- if (index < 0) {
- segment = id.substring(start);
- this.id = null;
- } else {
- segment = id.substring(start, index);
- isInShortId = true;
- idx = index + 1;
- start = idx;
- }
+ if (c == subComponentSeparator) {
+ if (componentId == null) {
+ componentId = id.substring(idx, i);
+ }
+ } else if (c == namingContainerSeparator) {
+ String idSegment = id.substring(idx, i);
- return segment;
- }
+ if (componentId == null) {
+ componentId = idSegment;
+ } else {
+ metadataComponentId = idSegment;
+ }
- public void setId(String id) {
- reset();
- this.id = id;
- }
+ idx = i + 1;
+ foundSeparator = true;
+ }
+ }
- public String nextSegment() {
- if (this.id == null) {
- reset();
- return null;
- }
+ if (!foundSeparator) {
+ String idSegment = id.substring(idx, idLength);
- containsSubComponentSeparator = !isInShortId;
+ if (componentId == null) {
+ componentId = idSegment;
+ } else {
+ metadataComponentId = idSegment;
+ }
- String segment = null;
- if (isInShortId) {
- segment = findNextInShortId();
+ idx = idLength;
+ }
+
+ return true;
} else {
- segment = findNextInFullId();
+ reset();
+ return false;
}
+ }
- return segment;
+ public String getComponentId() {
+ return componentId;
}
- public boolean containsSubComponentSeparator() {
- return containsSubComponentSeparator;
+ public String getMetadataComponentId() {
+ return metadataComponentId;
}
+
}
\ No newline at end of file
Added: root/framework/trunk/impl/src/main/java/org/richfaces/context/IdTreeNode.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/richfaces/context/IdTreeNode.java
(rev 0)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/IdTreeNode.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -0,0 +1,155 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.richfaces.context;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+
+final class IdTreeNode {
+
+ private static final char LIST_OPENING_CHAR = '[';
+
+ private static final char LIST_CLOSING_CHAR = ']';
+
+ private String componentId;
+
+ private String metadataComponentId;
+
+ private List<IdTreeNode> childNodes;
+
+ private IdTreeNode(String componentId, String metadataComponentId) {
+ this.componentId = componentId;
+ this.metadataComponentId = metadataComponentId;
+ }
+
+ public IdTreeNode() {
+ this(null, null);
+ }
+
+ private void setChildNodes(String[] componentIds) {
+ childNodes = new ArrayList<IdTreeNode>(componentIds.length);
+ for (String componentId : componentIds) {
+ childNodes.add(new IdTreeNode(componentId, null));
+ }
+ }
+
+ private void setChildNode(String componentId, String metadataComponentId) {
+ childNodes = Collections.singletonList(new IdTreeNode(componentId,
metadataComponentId));
+ }
+
+ private void appendToStringBuilder(StringBuilder sb, int indentLevel) {
+ for (int i = 0; i < indentLevel; i++) {
+ sb.append(' ');
+ }
+ sb.append('+');
+
+ if (componentId != null) {
+ sb.append(componentId);
+
+ if (metadataComponentId != null) {
+ sb.append('(');
+ sb.append(metadataComponentId);
+ sb.append(')');
+ }
+
+ } else {
+ sb.append("<empty>");
+ }
+
+ sb.append('\n');
+
+ if (childNodes != null) {
+ for (IdTreeNode childNode : childNodes) {
+ childNode.appendToStringBuilder(sb, indentLevel + 2);
+ }
+ }
+ }
+
+ public void appendNodesFromParser(IdParser idParser) {
+ List<IdTreeNode> nodes = Collections.singletonList(this);
+
+ while (idParser.findNext()) {
+ String componentId = idParser.getComponentId();
+ String metadataComponentId = idParser.getMetadataComponentId();
+
+ int childNodesCount = 0;
+
+ if (metadataComponentId != null) {
+ for (IdTreeNode node : nodes) {
+ node.setChildNode(componentId, metadataComponentId);
+ childNodesCount++;
+ }
+ } else {
+ if (componentId.length() > 2 && componentId.charAt(0) ==
LIST_OPENING_CHAR &&
+ componentId.charAt(componentId.length() - 1) == LIST_CLOSING_CHAR) {
+
+ String[] split = AjaxRendererUtils.asArray(componentId.substring(1,
componentId.length() - 1));
+ for (IdTreeNode node : nodes) {
+ node.setChildNodes(split);
+ childNodesCount += split.length;
+ }
+ } else {
+ for (IdTreeNode node : nodes) {
+ node.setChildNode(componentId, null);
+ childNodesCount++;
+ }
+ }
+ }
+
+ List<IdTreeNode> newNodesList;
+ if (nodes.size() == 1) {
+ newNodesList = nodes.get(0).getChildNodes();
+ } else {
+ newNodesList = new ArrayList<IdTreeNode>(childNodesCount);
+ for (IdTreeNode node : nodes) {
+ newNodesList.addAll(node.getChildNodes());
+ }
+ }
+
+ nodes = newNodesList;
+ }
+ }
+
+ public List<IdTreeNode> getChildNodes() {
+ return childNodes;
+ }
+
+ public String getComponentId() {
+ return componentId;
+ }
+
+ public String getMetadataComponentId() {
+ return metadataComponentId;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ appendToStringBuilder(sb, 0);
+
+ return sb.toString();
+ }
+}
Modified:
root/framework/trunk/impl/src/test/java/org/richfaces/context/ExtendedPartialVisitContextTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/context/ExtendedPartialVisitContextTest.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/context/ExtendedPartialVisitContextTest.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -314,7 +314,7 @@
}
private void createView() {
- viewRoot = (UIViewRoot) application.createComponent(UIViewRoot.COMPONENT_TYPE);
+ viewRoot = facesContext.getViewRoot();
createForm();
}
@@ -715,5 +715,38 @@
assertEquals(Arrays.asList(), trackingVisitCallback.getVisitedIds());
}
+
+ @Test
+ public void testVisitMultiple() throws Exception {
+ createVisitContext(true);
+
+ renderingContext.getIdsToVisit().add("myForm:table:[ 0, 1 ]:nestedTable:[ 1
]:nestedTableText");
+ boolean visitResult = viewRoot.visitTree(renderingContext,
trackingVisitCallback);
+ assertTrue(visitResult);
+
+
assertEquals(Arrays.asList("myForm:table:0:nestedTable:1:nestedTableText",
+ "myForm:table:1:nestedTable:1:nestedTableText"),
trackingVisitCallback.getVisitedIds());
+ }
+
+ @Test
+ public void testVisitMultipleWithPatternAndMetacomponent() throws Exception {
+ createVisitContext(true);
+
+ renderingContext.getIdsToVisit().add("myForm:table:[ 0, 1
]:nestedTable:*:nestedTableText");
+
renderingContext.getIdsToVisit().add("myForm:table:[0]:nestedTable@footer");
+
+ viewRoot.visitTree(renderingContext, trackingVisitCallback);
+
+ assertEquals(Arrays.asList(
+ "myForm:table:0:nestedTable@footer",
+ "myForm:table:0:nestedTable:0:nestedTableText",
+ "myForm:table:0:nestedTable:1:nestedTableText",
+ "myForm:table:0:nestedTable:2:nestedTableText",
+
+ "myForm:table:1:nestedTable:0:nestedTableText",
+ "myForm:table:1:nestedTable:1:nestedTableText",
+ "myForm:table:1:nestedTable:2:nestedTableText"
+ ), trackingVisitCallback.getVisitedIds());
+ }
}
Modified: root/framework/trunk/impl/src/test/java/org/richfaces/context/IdParserTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/richfaces/context/IdParserTest.java 2010-04-16
10:31:58 UTC (rev 16766)
+++
root/framework/trunk/impl/src/test/java/org/richfaces/context/IdParserTest.java 2010-04-16
14:13:24 UTC (rev 16767)
@@ -50,121 +50,114 @@
}
@Test
- public void testEmptyString() throws Exception {
+ public void testIncorrectIds() throws Exception {
idParser.setId("");
- String segment;
+ idParser.findNext();
+ assertFalse(idParser.findNext());
- segment = idParser.nextSegment();
- assertEquals("", segment);
- assertFalse(idParser.containsSubComponentSeparator());
- assertNull(idParser.nextSegment());
+ idParser.setId(":test");
+
+ idParser.findNext();
+ idParser.findNext();
+ assertFalse(idParser.findNext());
+
+ idParser.setId("test:");
+
+ idParser.findNext();
+ idParser.findNext();
+ assertFalse(idParser.findNext());
+
+ idParser.setId("@head");
+
+ idParser.findNext();
+ assertFalse(idParser.findNext());
+
+ idParser.setId("head@");
+
+ idParser.findNext();
+ assertFalse(idParser.findNext());
}
@Test
public void testSimpleId() throws Exception {
idParser.setId("simpleId");
- String segment;
+ assertTrue(idParser.findNext());
+ assertEquals("simpleId", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("simpleId", segment);
- assertFalse(idParser.containsSubComponentSeparator());
- assertNull(idParser.nextSegment());
+ assertFalse(idParser.findNext());
}
@Test
public void testSubComponentId() throws Exception {
idParser.setId("table@head");
- String segment;
+ assertTrue(idParser.findNext());
+ assertEquals("table@head", idParser.getMetadataComponentId());
+ assertEquals("table", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("table", segment);
- assertFalse(idParser.containsSubComponentSeparator());
-
- segment = idParser.nextSegment();
- assertEquals("table@head", segment);
- assertTrue(idParser.containsSubComponentSeparator());
-
- assertNull(idParser.nextSegment());
+ assertFalse(idParser.findNext());
}
@Test
public void testSeries() throws Exception {
idParser.setId("form:table:0:nestedTable@body");
- String segment;
+ assertTrue(idParser.findNext());
+ assertEquals("form", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("form", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("table", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("table", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("0", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("0", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("nestedTable@body", idParser.getMetadataComponentId());
+ assertEquals("nestedTable", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("nestedTable", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertFalse(idParser.findNext());
- segment = idParser.nextSegment();
- assertEquals("nestedTable@body", segment);
- assertTrue(idParser.containsSubComponentSeparator());
-
- assertNull(idParser.nextSegment());
-
idParser.setId("myBigTable@header");
- segment = idParser.nextSegment();
- assertEquals("myBigTable", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("myBigTable@header", idParser.getMetadataComponentId());
+ assertEquals("myBigTable", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("myBigTable@header", segment);
- assertTrue(idParser.containsSubComponentSeparator());
+ assertFalse(idParser.findNext());
- assertNull(idParser.nextSegment());
-
idParser.setId("tree:0-12-28:node@status:table:10:tab@label");
- segment = idParser.nextSegment();
- assertEquals("tree", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("tree", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("0-12-28", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("0-12-28", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("node", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("node@status", idParser.getMetadataComponentId());
+ assertEquals("node", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("node@status", segment);
- assertTrue(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("table", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("table", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("10", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("10", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("tab@label", idParser.getMetadataComponentId());
+ assertEquals("tab", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("tab", segment);
- assertFalse(idParser.containsSubComponentSeparator());
-
- segment = idParser.nextSegment();
- assertEquals("tab@label", segment);
- assertTrue(idParser.containsSubComponentSeparator());
-
- assertNull(idParser.nextSegment());
+ assertFalse(idParser.findNext());
}
@Test
@@ -173,24 +166,18 @@
idParser.setId("form:table@head@x-head:child");
- String segment;
+ assertTrue(idParser.findNext());
+ assertEquals("form", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("form", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("table@head@x-head", idParser.getMetadataComponentId());
+ assertEquals("table", idParser.getComponentId());
- segment = idParser.nextSegment();
- assertEquals("table", segment);
- assertFalse(idParser.containsSubComponentSeparator());
+ assertTrue(idParser.findNext());
+ assertEquals("child", idParser.getComponentId());
+ assertNull(idParser.getMetadataComponentId());
- segment = idParser.nextSegment();
- assertEquals("table@head@x-head", segment);
- assertTrue(idParser.containsSubComponentSeparator());
-
- segment = idParser.nextSegment();
- assertEquals("child", segment);
- assertFalse(idParser.containsSubComponentSeparator());
-
- assertNull(idParser.nextSegment());
+ assertFalse(idParser.findNext());
}
}