Author: nbelaevski
Date: 2010-04-20 11:13:08 -0400 (Tue, 20 Apr 2010)
New Revision: 16775
Added:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/IdSplitBuilder.java
root/framework/trunk/impl/src/test/java/org/ajax4jsf/renderkit/IdSplitBuilderTest.java
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java
Log:
https://jira.jboss.org/jira/browse/RF-7856
Added: root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/IdSplitBuilder.java
===================================================================
--- root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/IdSplitBuilder.java
(rev 0)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/IdSplitBuilder.java 2010-04-20
15:13:08 UTC (rev 16775)
@@ -0,0 +1,150 @@
+/*
+ * 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.ajax4jsf.renderkit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Nick Belaevski
+ */
+final class IdSplitBuilder {
+
+ private static final int INITIAL_SPLIT_LIST_SIZE = 3;
+
+ private enum State {
+ IN_ID (true) {
+
+ @Override
+ public State getNextState(char c) {
+ if (c == '[') {
+ return State.IN_ID_INSIDE_BRACKETS;
+ } else if (isSeparator(c)) {
+ return State.OUTSIDE_ID;
+ } else {
+ return this;
+ }
+ }
+ },
+ IN_ID_INSIDE_BRACKETS (true) {
+
+ @Override
+ public State getNextState(char c) {
+ if (c == ']') {
+ return State.IN_ID;
+ } else {
+ return this;
+ }
+ }
+ },
+ OUTSIDE_ID (false) {
+
+ @Override
+ public State getNextState(char c) {
+ if (!isSeparator(c)) {
+ if (c == '[') {
+ return State.IN_ID_INSIDE_BRACKETS;
+ } else {
+ return State.IN_ID;
+ }
+ }
+
+ return this;
+ }
+ };
+
+ private final boolean idSegment;
+
+ private State(boolean idSegment) {
+ this.idSegment = idSegment;
+ }
+
+ private static boolean isSeparator(char c) {
+ return c == ',' || Character.isWhitespace(c);
+ }
+
+ public abstract State getNextState(char c);
+
+ public boolean isIdSegment() {
+ return idSegment;
+ }
+
+ public void processChar(IdSplitBuilder builder, char c, int charIdx) {
+ State nextState = getNextState(c);
+
+ if (nextState.isIdSegment() ^ isIdSegment()) {
+ if (nextState.isIdSegment()) {
+ builder.setStartIndex(charIdx);
+ } else {
+ builder.flushBuilder(charIdx);
+ builder.setStartIndex(-1);
+ }
+ }
+
+ builder.state = nextState;
+ }
+ }
+
+ private int startIdx = -1;
+
+ private String sourceString;
+
+ private List<String> result = new
ArrayList<String>(INITIAL_SPLIT_LIST_SIZE);
+
+ private State state = State.OUTSIDE_ID;
+
+ private IdSplitBuilder(String sourceString) {
+ super();
+ this.sourceString = sourceString;
+ }
+
+ private void setStartIndex(int idx) {
+ startIdx = idx;
+ }
+
+ private void flushBuilder(int endIdx) {
+ if (startIdx >= 0 && endIdx > startIdx) {
+ String id = sourceString.substring(startIdx, endIdx);
+ result.add(id);
+ }
+ }
+
+ private void build() {
+ int length = sourceString.length();
+ for (int i = 0; i < length; i++) {
+ char c = sourceString.charAt(i);
+ state.processChar(this, c, i);
+ }
+ flushBuilder(length);
+ }
+
+ private String[] getSplit() {
+ return result.toArray(new String[result.size()]);
+ }
+
+ public static String[] split(String s) {
+ IdSplitBuilder splitBuilder = new IdSplitBuilder(s);
+ splitBuilder.build();
+ return splitBuilder.getSplit();
+ }
+
+}
\ No newline at end of file
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-20
15:05:30 UTC (rev 16774)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentMatcherNode.java 2010-04-20
15:13:08 UTC (rev 16775)
@@ -48,6 +48,14 @@
private Set<String> subtreeIds;
+ private static boolean isEmpty(Collection<?> c) {
+ return c == null || c.isEmpty();
+ }
+
+ private static boolean isEmpty(Map<?, ?> m) {
+ return m == null || m.isEmpty();
+ }
+
void setParentNode(ComponentMatcherNode parentNode) {
this.parentNode = parentNode;
}
@@ -222,11 +230,11 @@
}
public boolean hasDirectIdChildren() {
- return idChildren != null && !idChildren.isEmpty();
+ return !isEmpty(idChildren);
}
public boolean hasDirectPatternChildren() {
- return patternChildren != null && !patternChildren.isEmpty();
+ return !isEmpty(patternChildren);
}
public boolean hasKidPatternNodes() {
@@ -257,6 +265,10 @@
return subtreeIds;
}
+ public boolean hasSubtreeIds() {
+ return !isEmpty(subtreeIds);
+ }
+
public void addAllSubtreeIds(Collection<String> ids) {
if (ids != null) {
if (subtreeIds == null) {
Added:
root/framework/trunk/impl/src/test/java/org/ajax4jsf/renderkit/IdSplitBuilderTest.java
===================================================================
---
root/framework/trunk/impl/src/test/java/org/ajax4jsf/renderkit/IdSplitBuilderTest.java
(rev 0)
+++
root/framework/trunk/impl/src/test/java/org/ajax4jsf/renderkit/IdSplitBuilderTest.java 2010-04-20
15:13:08 UTC (rev 16775)
@@ -0,0 +1,80 @@
+/*
+ * 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.ajax4jsf.renderkit;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class IdSplitBuilderTest {
+
+ private static String[] asArray(String... strings) {
+ return strings;
+ }
+
+ @Test
+ public void testEmptyString() throws Exception {
+ assertArrayEquals(asArray(), IdSplitBuilder.split(""));
+ assertArrayEquals(asArray(), IdSplitBuilder.split(" \r\t\n "));
+ }
+
+ @Test
+ public void testOneStrings() throws Exception {
+ assertArrayEquals(asArray("test"),
IdSplitBuilder.split("test"));
+ assertArrayEquals(asArray("some:id"),
IdSplitBuilder.split("some:id"));
+ assertArrayEquals(asArray("table:[1]"),
IdSplitBuilder.split("table:[1]"));
+ assertArrayEquals(asArray("table:[1, 2]"),
IdSplitBuilder.split("table:[1, 2]"));
+ assertArrayEquals(asArray("table:[1, 2]:nestedTable:[*]"),
IdSplitBuilder.split("table:[1, 2]:nestedTable:[*]"));
+ assertArrayEquals(asArray("table:[1, 2]:[*]:group"),
IdSplitBuilder.split("table:[1, 2]:[*]:group"));
+ assertArrayEquals(asArray("table:[1 2]:nestedTable:[*]"),
IdSplitBuilder.split("table:[1 2]:nestedTable:[*]"));
+ assertArrayEquals(asArray("table:[1 2]:[*]:group"),
IdSplitBuilder.split("table:[1 2]:[*]:group"));
+ }
+
+ @Test
+ public void testTwoStrings() throws Exception {
+ assertArrayEquals(asArray("test", "abc"),
IdSplitBuilder.split("test abc"));
+ assertArrayEquals(asArray("some:id", "form:table"),
IdSplitBuilder.split("some:id form:table"));
+ assertArrayEquals(asArray("test", "abc"),
IdSplitBuilder.split("test, abc"));
+ assertArrayEquals(asArray("some:id", "form:table"),
IdSplitBuilder.split("some:id, form:table"));
+
+ assertArrayEquals(asArray("test:[1 2 3]:abc", "form:[2]"),
IdSplitBuilder.split("test:[1 2 3]:abc form:[2]"));
+ assertArrayEquals(asArray("[1 2]:some", "[3\t4]:id"),
IdSplitBuilder.split(" [1 2]:some [3\t4]:id "));
+ }
+
+ @Test
+ public void testSeveralStrings() throws Exception {
+ assertArrayEquals(asArray("test", "abc", "def",
"ghi"), IdSplitBuilder.split("test abc def ghi"));
+ assertArrayEquals(asArray("test:[1 2]abc", "def",
"ghi"), IdSplitBuilder.split("test:[1 2]abc def ghi"));
+ assertArrayEquals(asArray("[1 2]abc", "[3, 4]def",
"ghi[5 6 7]"),
+ IdSplitBuilder.split("[1 2]abc [3, 4]def ghi[5 6 7]"));
+
+ assertArrayEquals(
+ asArray("test:[1 2]:abc", "table", "form:table:[ *
]:child", "extTable:[ 0, 3 ]:child:[1 8]:@header"),
+ IdSplitBuilder.split(" test:[1 2]:abc, table," +
+ " form:table:[ * ]:child, extTable:[ 0, 3 ]:child:[1
8]:@header" ));
+ }
+}