You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by gv...@apache.org on 2006/05/28 00:57:45 UTC
svn commit: r409894 - in /struts/shale/trunk/clay-plugin/src:
java/org/apache/shale/clay/config/ java/org/apache/shale/clay/config/beans/
java/org/apache/shale/clay/parser/builder/ test/org/apache/shale/clay/config/
Author: gvanmatre
Date: Sat May 27 15:57:44 2006
New Revision: 409894
URL: http://svn.apache.org/viewvc?rev=409894&view=rev
Log:
Fix for issue SHALE-181 reported by "ÁÖ Ã÷ aftermath_lin2@hotmail.com".
Added:
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java (with props)
Modified:
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayTemplateParser.java
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/VerbatimBuilder.java
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayTemplateParser.java
URL: http://svn.apache.org/viewvc/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayTemplateParser.java?rev=409894&r1=409893&r2=409894&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayTemplateParser.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayTemplateParser.java Sat May 27 15:57:44 2006
@@ -29,6 +29,7 @@
import org.apache.shale.clay.config.beans.ComponentConfigBean;
import org.apache.shale.clay.config.beans.ConfigBean;
import org.apache.shale.clay.config.beans.ElementBean;
+import org.apache.shale.clay.config.beans.TemplateConfigBean;
import org.apache.shale.clay.parser.Node;
import org.apache.shale.clay.parser.Parser;
import org.apache.shale.clay.parser.builder.Builder;
@@ -142,6 +143,11 @@
//verify there is not a duplicate component id within a naming
//container.
config.checkTree(root);
+
+ //compress the tree merging adjacent verbatim nodes
+ if (config instanceof TemplateConfigBean)
+ ((TemplateConfigBean) config).optimizeTree(root);
+
return root;
}
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java
URL: http://svn.apache.org/viewvc/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java?rev=409894&r1=409893&r2=409894&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java Sat May 27 15:57:44 2006
@@ -18,6 +18,7 @@
package org.apache.shale.clay.config.beans;
+import java.util.BitSet;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
@@ -218,5 +219,126 @@
return b;
}
+
+ /**
+ * <p>Determines if the <code>node</code> is a transient
+ * <code>outputText</code> (<strong>verbatim</strong>) component.</p>
+ */
+ private boolean isVerbatim(ComponentBean node) {
+
+ AttributeBean attr = null;
+ if (node.getJsfid().equals("verbatim")
+ && node.getComponentType().equals("javax.faces.HtmlOutputText")) {
+
+ if ((attr = node.getAttribute("isTransient")) != null) {
+ if (attr.getValue() != null && attr.getValue().length() > 0) {
+ return (Character.toLowerCase(attr.getValue().charAt(0)) == 't');
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * <p>Recursively walks down the graph of meta-data {@link ComponentBean}'s
+ * looking at the children of the <code>root</code>. Adjacent
+ * children that are both <code>verbatim</code> component
+ * definitions are merged. If there is only one child and
+ * the child and root nodes are both <code>verbatim</code>
+ * definitions, the child is merged up to the root.</p>
+ */
+ public void optimizeTree(ComponentBean root) {
+
+ // children is a TreeSet that is returned as a Collection.
+ int size = root.getChildren().size();
+ ComponentBean[] children = new ComponentBean[size];
+ BitSet verbatimSet = new BitSet(size);
+ verbatimSet.clear(0, size);
+
+ StringBuffer buff = new StringBuffer();
+
+ int i = 0;
+ Iterator ci = root.getChildrenIterator();
+ while (ci.hasNext()) {
+ children[i] = (ComponentBean) ci.next();
+ if (isVerbatim(children[i])) {
+
+ verbatimSet.set(i);
+ }
+
+ if (children[i].getChildren().size() > 0) {
+ optimizeTree(children[i]); // merge children for the top down
+ // starting a the botton of the tree.
+ }
+
+ i++;
+ }
+
+ int s = -1;
+ while ((s = verbatimSet.nextSetBit(++s)) > -1) {
+
+ merge: for (int j = s + 1; j < children.length; j++) {
+ if (verbatimSet.get(j)) {
+ buff.setLength(0);
+
+ // grap the value attribute of the first one in the stack
+ // and concat to a buffer
+ AttributeBean attrTop = null;
+ if (((attrTop = children[s].getAttribute("value")) != null)) {
+ if (attrTop.getValue() != null)
+ buff.append(attrTop.getValue());
+ } else
+ break merge; // a verbatim without a value should never happen
+
+ AttributeBean attrNext = null; // the next in sequence to be merged
+ if (((attrNext = children[j].getAttribute("value")) != null)) {
+ if (attrNext.getValue() != null)
+ buff.append(attrNext.getValue());
+ } else
+ continue merge; // a verbatim without a value should never happen
+
+ // merge node values
+ attrTop.setValue(buff.toString());
+ root.getChildren().remove(children[j]); // delete the node after merge from the parent
+
+ } else {
+ // the verbatims are not in sequence (true, false, true)
+ s = j;
+ break merge;
+ }
+ }
+
+
+ }
+
+ // if the root is a verbatim and the only child is a verbatim
+ // merge up to the root
+ if (isVerbatim(root) && root.getChildren().size() == 1
+ && isVerbatim(children[0])) {
+
+ buff.setLength(0);
+
+ // grap the value attribute of the first one in the stack
+ // and concat to a buffer
+ AttributeBean attrTop = null;
+ if (((attrTop = root.getAttribute("value")) != null)) {
+ if (attrTop.getValue() != null)
+ buff.append(attrTop.getValue());
+
+ AttributeBean attrNext = null; // the next in sequence to be merged
+ if (((attrNext = children[0].getAttribute("value")) != null)) {
+ if (attrNext.getValue() != null)
+ buff.append(attrNext.getValue());
+ }
+ // merge node values
+ attrTop.setValue(buff.toString());
+ root.getChildren().clear(); // delete the node after merge from the parent
+ }
+ }
+
+
+ }
}
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/VerbatimBuilder.java
URL: http://svn.apache.org/viewvc/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/VerbatimBuilder.java?rev=409894&r1=409893&r2=409894&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/VerbatimBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/VerbatimBuilder.java Sat May 27 15:57:44 2006
@@ -52,7 +52,7 @@
* </p>
*/
protected String getJsfid(Node node) {
- return "outputText";
+ return "verbatim";
}
/**
Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java
URL: http://svn.apache.org/viewvc/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java?rev=409894&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java Sat May 27 15:57:44 2006
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.clay.config;
+
+import java.util.Iterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.shale.clay.config.beans.AttributeBean;
+import org.apache.shale.clay.config.beans.ComponentBean;
+import org.apache.shale.clay.config.beans.ElementBean;
+import org.apache.shale.clay.config.beans.TemplateConfigBean;
+
+// tests squeezing the component tree
+public class OptimizeTreeTestCase extends AbstractTestCaseConfig {
+
+ // Construct a new instance of this test case.
+ public OptimizeTreeTestCase(String name) {
+ super(name);
+ }
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(OptimizeTreeTestCase.class));
+
+ }
+
+ public void setUp() {
+ super.setUp();
+ }
+
+ private ComponentBean createVerbatim(Class classz, String value)
+ throws InstantiationException, IllegalAccessException {
+
+ ComponentBean target = (ComponentBean) classz.newInstance();
+ target.setJsfid("verbatim");
+ target.setComponentType("javax.faces.HtmlOutputText");
+
+ AttributeBean attr = new AttributeBean();
+ attr.setBindingType(AttributeBean.BINDING_TYPE_VALUE);
+ attr.setName("value");
+ attr.setValue(value);
+ target.addAttribute(attr);
+
+ attr = new AttributeBean();
+ attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
+ attr.setName("escape");
+ attr.setValue(Boolean.FALSE.toString());
+ target.addAttribute(attr);
+
+ attr = new AttributeBean();
+ attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
+ attr.setName("isTransient");
+ attr.setValue(Boolean.TRUE.toString());
+ target.addAttribute(attr);
+
+ return target;
+ }
+
+ public void testRollup() throws Exception {
+
+ ComponentBean root = createVerbatim(ComponentBean.class, "0");
+ for (int i = 1; i < 10; i++) {
+ ElementBean child = (ElementBean) createVerbatim(ElementBean.class,
+ String.valueOf(i));
+ child.setRenderId(i);
+ root.addChild(child);
+ }
+
+ ((TemplateConfigBean) htmlTemplateConfigBean).optimizeTree(root);
+
+ assertEquals("#Children", 0, root.getChildren().size());
+
+ AttributeBean attr = root.getAttribute("value");
+ assertNotNull(attr);
+
+ assertEquals("root value", "0123456789", attr.getValue());
+
+ }
+
+ public void testRollupNested() throws Exception {
+
+ // root 0
+ // + 1
+ // + 2
+ // + 3
+ // + 4
+ // + 5
+ // + 6
+ // + 7
+ // + 8
+ // + 9
+ ComponentBean root = createVerbatim(ComponentBean.class, "0");
+ ElementBean lastChild = null;
+ for (int i = 1; i < 5; i++) {
+ lastChild = (ElementBean) createVerbatim(ElementBean.class, String
+ .valueOf(i));
+ lastChild.setRenderId(i);
+ root.addChild(lastChild);
+ }
+
+ for (int i = 5; i < 10; i++) {
+ ElementBean child = (ElementBean) createVerbatim(ElementBean.class,
+ String.valueOf(i));
+ child.setRenderId(i);
+ lastChild.addChild(child);
+ }
+
+ ((TemplateConfigBean) htmlTemplateConfigBean).optimizeTree(root);
+
+ assertEquals("#Children", 0, root.getChildren().size());
+
+ AttributeBean attr = root.getAttribute("value");
+ assertNotNull(attr);
+
+ assertEquals("root value", "0123456789", attr.getValue());
+
+ }
+
+ public void testInterwoven() throws Exception {
+
+ // 0
+ // +1
+ // +2
+ // +3 not verbatim
+ // +4
+ // +5 not verbatim
+ // +6
+ // +7 not verbatim
+ // +8
+ // +9
+
+ AttributeBean attr = null;
+ ElementBean child = null;
+ ComponentBean root = createVerbatim(ComponentBean.class, "0");
+ // root is not a verbatim
+ root.setJsfid("outputText");
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "1");
+ child.setRenderId(1);
+ root.addChild(child);
+
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "2");
+ child.setRenderId(2);
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "3");
+ child.setRenderId(3);
+ // root is not a verbatim
+ child.setJsfid("outputText");
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "4");
+ child.setRenderId(4);
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "5");
+ child.setRenderId(5);
+ // root is not a verbatim
+ child.setJsfid("outputText");
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "6");
+ child.setRenderId(6);
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "7");
+ child.setRenderId(7);
+ // root is not a verbatim
+ child.setJsfid("outputText");
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "8");
+ child.setRenderId(8);
+ root.addChild(child);
+
+ child = (ElementBean) createVerbatim(ElementBean.class, "9");
+ child.setRenderId(9);
+ root.addChild(child);
+
+ ((TemplateConfigBean) htmlTemplateConfigBean).optimizeTree(root);
+
+ assertEquals("#Children", 7, root.getChildren().size());
+
+ Iterator ci = root.getChildren().iterator();
+ int i = 0;
+ while (ci.hasNext()) {
+ child = (ElementBean) ci.next();
+
+ switch (++i) {
+ case 1: {
+ // first two nodes merged
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "12", attr.getValue());
+ break;
+ }
+ case 2: {
+ // non-verbatim
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "3", attr.getValue());
+ break;
+ }
+ case 3: {
+ // verbatim non-adjacent
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "4", attr.getValue());
+ break;
+ }
+ case 4: {
+ // non-verbatim
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "5", attr.getValue());
+ break;
+ }
+ case 5: {
+ // verbatim non-adjacent
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "6", attr.getValue());
+ break;
+ }
+ case 6: {
+ // non-verbatim
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "7", attr.getValue());
+ break;
+ }
+ case 7: {
+ // first two nodes merged
+ attr = child.getAttribute("value");
+ assertNotNull(attr);
+ assertEquals("root value", "89", attr.getValue());
+ break;
+ }
+
+ };
+ }
+
+ }
+
+}
Propchange: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/OptimizeTreeTestCase.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL