Author: lgawron
Date: Tue Nov 30 15:41:24 2004
New Revision: 109259

URL: http://svn.apache.org/viewcvs?view=rev&rev=109259
Log:
initial (very initial) cocoon-template-block
Added:
   cocoon/trunk/src/blocks/template/
   cocoon/trunk/src/blocks/template/conf/
   cocoon/trunk/src/blocks/template/java/
   cocoon/trunk/src/blocks/template/java/org/
   cocoon/trunk/src/blocks/template/java/org/apache/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/AbstractExpression.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Context.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/DefaultContext.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Expression.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/ExpressionCompiler.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/GenericExpressionCompiler.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlContext.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpression.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpressionCompiler.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ELUtils.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ParseHandler.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/generation/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/generation/TemplateGenerator.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AbstractToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AttributeToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/CharactersToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ElementToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ExpressionToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/PlainElementToken.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Script.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptCompiler.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptContext.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptInvoker.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/TagRepository.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Token.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/AbstractTag.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/Tag.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/samples/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/samples/DuplicateTag.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/ContextStackMap.java
   
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/IncludingConfiguration.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/TypeUtils.java
   cocoon/trunk/src/blocks/template/samples/
   cocoon/trunk/src/blocks/template/test/
   cocoon/trunk/src/blocks/template/test/org/
   cocoon/trunk/src/blocks/template/test/org/apache/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/ExtendedSitemapComponentTestCase.java
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/jexl/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/jexl/JexlExpressionTestCase.java
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/util/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/util/ELUtilsTestCase.java
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-generate.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag-output.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.xtest
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompiler-parse.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.xtest
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-attribute.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-element.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression-output.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag-output.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag.xml
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.xtest
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/ContextStackMapTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/IncludingConfigurationTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/TypeUtilsTestCase.java
   
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/included-conf.xml
Modified:
   cocoon/trunk/blocks.properties
   cocoon/trunk/gump.xml

Modified: cocoon/trunk/blocks.properties
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/blocks.properties?view=diff&rev=109259&p1=cocoon/trunk/blocks.properties&r1=109258&p2=cocoon/trunk/blocks.properties&r2=109259
==============================================================================
--- cocoon/trunk/blocks.properties      (original)
+++ cocoon/trunk/blocks.properties      Tue Nov 30 15:41:24 2004
@@ -46,49 +46,49 @@
 
 #-----[dependency]: "authentication-fw" depends on "session-fw".
 #-----[dependency]: "authentication-fw" is needed by "portal", "portal-fw".
-#include.block.authentication-fw=false
+include.block.authentication-fw=false
 #-----[dependency]: "batik" is needed by "fop", "scratchpad", "tour".
-#include.block.batik=false
-#include.block.bsf=false
+include.block.batik=false
+include.block.bsf=false
 #-----[dependency]: "chaperon" depends on "xsp" (for samples).
-#include.block.chaperon=false
+include.block.chaperon=false
 #-----[dependency]: "databases" depends on "xsp".
 #-----[dependency]: "databases" is needed by "hsqldb", "jms", "ojb", 
"petstore", "repository", "xmldb".
-#include.block.databases=false
+include.block.databases=false
 #-----[dependency]: "fop" depends on "batik".
 #-----[dependency]: "fop" is needed by "tour".
-#include.block.fop=false
+include.block.fop=false
 #-----[dependency]: "hsqldb" depends on "databases".
 #-----[dependency]: "hsqldb" is needed by "jms", "ojb", "petstore".
-#include.block.hsqldb=false
+include.block.hsqldb=false
 #-----[dependency]: "html" is needed by "portal".
-#include.block.html=false
-#include.block.itext=false
-#include.block.jfor=false
-#include.block.jsp=false
-#include.block.linkrewriter=false
+include.block.html=false
+include.block.itext=false
+include.block.jfor=false
+include.block.jsp=false
+include.block.linkrewriter=false
 #-----[dependency]: "lucene" depends on "forms" (for samples), "xsp" (for 
samples).
 #-----[dependency]: "lucene" is needed by "querybean".
-#include.block.lucene=false
-#include.block.naming=false
-#include.block.paranoid=false
-#include.block.poi=false
+include.block.lucene=false
+include.block.naming=false
+include.block.paranoid=false
+include.block.poi=false
 #-----[dependency]: "portal" depends on "authentication-fw", "html", 
"session-fw".
 #-----[dependency]: "portal" is needed by "faces".
-#include.block.portal=false
-#include.block.profiler=false
+include.block.portal=false
+include.block.profiler=false
 #-----[dependency]: "python" depends on "xsp".
-#include.block.python=false
+include.block.python=false
 #-----[dependency]: "session-fw" depends on "xsp".
 #-----[dependency]: "session-fw" is needed by "authentication-fw", "portal", 
"portal-fw".
-#include.block.session-fw=false
+include.block.session-fw=false
 #-----[dependency]: "velocity" is needed by "petstore", "scratchpad".
-#include.block.velocity=false
-#include.block.web3=false
+include.block.velocity=false
+include.block.web3=false
 #-----[dependency]: "xmldb" depends on "databases".
-#include.block.xmldb=false
+include.block.xmldb=false
 #-----[dependency]: "xsp" is needed by "chaperon", "databases", "eventcache", 
"forms", "lucene", "python", "scratchpad", "session-fw", "woody".
-#include.block.xsp=false
+include.block.xsp=false
 
 # Unstable blocks 
--------------------------------------------------------------
 
@@ -101,60 +101,61 @@
 # stable.
 
 #-----[dependency]: "apples" depends on "forms" (for samples).
-#include.block.apples=false
+include.block.apples=false
 #-----[dependency]: "asciiart" is needed by "mail".
-#include.block.asciiart=false
+include.block.asciiart=false
 #-----[dependency]: "axis" is needed by "scratchpad".
-#include.block.axis=false
+include.block.axis=false
 #-----[dependency]: "cron" is needed by "scratchpad".
-#include.block.cron=false
-#include.block.deli=false
+include.block.cron=false
+include.block.deli=false
 #-----[dependency]: "eventcache" depends on "jms", "xsp" (for samples).
 #-----[dependency]: "eventcache" is needed by "repository".
-#include.block.eventcache=false
+include.block.eventcache=false
 #-----[dependency]: "faces" depends on "portal", "taglib".
 #-----[dependency]: "faces" is needed by "scratchpad".
-#include.block.faces=false
+include.block.faces=false
 #-----[dependency]: "forms" depends on "xsp" (for samples).
 #-----[dependency]: "forms" is needed by "apples", "javaflow", "lucene", 
"ojb", "petstore", "querybean", "tour".
-#include.block.forms=false
+include.block.forms=false
 #-----[dependency]: "javaflow" depends on "forms", "ojb" (for samples).
 #-----[dependency]: "javaflow" is needed by "scratchpad".
-#include.block.javaflow=false
+include.block.javaflow=false
 #-----[dependency]: "jms" depends on "databases" (for samples), "hsqldb".
 #-----[dependency]: "jms" is needed by "eventcache", "slide".
-#include.block.jms=false
-#include.block.linotype=false
+include.block.jms=false
+include.block.linotype=false
 #-----[dependency]: "mail" depends on "asciiart", "scratchpad".
-#include.block.mail=false
-#include.block.midi=false
+include.block.mail=false
+include.block.midi=false
 #-----[dependency]: "ojb" depends on "databases" (for samples), "forms" (for 
samples), "hsqldb" (for samples).
 #-----[dependency]: "ojb" is needed by "javaflow".
-#include.block.ojb=false
+include.block.ojb=false
 #-----[dependency]: "petstore" depends on "databases", "forms", "hsqldb", 
"velocity".
-#include.block.petstore=false
-#include.block.proxy=false
-#include.block.qdox=false
+include.block.petstore=false
+include.block.proxy=false
+include.block.qdox=false
 #-----[dependency]: "querybean" depends on "forms" (for samples), "lucene".
-#include.block.querybean=false
+include.block.querybean=false
 #-----[dependency]: "repository" depends on "databases", "eventcache".
 #-----[dependency]: "repository" is needed by "scratchpad", "slide", "webdav".
-#include.block.repository=false
+include.block.repository=false
 #-----[dependency]: "scratchpad" depends on "axis", "batik" (for samples), 
"cron", "faces", "javaflow", "repository", "velocity", "xsp".
 #-----[dependency]: "scratchpad" is needed by "mail".
-#include.block.scratchpad=false
-#include.block.serializers=false
+include.block.scratchpad=false
+include.block.serializers=false
 #-----[dependency]: "slide" depends on "jms", "repository".
-#include.block.slide=false
+include.block.slide=false
 #-----[dependency]: "slop" is needed by "tour".
-#include.block.slop=false
-#include.block.stx=false
+include.block.slop=false
+include.block.stx=false
 #-----[dependency]: "taglib" is needed by "faces".
-#include.block.taglib=false
+include.block.taglib=false
+#include.block.template=false
 #-----[dependency]: "tour" depends on "batik", "fop", "forms", "slop".
-#include.block.tour=false
+include.block.tour=false
 #-----[dependency]: "webdav" depends on "repository".
-#include.block.webdav=false
+include.block.webdav=false
 
 # Deprecated blocks 
------------------------------------------------------------
 

Modified: cocoon/trunk/gump.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/gump.xml?view=diff&rev=109259&p1=cocoon/trunk/gump.xml&r1=109258&p2=cocoon/trunk/gump.xml&r2=109259
==============================================================================
--- cocoon/trunk/gump.xml       (original)
+++ cocoon/trunk/gump.xml       Tue Nov 30 15:41:24 2004
@@ -1215,6 +1215,23 @@
     <nag from="Gump &lt;general@gump.apache.org&gt;" 
to="dev@cocoon.apache.org"/>
   </project>
 
+  <project name="cocoon-block-template" status="unstable">
+    <package>org.apache.cocoon</package>
+    
+    <ant target="gump-block">
+       <property name="block-name" value="template"/>
+       <property name="version" value="@@DATE@@"/>
+    </ant>
+    
+    <depend project="cocoon" inherit="all"/>
+
+    <work nested="tools/anttasks"/>
+    <home nested="build/cocoon-@@DATE@@"/>
+
+    <jar name="blocks/template-block.jar"/>
+
+    <nag from="Gump &lt;general@gump.apache.org&gt;" 
to="dev@cocoon.apache.org"/>
+  </project>
   <!--
     ********************************************
     ********  COCOON SUPPLIED PROJECTS  ********

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/AbstractExpression.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/AbstractExpression.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/AbstractExpression.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+import org.apache.cocoon.util.TypeUtils;
+
+public abstract class AbstractExpression implements Expression {
+    public abstract Object evaluate(Context context);
+
+    public Object evaluate(Context context, Class toType) {
+        return TypeUtils.convert(evaluate(context), toType);
+    }
+
+    public boolean toBoolean(Context context) {
+        return TypeUtils.toBoolean(evaluate(context));
+    }
+
+    public byte toByte(Context context) {
+        return TypeUtils.toByte(evaluate(context));
+    }
+
+    public char toChar(Context context) {
+        return TypeUtils.toChar(evaluate(context));
+    }
+
+    public char[] toCharArray(Context context) {
+        return toString(context).toCharArray();
+    }
+
+    public double toDouble(Context context) {
+        return TypeUtils.toDouble(evaluate(context));
+    }
+
+    public float toFloat(Context context) {
+        return TypeUtils.toFloat(evaluate(context));
+    }
+
+    public int toInt(Context context) {
+        return TypeUtils.toInt(evaluate(context));
+    }
+
+    public long toLong(Context context) {
+        return TypeUtils.toLong(evaluate(context));
+    }
+
+    public short toShort(Context context) {
+        return TypeUtils.toShort(evaluate(context));
+    }
+
+    public String toString(Context context) {
+        String str = (String) evaluate(context, String.class);
+        return str == null ? "" : str;
+    }
+}
\ No newline at end of file

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Context.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Context.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Context.java     
Tue Nov 30 15:41:24 2004
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+import org.apache.cocoon.util.ContextStackMap;
+import org.apache.commons.jexl.JexlContext;
+
+public interface Context extends JexlContext {
+    public ContextStackMap getVariables();
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/DefaultContext.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/DefaultContext.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/DefaultContext.java  
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+import java.util.Map;
+
+import org.apache.cocoon.util.ContextStackMap;
+
+public class DefaultContext implements Context {
+    ContextStackMap variables = new ContextStackMap();
+
+    public ContextStackMap getVariables() {
+        return variables;
+    }
+
+    public Map getVars() {
+        return variables;
+    }
+
+    public void setVars(Map map) {
+        variables.clear();
+        variables.putAll(map);
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Expression.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Expression.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/Expression.java  
Tue Nov 30 15:41:24 2004
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+public interface Expression {
+    public Object evaluate(Context context);
+
+    public Object evaluate(Context context, Class toType);
+
+    public boolean toBoolean(Context context);
+
+    public byte toByte(Context context);
+
+    public char toChar(Context context);
+
+    public char[] toCharArray(Context context);
+
+    public double toDouble(Context context);
+
+    public float toFloat(Context context);
+
+    public int toInt(Context context);
+
+    public long toLong(Context context);
+
+    public short toShort(Context context);
+
+    public String toString(Context context);
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/ExpressionCompiler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/ExpressionCompiler.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/ExpressionCompiler.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+public interface ExpressionCompiler {
+    public Expression compile(String expression);
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/GenericExpressionCompiler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/GenericExpressionCompiler.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/GenericExpressionCompiler.java
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el;
+
+import org.apache.cocoon.el.jexl.JexlExpressionCompiler;
+
+public class GenericExpressionCompiler implements ExpressionCompiler {
+    public static final String JEXL_PREFIX = "jexl:";
+
+    static GenericExpressionCompiler instance;
+
+    ExpressionCompiler jexlCompiler = new JexlExpressionCompiler();
+
+    ExpressionCompiler defaultCompiler = jexlCompiler;
+
+    public static GenericExpressionCompiler getInstance() {
+        if (instance == null)
+            instance = new GenericExpressionCompiler();
+        return instance;
+    }
+
+    public Expression compile(String expression) {
+        // Should an exception be thrown here if prefix is invalid?
+        // The check might be costly.
+
+        if (expression.startsWith(JEXL_PREFIX))
+            return jexlCompiler.compile(expression.substring(JEXL_PREFIX
+                    .length()));
+        else
+            return defaultCompiler.compile(expression);
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlContext.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlContext.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlContext.java
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,19 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.jexl;
+
+public class JexlContext {
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpression.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpression.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpression.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.jexl;
+
+import org.apache.cocoon.el.AbstractExpression;
+import org.apache.cocoon.el.Context;
+import org.apache.commons.jexl.Expression;
+
+public class JexlExpression extends AbstractExpression {
+    Expression expression;
+
+    public JexlExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Object evaluate(Context context) {
+        try {
+            return expression.evaluate(context);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpressionCompiler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpressionCompiler.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/jexl/JexlExpressionCompiler.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.jexl;
+
+import org.apache.cocoon.el.Expression;
+import org.apache.cocoon.el.ExpressionCompiler;
+import org.apache.commons.jexl.ExpressionFactory;
+
+public class JexlExpressionCompiler implements ExpressionCompiler {
+    public Expression compile(String expression) {
+        try {
+            return new JexlExpression(ExpressionFactory
+                    .createExpression(expression));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ELUtils.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ELUtils.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ELUtils.java    
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.util;
+
+import java.nio.BufferUnderflowException;
+import java.nio.CharBuffer;
+
+public class ELUtils {
+    public static void parse(String str, ParseHandler handler) {
+        parse(CharBuffer.wrap(str), handler);
+    }
+
+    public static void parse(CharBuffer buf, ParseHandler handler) {
+        boolean inExpression = false;
+
+        while (buf.hasRemaining()) {
+            int length = 0;
+            CharBuffer slice = buf.slice();
+
+            if (inExpression) {
+                try {
+                    for (char ch = buf.get(); ch != '}'; ch = buf.get(), 
length++)
+                        if (ch == '\\') {
+                            buf.get();
+                            length++;
+                        }
+
+                    if (length > 0)
+                        handler.handleExpression(slice.subSequence(0, length));
+                } catch (BufferUnderflowException e) {
+                    throw new RuntimeException("Missing '}'");
+                }
+            } else {
+                while (buf.hasRemaining())
+                    if (buf.get() == '$' && buf.hasRemaining()
+                            && buf.get() == '{')
+                        break;
+                    else
+                        length++;
+
+                if (length > 0)
+                    handler.handleText(slice.subSequence(0, length));
+            }
+            inExpression = !inExpression;
+        }
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ParseHandler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ParseHandler.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/el/util/ParseHandler.java
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,22 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.util;
+
+public interface ParseHandler {
+    public void handleExpression(CharSequence characters);
+
+    public void handleText(CharSequence characters);
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/generation/TemplateGenerator.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/generation/TemplateGenerator.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/generation/TemplateGenerator.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.generation;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.el.ExpressionCompiler;
+import org.apache.cocoon.el.GenericExpressionCompiler;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.cocoon.template.script.Script;
+import org.apache.cocoon.template.script.ScriptCompiler;
+import org.apache.cocoon.template.script.ScriptContext;
+import org.apache.cocoon.template.script.ScriptInvoker;
+import org.apache.cocoon.template.script.TagRepository;
+import org.apache.cocoon.util.IncludingConfiguration;
+import org.apache.excalibur.source.Source;
+import org.xml.sax.SAXException;
+
+public class TemplateGenerator extends ServiceableGenerator implements
+        Configurable {
+    static HashMap cache = new HashMap();
+
+    TagRepository tagRepository = new TagRepository();
+
+    ExpressionCompiler expressionCompiler = GenericExpressionCompiler
+            .getInstance();
+
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        tagRepository.enableLogging(logger);
+    }
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        IncludingConfiguration newConf = new IncludingConfiguration(conf,
+                manager);
+        tagRepository.configure(newConf);
+    }
+
+    public TagRepository getTagRepository() {
+        return tagRepository;
+    }
+
+    public void generate() throws IOException, SAXException,
+            ProcessingException {
+        try {
+            Source inputSource = resolver.resolveURI(source);
+
+            Script script = null;
+            synchronized (cache) {
+                script = (Script) cache.get(inputSource.getURI());
+                if (script == null) {
+                    script = compileScript(inputSource);
+                    cache.put(inputSource.getURI(), script);
+                }
+            }
+
+            ScriptContext context = new ScriptContext();
+            context.setConsumer(xmlConsumer);
+
+            // TODO: populate context
+
+            ScriptInvoker scriptInvoker = new ScriptInvoker(script, context);
+            scriptInvoker.invoke();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected Script compileScript(Source inputSource) throws Exception {
+        ScriptCompiler compiler = new ScriptCompiler(tagRepository,
+                expressionCompiler);
+        SourceUtil.parse(manager, inputSource, compiler);
+        return compiler.getScript();
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AbstractToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AbstractToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AbstractToken.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public abstract class AbstractToken implements Token {
+    protected int start;
+    protected int end;
+
+    public int getStart() {
+        return start;
+    }
+
+    public void setStart(int start) {
+        this.start = start;
+    }
+
+    public int getEnd() {
+        return end;
+    }
+
+    public void setEnd(int end) {
+        this.end = end;
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AttributeToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AttributeToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/AttributeToken.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public class AttributeToken extends AbstractToken {
+    String namespace;
+    String lname;
+    String qname;
+
+    public void setup(String namespace, String lname, String qname) {
+        this.namespace = namespace;
+        this.lname = lname;
+        this.qname = qname;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getLName() {
+        return lname;
+    }
+
+    public String getQName() {
+        return qname;
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/CharactersToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/CharactersToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/CharactersToken.java
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public class CharactersToken extends AbstractToken {
+    char[] characters;
+
+    public void setup(CharSequence characters) {
+        // TODO: this should be done better
+        this.characters = characters.toString().toCharArray();
+    }
+
+    public char[] getCharacters() {
+        return characters;
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ElementToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ElementToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ElementToken.java
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public interface ElementToken extends Token {
+    public int getBodyStart();
+
+    public void setBodyStart(int bodyStart);
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ExpressionToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ExpressionToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ExpressionToken.java
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import org.apache.cocoon.el.Expression;
+
+public class ExpressionToken extends AbstractToken {
+    Expression expression;
+
+    public void setup(Expression expression) {
+        this.expression = expression;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/PlainElementToken.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/PlainElementToken.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/PlainElementToken.java
      Tue Nov 30 15:41:24 2004
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public class PlainElementToken extends AbstractToken implements ElementToken {
+    protected String namespace;
+    protected String lname;
+    protected String qname;
+    protected int bodyStart;
+
+    public void setup(String namespace, String lname, String qname) {
+        this.namespace = namespace;
+        this.lname = lname;
+        this.qname = qname;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getLName() {
+        return lname;
+    }
+
+    public String getQName() {
+        return qname;
+    }
+
+    public int getBodyStart() {
+        return bodyStart;
+    }
+
+    public void setBodyStart(int bodyStart) {
+        this.bodyStart = bodyStart;
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Script.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Script.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Script.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Script {
+    ArrayList tokens = new ArrayList();
+
+    public void add(Token token) {
+        token.setStart(size());
+        tokens.add(token);
+    }
+
+    public void addAtom(Token token) {
+        add(token);
+        token.setEnd(size());
+    }
+
+    public Token get(int i) {
+        return (Token) tokens.get(i);
+    }
+
+    public int size() {
+        return tokens.size();
+    }
+
+    public List getTokens() {
+        return tokens;
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptCompiler.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptCompiler.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptCompiler.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import java.nio.CharBuffer;
+import java.util.Stack;
+
+import org.apache.cocoon.el.ExpressionCompiler;
+import org.apache.cocoon.el.util.ELUtils;
+import org.apache.cocoon.el.util.ParseHandler;
+import org.apache.cocoon.xml.AbstractXMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class ScriptCompiler extends AbstractXMLConsumer {
+    static final int TEXT = 1;
+    static final int EXPRESSION = 2;
+    Script script = new Script();
+    TextParseHandler parseHandler = new TextParseHandler();
+    Stack openedTokens = new Stack();
+    TagRepository tagRepository;
+    ExpressionCompiler expressionCompiler;
+
+    public ScriptCompiler(TagRepository tagRepository,
+            ExpressionCompiler expressionCompiler) {
+        this.tagRepository = tagRepository;
+        this.expressionCompiler = expressionCompiler;
+    }
+
+    public Script getScript() {
+        return script;
+    }
+
+    public void startElement(String namespace, String lname, String qname,
+            Attributes atts) throws SAXException {
+        ElementToken token;
+
+        if (tagRepository.contains(namespace, lname)) {
+            token = tagRepository.getTag(namespace, lname);
+        } else {
+            token = new PlainElementToken();
+            ((PlainElementToken) token).setup(namespace, lname, qname);
+        }
+
+        script.add(token);
+        openedTokens.push(token);
+
+        for (int i = 0; i < atts.getLength(); i++) {
+            AttributeToken attrToken = new AttributeToken();
+            attrToken.setup(atts.getURI(i), atts.getLocalName(i), atts
+                    .getQName(i));
+            script.add(attrToken);
+            ELUtils.parse(CharBuffer.wrap(atts.getValue(i)), parseHandler);
+            attrToken.setEnd(script.size());
+        }
+
+        token.setBodyStart(script.size());
+    }
+
+    public void endElement(String namespace, String lname, String qname)
+            throws SAXException {
+        Token token = (Token) openedTokens.pop();
+        token.setEnd(script.size());
+    }
+
+    public void characters(char ch[], int start, int length)
+            throws SAXException {
+        ELUtils.parse(CharBuffer.wrap(ch, start, length), parseHandler);
+    }
+
+    public class TextParseHandler implements ParseHandler {
+        public void handleExpression(CharSequence characters) {
+            ExpressionToken token = new ExpressionToken();
+            token.setup(expressionCompiler.compile(characters.toString()));
+            script.addAtom(token);
+        }
+
+        public void handleText(CharSequence characters) {
+            CharactersToken token = new CharactersToken();
+            token.setup(characters);
+            script.addAtom(token);
+        }
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptContext.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptContext.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptContext.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import org.apache.cocoon.el.DefaultContext;
+import org.apache.cocoon.xml.XMLConsumer;
+
+public class ScriptContext extends DefaultContext {
+    XMLConsumer consumer;
+    ScriptInvoker scriptInvoker;
+
+    public XMLConsumer getConsumer() {
+        return consumer;
+    }
+
+    public void setConsumer(XMLConsumer consumer) {
+        this.consumer = consumer;
+    }
+
+    public ScriptInvoker getScriptInvoker() {
+        return scriptInvoker;
+    }
+
+    public void setScriptInvoker(ScriptInvoker scriptInvoker) {
+        this.scriptInvoker = scriptInvoker;
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptInvoker.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptInvoker.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/ScriptInvoker.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import org.apache.cocoon.template.tag.Tag;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+public class ScriptInvoker {
+
+    public static final String CDATA = "CDATA";
+
+    Script script;
+
+    ScriptContext context;
+
+    XMLConsumer consumer;
+
+    public ScriptInvoker(Script script, ScriptContext context) {
+        this.script = script;
+        this.context = context;
+        this.consumer = context.getConsumer();
+        context.setScriptInvoker(this);
+    }
+
+    public void invoke() throws Exception {
+        consumer.startDocument();
+        invoke(0, script.size());
+        consumer.endDocument();
+    }
+
+    public void invoke(int start, int end) throws Exception {
+
+        for (int i = start; i < end;) {
+            Token tok = script.get(i);
+
+            if (tok instanceof PlainElementToken) {
+                PlainElementToken token = (PlainElementToken) tok;
+                Attributes attributes = getElementAttributes(
+                        token.getStart() + 1, token.getBodyStart());
+                consumer.startElement(token.getNamespace(), token.getLName(),
+                        token.getQName(), attributes);
+                invoke(token.getBodyStart(), token.getEnd());
+                consumer.endElement(token.getNamespace(), token.getLName(),
+                        token.getQName());
+
+            } else if (tok instanceof Tag) {
+                ((Tag) tok).invoke(context);
+
+            } else if (tok instanceof CharactersToken) {
+                char[] characters = ((CharactersToken) tok).getCharacters();
+                consumer.characters(characters, 0, characters.length);
+
+            } else if (tok instanceof ExpressionToken) {
+                char[] value = ((ExpressionToken) tok).getExpression()
+                        .toCharArray(context);
+                consumer.characters(value, 0, value.length);
+
+            } else {
+                throw new RuntimeException("Illegal token");
+            }
+
+            i = tok.getEnd();
+        }
+    }
+
+    public Attributes getElementAttributes(int start, int end) throws 
Exception {
+        AttributesImpl attributes = new AttributesImpl();
+
+        for (int i = start; i < end;) {
+            Token tok = script.get(i);
+
+            if (tok instanceof AttributeToken) {
+                AttributeToken token = (AttributeToken) tok;
+                String value = getText(token.getStart() + 1, token.getEnd());
+                attributes.addAttribute(token.getNamespace(), token.getLName(),
+                        token.getQName(), CDATA, value);
+                i = token.getEnd();
+            } else {
+                throw new RuntimeException("Illegal token");
+            }
+        }
+
+        return attributes;
+    }
+
+    public String getText(int start, int end) throws Exception {
+        StringBuffer text = new StringBuffer();
+
+        for (int i = start; i < end; i++) {
+            Token token = script.get(i);
+
+            if (token instanceof CharactersToken)
+                text.append(((CharactersToken) token).getCharacters());
+            else if (token instanceof ExpressionToken)
+                text.append(((ExpressionToken) token).getExpression().toString(
+                        context));
+            else
+                throw new RuntimeException("Illegal token");
+        }
+        return text.toString();
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/TagRepository.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/TagRepository.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/TagRepository.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import java.util.HashMap;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.template.tag.Tag;
+
+public class TagRepository extends AbstractLogEnabled implements Configurable {
+    HashMap tagMap = new HashMap();
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        configureTags(conf.getChildren("tag"));
+    }
+
+    public void configureTags(Configuration[] confs)
+            throws ConfigurationException {
+        for (int i = 0; i < confs.length; i++) {
+            registerTag(confs[i].getAttribute("namespace"), confs[i]
+                    .getAttribute("name"), confs[i].getAttribute("src"));
+        }
+    }
+
+    public void registerTag(String namespace, String name, String src) {
+        try {
+            registerTag(namespace, name, Class.forName(src));
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Class not found", e);
+        }
+
+    }
+
+    public void registerTag(String namespace, String name, Class clazz) {
+        tagMap.put(createKey(namespace, name), clazz);
+        if (getLogger().isInfoEnabled())
+            getLogger().info("Registered tag: namespace=" + namespace + ", 
name="
+                    + name + ", src=" + clazz.getName());
+    }
+
+    public Tag getTag(String namespace, String name) {
+        try {
+            Class type = (Class) tagMap.get(createKey(namespace, name));
+            return (Tag) type.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public boolean contains(String namespace, String name) {
+        return tagMap.containsKey(createKey(namespace, name));
+    }
+
+    protected String createKey(String namespace, String name) {
+        return namespace + " " + name;
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Token.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Token.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/script/Token.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,27 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+public interface Token {
+    public int getStart();
+
+    public void setStart(int start);
+
+    public int getEnd();
+
+    public void setEnd(int end);
+}
+

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/AbstractTag.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/AbstractTag.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/AbstractTag.java
       Tue Nov 30 15:41:24 2004
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.tag;
+
+import org.apache.cocoon.template.script.AbstractToken;
+import org.apache.cocoon.template.script.ElementToken;
+import org.apache.cocoon.template.script.ScriptContext;
+
+public abstract class AbstractTag extends AbstractToken implements
+        ElementToken, Tag {
+    protected int bodyStart;
+
+    public int getBodyStart() {
+        return bodyStart;
+    }
+
+    public void setBodyStart(int bodyStart) {
+        this.bodyStart = bodyStart;
+    }
+
+    public abstract void invoke(ScriptContext context) throws Exception;
+
+    public void invokeBody(ScriptContext context) throws Exception {
+        context.getScriptInvoker().invoke(bodyStart, end);
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/Tag.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/Tag.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/Tag.java   
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.tag;
+
+import org.apache.cocoon.template.script.ElementToken;
+import org.apache.cocoon.template.script.ScriptContext;
+
+public interface Tag extends ElementToken {
+    public void invoke(ScriptContext context) throws Exception;
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/samples/DuplicateTag.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/samples/DuplicateTag.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/tag/samples/DuplicateTag.java
      Tue Nov 30 15:41:24 2004
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.tag.samples;
+
+import org.apache.cocoon.template.script.ScriptContext;
+import org.apache.cocoon.template.tag.AbstractTag;
+
+public class DuplicateTag extends AbstractTag {
+    public void invoke(ScriptContext context) throws Exception {
+        invokeBody(context);
+        invokeBody(context);
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/ContextStackMap.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/ContextStackMap.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/ContextStackMap.java
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 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.cocoon.util;
+
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.commons.collections.map.HashedMap;
+
+public final class ContextStackMap extends HashedMap {
+
+    Stack bkpStack = new Stack();
+
+    Map bkp;
+
+    public void clear() {
+        super.clear();
+        bkpStack.clear();
+        bkp = null;
+    }
+
+    public Object put(Object key, Object value) {
+        if (bkp == null || bkp.containsKey(key)) {
+            return super.put(key, value);
+        } else {
+            Object previous = super.put(key, value);
+            bkp.put(key, previous);
+            return previous;
+        }
+    }
+
+    public void putAll(Map map) {
+        if (bkp == null)
+            super.putAll(map);
+        else
+            throw new IllegalStateException(
+                    "We don't support putAll() in added contexts yet");
+    }
+
+    // NB. remove() only operates on the current context
+    public Object remove(Object key) {
+        if (bkp == null)
+            return super.remove(key);
+        else if (bkp.containsKey(key))
+            return super.put(key, bkp.remove(key));
+        else
+            return null;
+    }
+
+    public void pushContext() {
+        bkp = new HashedMap();
+        bkpStack.push(bkp);
+    }
+
+    public void popContext() {
+        super.putAll((Map) bkpStack.pop());
+        bkp = bkpStack.isEmpty() ? null : (Map) bkpStack.peek();
+    }
+
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/IncludingConfiguration.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/IncludingConfiguration.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/IncludingConfiguration.java
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 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.cocoon.util;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+public class IncludingConfiguration extends DefaultConfiguration {
+    DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+
+    public IncludingConfiguration(Configuration conf, ServiceManager manager) {
+        super(conf.getName());
+        addAllAttributes(conf);
+        addAllChildren(conf);
+        SourceResolver resolver = null;
+        try {
+            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+            Configuration[] confs = getChildren("include");
+            for (int i = 0; i < confs.length; i++) {
+                Source source = resolver.resolveURI(confs[i].getValue());
+                addAllChildren(builder.build(source.getInputStream()));
+                removeChild(confs[i]);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (resolver != null)
+                manager.release(resolver);
+        }
+    }
+
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/TypeUtils.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/TypeUtils.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/util/TypeUtils.java 
Tue Nov 30 15:41:24 2004
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2001,2004 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.cocoon.util;
+
+import org.apache.commons.lang.BooleanUtils;
+
+/**
+ * Derived from org.apache.commons.jex.util.TypeUtils
+ */
+public class TypeUtils {
+
+    public static Object convert(Object value, Class toType) {
+        if (value == null)
+            return value;
+
+        Class fromType = value.getClass();
+
+        if (toType == Object.class || fromType.equals(toType)
+                || toType.isAssignableFrom(fromType))
+            return value;
+
+        else if (value instanceof Boolean)
+            return doConvert((Boolean) value, toType);
+
+        else if (value instanceof Number)
+            return doConvert((Number) value, toType);
+
+        else if (value instanceof String)
+            return doConvert((String) value, toType);
+
+        else
+            throw new RuntimeException(message(value, toType));
+    }
+
+    protected static Object doConvert(Boolean value, Class toType) {
+        if (toType == String.class)
+            return value.toString();
+
+        else if (Number.class.isAssignableFrom(toType))
+            return doConvert(BooleanUtils.toIntegerObject(value), toType);
+
+        else
+            throw new RuntimeException(message(Boolean.class, toType));
+    }
+
+    protected static Object doConvert(Number value, Class toType) {
+        if (toType == String.class)
+            return value.toString();
+
+        else if (toType == Boolean.class)
+            return value.doubleValue() == 0.0 ? Boolean.FALSE : Boolean.TRUE;
+
+        else if (toType == Byte.class)
+            return new Byte(value.byteValue());
+
+        else if (toType == Short.class)
+            return new Short(value.shortValue());
+
+        else if (toType == Integer.class)
+            return new Integer(value.intValue());
+
+        else if (toType == Long.class)
+            return new Long(value.longValue());
+
+        else if (toType == Float.class)
+            return new Float(value.floatValue());
+
+        else if (toType == Double.class)
+            return new Double(value.doubleValue());
+
+        else
+            throw new RuntimeException(message(value, toType));
+    }
+
+    protected static Object doConvert(String value, Class toType) {
+        if (toType == Boolean.class)
+            return BooleanUtils.toBooleanObject(value);
+
+        else if (toType == Byte.class)
+            return new Byte(value);
+
+        else if (toType == Short.class)
+            return new Short(value);
+
+        else if (toType == Integer.class)
+            return new Integer(value);
+
+        else if (toType == Long.class)
+            return new Long(value);
+
+        else if (toType == Float.class)
+            return new Float(value);
+
+        else if (toType == Double.class)
+            return new Double(value);
+
+        else
+            throw new RuntimeException(message(value, toType));
+    }
+
+    public static boolean toBoolean(Object object) {
+        Boolean value = (Boolean) convert(object, Boolean.class);
+        return value == null ? false : value.booleanValue();
+    }
+
+    public static byte toByte(Object object) {
+        Byte value = (Byte) convert(object, Byte.class);
+        return value == null ? 0 : value.byteValue();
+    }
+
+    public static char toChar(Object object) {
+        Character value = (Character) convert(object, Character.class);
+        return value == null ? 0 : value.charValue();
+    }
+
+    public static double toDouble(Object object) {
+        Double value = (Double) convert(object, Double.class);
+        return value == null ? 0 : value.doubleValue();
+    }
+
+    public static float toFloat(Object object) {
+        Float value = (Float) convert(object, Float.class);
+        return value == null ? 0 : value.floatValue();
+    }
+
+    public static int toInt(Object object) {
+        Integer value = (Integer) convert(object, Integer.class);
+        return value == null ? 0 : value.intValue();
+    }
+
+    public static long toLong(Object object) {
+        Long value = (Long) convert(object, Long.class);
+        return value == null ? 0 : value.longValue();
+    }
+
+    public static short toShort(Object object) {
+        Short value = (Short) convert(object, Short.class);
+        return value == null ? 0 : value.shortValue();
+    }
+
+    // Helper functions
+
+    protected static String message(Object value, Class toType) {
+        return value.getClass().getName() + " -> " + toType.getName()
+                + " conversion not supported";
+    }
+
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/ExtendedSitemapComponentTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/ExtendedSitemapComponentTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/ExtendedSitemapComponentTestCase.java
       Tue Nov 30 15:41:24 2004
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 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.cocoon;
+
+// TODO: cleanup imports
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.source.SourceResolverAdapter;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.mock.MockEnvironment;
+import org.apache.cocoon.generation.AbstractGenerator;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.xml.WhitespaceFilter;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.w3c.dom.Document;
+import org.xml.sax.ContentHandler;
+
+/**
+ * Adds some utility functions
+ */
+public abstract class ExtendedSitemapComponentTestCase extends
+        SitemapComponentTestCase {
+    /**
+     * Generates with a supplied generator
+     */
+    public void generate(AbstractGenerator generator, String source,
+            Parameters parameters, XMLConsumer consumer) throws Exception {
+        MockEnvironment env = new MockEnvironment();
+        Processor processor = new MockProcessor();
+
+        EnvironmentHelper.enterProcessor(processor, this.getManager(), env);
+
+        SourceResolver resolver = (SourceResolver) lookup(SourceResolver.ROLE);
+        generator.setup(new SourceResolverAdapter(resolver, getManager()),
+                getObjectModel(), source, parameters);
+        generator.setConsumer(new WhitespaceFilter(consumer));
+        generator.generate();
+        generator.recycle();
+        release(resolver);
+
+        EnvironmentHelper.leaveProcessor();
+    }
+
+    /**
+     * Transforms with a supplied transformer
+     */
+    public Document transform(Transformer transformer, String source,
+            Parameters parameters, Document input) throws Exception {
+        MockEnvironment env = new MockEnvironment();
+        Processor processor = new MockProcessor();
+
+        EnvironmentHelper.enterProcessor(processor, this.getManager(), env);
+
+        SourceResolver resolver = (SourceResolver) lookup(SourceResolver.ROLE);
+        transformer.setup(new SourceResolverAdapter(resolver, getManager()),
+                getObjectModel(), source, parameters);
+
+        SAXParser parser = (SAXParser) lookup(SAXParser.ROLE);
+        DOMBuilder builder = new DOMBuilder();
+        transformer.setConsumer(new WhitespaceFilter(builder));
+        DOMStreamer streamer = new DOMStreamer(transformer);
+        streamer.stream(input);
+        Document document = builder.getDocument();
+
+        release(resolver);
+        release(parser);
+
+        EnvironmentHelper.leaveProcessor();
+        return document;
+    }
+
+    public Source resolveURI(String uri) throws Exception {
+        SourceResolver resolver = (SourceResolver) lookup(SourceResolver.ROLE);
+        Source source = resolver.resolveURI(uri);
+        release(resolver);
+        return source;
+    }
+
+    public void parse(String uri, ContentHandler contentHandler)
+            throws Exception {
+        Source source = resolveURI(uri);
+        SourceUtil.parse(getManager(), source, contentHandler);
+    }
+
+    public Configuration conf(String name) {
+        return new DefaultConfiguration(name);
+    }
+
+    public Configuration conf(String name, Configuration child) {
+        DefaultConfiguration conf = new DefaultConfiguration(name);
+        conf.addChild(child);
+        return conf;
+    }
+
+    public Configuration conf(String name, String value) {
+        DefaultConfiguration conf = new DefaultConfiguration(name);
+        conf.setValue(value);
+        return conf;
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/jexl/JexlExpressionTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/jexl/JexlExpressionTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/jexl/JexlExpressionTestCase.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.jexl;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.container.ContainerTestCase;
+import org.apache.cocoon.el.Context;
+import org.apache.cocoon.el.DefaultContext;
+import org.apache.cocoon.el.Expression;
+
+public class JexlExpressionTestCase extends ContainerTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    JexlExpressionCompiler compiler;
+    Context context;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        compiler = new JexlExpressionCompiler();
+        context = new DefaultContext();
+    }
+
+    public void testEvaluate() {
+        Expression expression = compiler.compile("1 + 1");
+        assertEquals(2, expression.toInt(context));
+        assertEquals("2", expression.toString(context));
+    }
+
+    public void testEvaluateVariables() {
+        context.getVariables().put("a", new Integer(1));
+        context.getVariables().put("b", new Integer(2));
+        Expression expression = compiler.compile("a + b");
+        assertEquals(3, expression.toInt(context));
+    }
+
+    public void testToCharArrayNull() {
+        context.getVariables().put("a", null);
+        Expression expression = compiler.compile("a");
+        assertEquals(0, expression.toCharArray(context).length);
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/util/ELUtilsTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/util/ELUtilsTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/el/util/ELUtilsTestCase.java
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 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.cocoon.el.util;
+
+import java.util.ArrayList;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.container.ContainerTestCase;
+
+public class ELUtilsTestCase extends ContainerTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+    TestParseHandler handler;
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        handler = new TestParseHandler();
+    }
+
+    public void testParse1() throws Exception {
+        ELUtils.parse("123", handler);
+
+        assertEquals(1, handler.texts.size());
+        assertEquals(0, handler.expressions.size());
+
+        assertEquals("123", handler.texts.get(0));
+    }
+
+    public void testParse2() throws Exception {
+        ELUtils.parse("${expr}", handler);
+
+        assertEquals(0, handler.texts.size());
+        assertEquals(1, handler.expressions.size());
+
+        assertEquals("expr", handler.expressions.get(0));
+    }
+
+    public void testParse3() throws Exception {
+        ELUtils.parse("123${expr}234", handler);
+
+        assertEquals(2, handler.texts.size());
+        assertEquals(1, handler.expressions.size());
+
+        assertEquals("123", handler.texts.get(0));
+        assertEquals("expr", handler.expressions.get(0));
+        assertEquals("234", handler.texts.get(1));
+    }
+
+    public void testParse4() throws Exception {
+        try {
+            ELUtils.parse("${expr", handler);
+            fail("Should throw exception");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testParse5() throws Exception {
+        ELUtils.parse("${123\\}234}", handler);
+
+        assertEquals(0, handler.texts.size());
+        assertEquals(1, handler.expressions.size());
+
+        assertEquals("123\\}234", handler.expressions.get(0));
+    }
+
+    public class TestParseHandler implements ParseHandler {
+        public ArrayList texts = new ArrayList();
+
+        public ArrayList expressions = new ArrayList();
+
+        public void handleText(CharSequence characters) {
+            texts.add(characters.toString());
+        }
+
+        public void handleExpression(CharSequence characters) {
+            expressions.add(characters.toString());
+        }
+
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-generate.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-generate.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-generate.xml
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+
+<root>
+  text
+
+  <item attr="1">
+    Some text
+  </item>
+  <item attr="2">
+    More text
+  </item>
+
+</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag-output.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag-output.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag-output.xml
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<root>
+  <item>1</item>
+  <item>1</item>
+</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGenerator-tag.xml
       Tue Nov 30 15:41:24 2004
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+
+<root xmlns:test="testns">
+  <test:duplicate>
+    <item>1</item>
+  </test:duplicate>
+</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.generation;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ExtendedSitemapComponentTestCase;
+import org.apache.cocoon.template.tag.samples.DuplicateTag;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+
+public class TemplateGeneratorTestCase extends 
ExtendedSitemapComponentTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+    String docBase = "resource://org/apache/cocoon/template/generation/";
+    TemplateGenerator generator;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        generator = new TemplateGenerator();
+        generator.service(getManager());
+        generator.enableLogging(logger);
+    }
+
+    public Logger getLogger() {
+        return this.logger;
+    }
+
+    public void testGenerate() throws Exception {
+        String inputURI = docBase + "TemplateGenerator-generate.xml";
+
+        DOMBuilder builder = new DOMBuilder();
+        generate(generator, inputURI, EMPTY_PARAMS, builder);
+
+        assertEqual(load(inputURI), builder.getDocument());
+    }
+
+    public void testTag() throws Exception {
+        String inputURI = docBase + "TemplateGenerator-tag.xml";
+        String outputURI = docBase + "TemplateGenerator-tag-output.xml";
+
+        generator.getTagRepository().registerTag("testns", "duplicate",
+                DuplicateTag.class);
+        DOMBuilder builder = new DOMBuilder();
+        generate(generator, inputURI, EMPTY_PARAMS, builder);
+
+        assertEqual(load(outputURI), builder.getDocument());
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.xtest
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.xtest?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/generation/TemplateGeneratorTestCase.xtest
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 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.
+-->
+
+<testcase>
+  <roles>
+    <role name="org.apache.excalibur.xml.sax.SAXParser"
+      shorthand="xml-parser"
+      default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  </roles>
+ 
+  <components>
+    <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+      <parameter name="validate" value="false"/>
+      <parameter name="namespace-prefixes" value="false"/>
+      <parameter name="stop-on-warning" value="true"/>
+      <parameter name="stop-on-recoverable-error" value="true"/>
+      <parameter name="reuse-parsers" value="false"/>
+    </xml-parser>
+  </components>
+ 
+</testcase>
+ 

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompiler-parse.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompiler-parse.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompiler-parse.xml
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<root>text</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ExtendedSitemapComponentTestCase;
+import org.apache.cocoon.el.GenericExpressionCompiler;
+import org.apache.cocoon.template.tag.AbstractTag;
+import org.xml.sax.helpers.AttributesImpl;
+
+public class ScriptCompilerTestCase extends ExtendedSitemapComponentTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+    String docBase = "resource://org/apache/cocoon/template/script/";
+    ScriptCompiler compiler;
+    TagRepository tagRepository;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        tagRepository = new TagRepository();
+        tagRepository.enableLogging(getLogger());
+        compiler = new ScriptCompiler(tagRepository, GenericExpressionCompiler
+                .getInstance());
+    }
+
+    public Logger getLogger() {
+        return this.logger;
+    }
+
+    public void testParse() throws Exception {
+        parse(docBase + "ScriptCompiler-parse.xml", compiler);
+        Script script = compiler.getScript();
+        assertEquals(2, script.size());
+    }
+
+    public void testElement() throws Exception {
+        compiler.startElement("ns", "lname", "qname", new AttributesImpl());
+        compiler.endElement("ns", "lname", "qname");
+        Script script = compiler.getScript();
+
+        assertEquals(1, script.size());
+
+        PlainElementToken token = (PlainElementToken) script.get(0);
+        assertEquals(0, token.getStart());
+        assertEquals(1, token.getBodyStart());
+        assertEquals(1, token.getEnd());
+        assertEquals("ns", token.getNamespace());
+        assertEquals("lname", token.getLName());
+        assertEquals("qname", token.getQName());
+
+    }
+
+    public void testNestedElement() throws Exception {
+        compiler.startElement("", "el0", "", new AttributesImpl());
+        compiler.startElement("", "el1", "", new AttributesImpl());
+        compiler.endElement("", "el1", "");
+        compiler.endElement("", "el0", "");
+        Script script = compiler.getScript();
+
+        assertEquals(2, script.size());
+
+        PlainElementToken token0 = (PlainElementToken) script.get(0);
+        PlainElementToken token1 = (PlainElementToken) script.get(1);
+
+        assertEquals("el0", token0.getLName());
+        assertEquals(0, token0.getStart());
+        assertEquals(2, token0.getEnd());
+
+        assertEquals("el1", token1.getLName());
+        assertEquals(1, token1.getStart());
+        assertEquals(2, token1.getEnd());
+    }
+
+    public void testCharacters() throws Exception {
+        compiler.characters("123".toCharArray(), 0, 3);
+        Script script = compiler.getScript();
+
+        assertEquals(1, script.size());
+
+        CharactersToken token = (CharactersToken) script.get(0);
+        assertEquals(0, token.getStart());
+        assertEquals(1, token.getEnd());
+        assertEquals("123", new String(token.getCharacters()));
+    }
+
+    public void testAttributes() throws Exception {
+        AttributesImpl attributes = new AttributesImpl();
+        attributes.addAttribute("ns", "lname", "qname", "CDATA", "value");
+
+        compiler.startElement("", "element", "", attributes);
+        compiler.endElement("", "element", "");
+
+        Script script = compiler.getScript();
+        assertEquals(3, script.size());
+
+        PlainElementToken element = (PlainElementToken) script.get(0);
+        assertEquals(0, element.getStart());
+        assertEquals(3, element.getBodyStart());
+        assertEquals(3, element.getEnd());
+
+        AttributeToken attribute = (AttributeToken) script.get(1);
+        assertEquals(1, attribute.getStart());
+        assertEquals(3, attribute.getEnd());
+        assertEquals("ns", attribute.getNamespace());
+        assertEquals("lname", attribute.getLName());
+        assertEquals("qname", attribute.getQName());
+
+        CharactersToken characters = (CharactersToken) script.get(2);
+        assertEquals(2, characters.getStart());
+        assertEquals(3, characters.getEnd());
+        assertEquals("value", new String(characters.getCharacters()));
+    }
+
+    public void testExpression() throws Exception {
+        compiler.characters("${1}".toCharArray(), 0, 4);
+
+        Script script = compiler.getScript();
+        assertEquals(1, script.size());
+
+        ExpressionToken token = (ExpressionToken) script.get(0);
+        assertEquals(0, token.getStart());
+        assertEquals(1, token.getEnd());
+        assertNotNull(token.getExpression());
+    }
+
+    public void testTextAndExpression() throws Exception {
+        compiler.characters("1${1}2".toCharArray(), 0, 6);
+
+        Script script = compiler.getScript();
+        assertEquals(3, script.size());
+
+        assertTrue(script.get(0) instanceof CharactersToken);
+        assertTrue(script.get(1) instanceof ExpressionToken);
+        assertTrue(script.get(2) instanceof CharactersToken);
+    }
+
+    public void testTag() throws Exception {
+        tagRepository.registerTag("ns", "dummy", DummyTag.class);
+        Script script = compiler.getScript();
+
+        compiler.startElement("ns", "dummy", "", new AttributesImpl());
+        compiler.endElement("ns", "dummy", "");
+
+        assertEquals(1, script.size());
+
+        assertTrue(script.get(0) instanceof DummyTag);
+    }
+
+    public static class DummyTag extends AbstractTag {
+        public void invoke(ScriptContext context) throws Exception {
+        }
+    }
+
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.xtest
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.xtest?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptCompilerTestCase.xtest
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 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.
+-->
+
+<testcase>
+  <roles>
+    <role name="org.apache.excalibur.xml.sax.SAXParser"
+      shorthand="xml-parser"
+      default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  </roles>
+ 
+  <components>
+    <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+      <parameter name="validate" value="false"/>
+      <parameter name="namespace-prefixes" value="false"/>
+      <parameter name="stop-on-warning" value="true"/>
+      <parameter name="stop-on-recoverable-error" value="true"/>
+      <parameter name="reuse-parsers" value="false"/>
+    </xml-parser>
+  </components>
+ 
+</testcase>
+ 

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-attribute.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-attribute.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-attribute.xml
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+
+<root attr1="1" attr2="2"/>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-element.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-element.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-element.xml
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+
+<root/>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression-output.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression-output.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression-output.xml
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+
+<root>2</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-expression.xml
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+
+<root>${1 + 1}</root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag-output.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag-output.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag-output.xml
        Tue Nov 30 15:41:24 2004
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root><item>1</item><item>1</item></root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvoker-tag.xml
       Tue Nov 30 15:41:24 2004
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+
+<root 
xmlns:test="testns"><test:duplicate><item>1</item></test:duplicate></root>

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.java
  Tue Nov 30 15:41:24 2004
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 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.cocoon.template.script;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ExtendedSitemapComponentTestCase;
+import org.apache.cocoon.el.GenericExpressionCompiler;
+import org.apache.cocoon.template.tag.samples.DuplicateTag;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+
+public class ScriptInvokerTestCase extends ExtendedSitemapComponentTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+    String docBase = "resource://org/apache/cocoon/template/script/";
+    ScriptCompiler compiler;
+    TagRepository tagRepository;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        tagRepository = new TagRepository();
+        tagRepository.enableLogging(getLogger());
+        compiler = new ScriptCompiler(tagRepository, GenericExpressionCompiler
+                .getInstance());
+    }
+
+    public Logger getLogger() {
+        return this.logger;
+    }
+
+    public void testElement() throws Exception {
+        String inputURI = docBase + "ScriptInvoker-element.xml";
+        parse(inputURI, compiler);
+        Script script = compiler.getScript();
+
+        DOMBuilder builder = new DOMBuilder();
+        ScriptInvoker invoker = new ScriptInvoker(script,
+                createContext(builder));
+        invoker.invoke();
+        assertEqual(load(inputURI), builder.getDocument());
+    }
+
+    public void testAttribute() throws Exception {
+        String inputURI = docBase + "ScriptInvoker-attribute.xml";
+        parse(inputURI, compiler);
+        Script script = compiler.getScript();
+
+        DOMBuilder builder = new DOMBuilder();
+        ScriptInvoker invoker = new ScriptInvoker(script,
+                createContext(builder));
+        invoker.invoke();
+        assertEqual(load(inputURI), builder.getDocument());
+    }
+
+    public void testTag() throws Exception {
+        String inputURI = docBase + "ScriptInvoker-tag.xml";
+        String outputURI = docBase + "ScriptInvoker-tag-output.xml";
+
+        tagRepository.registerTag("testns", "duplicate", DuplicateTag.class);
+        parse(inputURI, compiler);
+        Script script = compiler.getScript();
+
+        DOMBuilder builder = new DOMBuilder();
+        ScriptInvoker invoker = new ScriptInvoker(script,
+                createContext(builder));
+        invoker.invoke();
+        assertEqual(load(outputURI), builder.getDocument());
+    }
+
+    public void testExpression() throws Exception {
+        String inputURI = docBase + "ScriptInvoker-expression.xml";
+        String outputURI = docBase + "ScriptInvoker-expression-output.xml";
+
+        parse(inputURI, compiler);
+        Script script = compiler.getScript();
+
+        DOMBuilder builder = new DOMBuilder();
+        ScriptInvoker invoker = new ScriptInvoker(script,
+                createContext(builder));
+        invoker.invoke();
+        assertEqual(load(outputURI), builder.getDocument());
+    }
+
+    public ScriptContext createContext(XMLConsumer consumer) {
+        ScriptContext context = new ScriptContext();
+        context.setConsumer(consumer);
+        return context;
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.xtest
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.xtest?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/template/script/ScriptInvokerTestCase.xtest
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 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.
+-->
+
+<testcase>
+  <roles>
+    <role name="org.apache.excalibur.xml.sax.SAXParser"
+      shorthand="xml-parser"
+      default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  </roles>
+ 
+  <components>
+    <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+      <parameter name="validate" value="false"/>
+      <parameter name="namespace-prefixes" value="false"/>
+      <parameter name="stop-on-warning" value="true"/>
+      <parameter name="stop-on-recoverable-error" value="true"/>
+      <parameter name="reuse-parsers" value="false"/>
+    </xml-parser>
+  </components>
+ 
+</testcase>
+ 

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/ContextStackMapTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/ContextStackMapTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/ContextStackMapTestCase.java
   Tue Nov 30 15:41:24 2004
@@ -0,0 +1,129 @@
+/*
+ * Copyright 1999-2004 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.cocoon.util;
+
+import java.util.HashMap;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.container.ContainerTestCase;
+
+public class ContextStackMapTestCase extends ContainerTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    ContextStackMap map;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        map = new ContextStackMap();
+    }
+
+    public void testPutInRootContext() {
+        assertNull(map.put("key", "value1"));
+        assertEquals("value1", map.get("key"));
+        assertEquals("value1", map.put("key", "value2"));
+    }
+
+    public void testRemoveInRootContext() {
+        assertNull(map.remove("blah"));
+
+        map.put("key", "value");
+        assertEquals("value", map.remove("key"));
+        assertNull(map.remove("key"));
+    }
+
+    public void testPutInAddedContext1() {
+        map.pushContext();
+
+        assertNull(map.put("key2", "value2"));
+        assertEquals("value2", map.get("key2"));
+    }
+
+    public void testPutInAddedContext2() {
+        map.put("key1", "value1.1");
+        map.pushContext();
+
+        assertEquals("value1.1", map.put("key1", "value1.2"));
+        assertEquals("value1.2", map.get("key1"));
+        assertEquals("value1.2", map.put("key1", "value1.3"));
+    }
+
+    public void testRemoveInAddedContext1() {
+        map.pushContext();
+        map.put("key", "value");
+        assertEquals("value", map.remove("key"));
+        assertNull(map.remove("key"));
+    }
+
+    public void testRemoveInAddedContext2() {
+        map.put("key", "value1");
+        map.pushContext();
+        map.put("key", "value2");
+        assertEquals("value2", map.remove("key"));
+        assertNull(map.remove("key"));
+        map.popContext();
+        assertEquals("value1", map.get("key"));
+    }
+
+    public void testPopContext1() {
+        map.pushContext();
+        map.put("key", "value");
+        map.popContext();
+
+        assertNull(map.get("key"));
+    }
+
+    public void testPopContext2() {
+        map.put("key", "value1");
+        map.pushContext();
+
+        map.put("key", "value2");
+        map.popContext();
+
+        assertEquals("value1", map.get("key"));
+    }
+
+    public void testClear() {
+        map.put("key1", "value1");
+        map.pushContext();
+        map.put("key2", "value2");
+        map.clear();
+        assertNull(map.get("key1"));
+        assertNull(map.get("key2"));
+    }
+
+    public void testPutAll1() {
+        HashMap m = new HashMap();
+        m.put("key", "value");
+        map.putAll(m);
+        assertEquals("value", map.get("key"));
+    }
+
+    public void testPutAll2() {
+        HashMap m = new HashMap();
+        map.pushContext();
+        try {
+            map.putAll(m);
+            fail("Should throw IllegalStateException");
+        } catch (IllegalStateException e) {
+        }
+    }
+}
+

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/IncludingConfigurationTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/IncludingConfigurationTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/IncludingConfigurationTestCase.java
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 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.cocoon.util;
+
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ExtendedSitemapComponentTestCase;
+
+public class IncludingConfigurationTestCase extends
+        ExtendedSitemapComponentTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+
+    public Logger getLogger() {
+        return this.logger;
+    }
+
+    public void testInclude() throws Exception {
+        DefaultConfiguration conf = new DefaultConfiguration("root");
+        DefaultConfiguration includeNode = new DefaultConfiguration("include");
+        includeNode
+                
.setValue("resource://org/apache/cocoon/util/included-conf.xml");
+        conf.addChild(includeNode);
+
+        IncludingConfiguration resultConf = new IncludingConfiguration(conf,
+                getManager());
+        assertEquals("root", resultConf.getName());
+        assertNotNull(resultConf.getChild("node", false));
+        assertEquals("value", resultConf.getChild("node").getValue());
+        assertEquals(0, resultConf.getChildren("include").length);
+    }
+}
\ No newline at end of file

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/TypeUtilsTestCase.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/TypeUtilsTestCase.java?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/TypeUtilsTestCase.java
 Tue Nov 30 15:41:24 2004
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1999-2004 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.cocoon.util;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.container.ContainerTestCase;
+
+public class TypeUtilsTestCase extends ContainerTestCase {
+    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    Object[] ones = new Object[] { new Byte("1"), Boolean.TRUE,
+            new Double("1"), new Float("1"), new Integer("1"), new Long("1"),
+            new Short("1"), new String("1") };
+
+    Object[] zeroes = new Object[] { new Byte("0"), new Double("0"),
+            new Float("0"), new Integer("0"), new Long("0"), new Short("0") };
+
+    public void testConvert() {
+        for (int i = 0; i < ones.length; i++) {
+            for (int j = 0; j < ones.length; j++) {
+                Class fromType = ones[i].getClass();
+                Class toType = ones[j].getClass();
+
+                //System.out.println(fromType.getName() + " -> " +
+                // toType.getName());
+
+                // Handle these cases separately
+                if (fromType == Double.class && toType == String.class
+                        || fromType == Float.class && toType == String.class
+                        || fromType == String.class && toType == Boolean.class
+                        || fromType == Boolean.class && toType == 
String.class) {
+                    continue;
+                }
+
+                assertEquals(toType, TypeUtils.convert(ones[i], toType)
+                        .getClass());
+                assertEquals(ones[j], TypeUtils.convert(ones[i], toType));
+            }
+        }
+        assertEquals("1.0", TypeUtils.convert(new Double("1"), String.class));
+        assertEquals("1.0", TypeUtils.convert(new Float("1"), String.class));
+
+    }
+
+    public void testBooleanTrueSpecialCases() {
+        assertEquals(Boolean.TRUE, TypeUtils.convert("true", Boolean.class));
+        assertEquals("true", TypeUtils.convert(Boolean.TRUE, String.class));
+    }
+
+    public void testBooleanFalse() {
+        for (int i = 0; i < zeroes.length; i++) {
+            assertEquals(zeroes[i], TypeUtils.convert(Boolean.FALSE, zeroes[i]
+                    .getClass()));
+            assertEquals(Boolean.FALSE, TypeUtils.convert(zeroes[i],
+                    Boolean.class));
+        }
+
+        assertEquals(Boolean.FALSE, TypeUtils.convert("false", Boolean.class));
+        assertEquals("false", TypeUtils.convert(Boolean.FALSE, String.class));
+    }
+
+    public void testPrimitives() {
+        assertTrue(1 == TypeUtils.toByte("1"));
+        assertTrue(1 == TypeUtils.toDouble("1"));
+        assertTrue(1 == TypeUtils.toFloat("1"));
+        assertTrue(1 == TypeUtils.toInt("1"));
+        assertTrue(1 == TypeUtils.toLong("1"));
+        assertTrue(1 == TypeUtils.toShort("1"));
+        assertTrue(true == TypeUtils.toBoolean("true"));
+    }
+
+    public void testPrimitivesNull() {
+        assertTrue(0 == TypeUtils.toByte(null));
+        assertTrue(0 == TypeUtils.toDouble(null));
+        assertTrue(0 == TypeUtils.toFloat(null));
+        assertTrue(0 == TypeUtils.toInt(null));
+        assertTrue(0 == TypeUtils.toLong(null));
+        assertTrue(0 == TypeUtils.toShort(null));
+        assertTrue(false == TypeUtils.toBoolean(null));
+    }
+
+}
+

Added: 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/included-conf.xml
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/included-conf.xml?view=auto&rev=109259
==============================================================================
--- (empty file)
+++ 
cocoon/trunk/src/blocks/template/test/org/apache/cocoon/util/included-conf.xml  
    Tue Nov 30 15:41:24 2004
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+
+<root>
+  <node>value</node>
+</root>

Reply via email to