Index: org/apache/commons/jelly/TagSupport.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/jelly/src/java/org/apache/commons/jelly/TagSupport.java,v
retrieving revision 1.33
diff -u -r1.33 TagSupport.java
--- org/apache/commons/jelly/TagSupport.java 9 Sep 2004 12:25:40 -0000 1.33
+++ org/apache/commons/jelly/TagSupport.java 13 Oct 2004 04:25:00 -0000
@@ -19,11 +19,8 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
-import org.apache.commons.jelly.impl.CompositeTextScriptBlock;
-import org.apache.commons.jelly.impl.ScriptBlock;
-import org.apache.commons.jelly.impl.TextScript;
+import org.apache.commons.jelly.util.TagUtils;
/**
TagSupport an abstract base class which is useful to
* inherit from if developing your own tag.
@@ -242,55 +239,10 @@
/**
* Find all text nodes inside the top level of this body and
* if they are just whitespace then remove them
+ * @throws JellyTagException
*/
protected void trimBody() {
- synchronized(body) {
- // #### should refactor this code into
- // #### trimWhitespace() methods on the Script objects
-
- if ( body instanceof CompositeTextScriptBlock ) {
- CompositeTextScriptBlock block = (CompositeTextScriptBlock) body;
- List list = block.getScriptList();
- int size = list.size();
- if ( size > 0 ) {
- Script script = (Script) list.get(0);
- if ( script instanceof TextScript ) {
- TextScript textScript = (TextScript) script;
- textScript.trimStartWhitespace();
- }
- if ( size > 1 ) {
- script = (Script) list.get(size - 1);
- if ( script instanceof TextScript ) {
- TextScript textScript = (TextScript) script;
- textScript.trimEndWhitespace();
- }
- }
- }
- }
- else
- if ( body instanceof ScriptBlock ) {
- ScriptBlock block = (ScriptBlock) body;
- List list = block.getScriptList();
- for ( int i = list.size() - 1; i >= 0; i-- ) {
- Script script = (Script) list.get(i);
- if ( script instanceof TextScript ) {
- TextScript textScript = (TextScript) script;
- String text = textScript.getText();
- text = text.trim();
- if ( text.length() == 0 ) {
- list.remove(i);
- }
- else {
- textScript.setText(text);
- }
- }
- }
- }
- else if ( body instanceof TextScript ) {
- TextScript textScript = (TextScript) body;
- textScript.trimWhitespace();
- }
- }
+ TagUtils.trimScript(body);
}
/**
Index: org/apache/commons/jelly/impl/TagScript.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/jelly/src/java/org/apache/commons/jelly/impl/TagScript.java,v
retrieving revision 1.44
diff -u -r1.44 TagScript.java
--- org/apache/commons/jelly/impl/TagScript.java 16 Sep 2004 01:12:11 -0000 1.44
+++ org/apache/commons/jelly/impl/TagScript.java 13 Oct 2004 04:25:01 -0000
@@ -505,7 +505,8 @@
parentTag = parent.getTag();
}
tag.setParent( parentTag );
- tag.setBody( tagBody );
+ tag.setBody( new WeakReferenceWrapperScript(tagBody) );
+ //tag.setBody( tagBody );
if (tag instanceof NamespaceAwareTag) {
NamespaceAwareTag naTag = (NamespaceAwareTag) tag;
Index: org/apache/commons/jelly/impl/WeakReferenceWrapperScript.java
===================================================================
RCS file: org/apache/commons/jelly/impl/WeakReferenceWrapperScript.java
diff -N org/apache/commons/jelly/impl/WeakReferenceWrapperScript.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ org/apache/commons/jelly/impl/WeakReferenceWrapperScript.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2002,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.commons.jelly.impl;
+
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.jelly.JellyContext;
+import org.apache.commons.jelly.JellyException;
+import org.apache.commons.jelly.JellyTagException;
+import org.apache.commons.jelly.Script;
+import org.apache.commons.jelly.Tag;
+import org.apache.commons.jelly.XMLOutput;
+import org.apache.commons.jelly.tags.xml.ParamTag;
+import org.apache.commons.jelly.util.TagUtils;
+
+/** Wraps another Script instance in a WeakReference. Used to prevent
+ * a Tag class from holding a hard reference to its body script.
+ *
+ * If the underlying Script has been GC'd and is no longer available,
+ * an exception is thrown on any attempt to use this Script.
+ *
+ * WARNING: This class is not a permanent part of the API and will be removed or replaced in a future release.
+ * Don't extend it or use it unless you absolutely must.
+ *
+ * @author Hans Gilde
+ *
+ */
+public class WeakReferenceWrapperScript implements Script {
+ private WeakReference reference;
+
+ public WeakReferenceWrapperScript(Script script) {
+ reference = new WeakReference(script);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.jelly.Script#compile()
+ */
+ public Script compile() throws JellyException {
+ return script().compile();
+ }
+
+ /** Use this method to access the script.
+ * @throws JellyException If the script has been GC'd.
+ */
+ protected Script script() throws JellyTagException {
+ Script script = (Script) reference.get();
+
+ if (script == null) {
+ throw new JellyTagException("Attempt to use a script that has been garbage collected.");
+ }
+
+ return script;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.jelly.Script#run(org.apache.commons.jelly.JellyContext, org.apache.commons.jelly.XMLOutput)
+ */
+ public void run(JellyContext context, XMLOutput output)
+ throws JellyTagException {
+
+ script().run(context, output);
+ }
+
+ /**Trims the white space from the script and its children.
+ * TODO this code should be refactored into a formal part of the Script interface.
+ */
+ public void trimWhitespace() throws JellyTagException {
+ TagUtils.trimScript(script());
+ }
+
+ /** Determines if this script (the one in the WeakReference)
+ * or a child reference contains a Script
+ * that's of a particular class.
+ *
+ * This method is in place
+ * to support specific features in the XML tag library and
+ * shouldn't be used by anyone at all.
+ * This method will be removed in a near-future verison of jelly.
+ *
+ * This method will be removed in a near-future verison of jelly.
+ * XXX this is totally bogus and temporary, we should not need to check the type of scripts.
+ * @param clazz Find a script that's an instance of this classs.
+ * @throws JellyTagException
+ */
+ public boolean containsScriptType(Class clazz) throws JellyTagException {
+ Object bodyScript = script();
+
+ if (clazz.isInstance(bodyScript)) {
+ return true;
+ }
+
+ if (bodyScript instanceof ScriptBlock) {
+ ScriptBlock scriptBlock = (ScriptBlock) bodyScript;
+ List scriptList = scriptBlock.getScriptList();
+ for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) {
+ Script script = (Script) iter.next();
+ if (script instanceof StaticTagScript) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /** Locates all child TagScripts, whose tags are of the type
+ * given. These tags are executed with the provided JellyContext and output.
+ *
+ * This method is in place
+ * to support specific features in the XML tag library and
+ * shouldn't be used by anyone at all.
+ * This method will be removed in a near-future verison of jelly.
+ *
+ *
+ * XXX if possible, this is actually more bogus than "containsScriptType", it must be removed ASAP
+ *
+ * @param clazz Execute all child tags of this type
+ * @param output The output to use when executing the tags.
+ * @throws JellyTagException
+ */
+ public void invokeNestedTagsOfType(Class clazz, JellyContext context, XMLOutput output) throws JellyTagException {
+ Object bodyScript = script();
+
+ if (bodyScript instanceof ScriptBlock) {
+ ScriptBlock scriptBlock = (ScriptBlock) bodyScript;
+ List scriptList = scriptBlock.getScriptList();
+ for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) {
+ Script script = (Script) iter.next();
+ if (script instanceof TagScript) {
+
+ Tag tag = null;
+ try {
+ tag = ((TagScript) script).getTag();
+ } catch (JellyException e) {
+ throw new JellyTagException(e);
+ }
+
+ if (tag instanceof ParamTag) {
+ script.run(context, output);
+ }
+
+
+ }
+ }
+ }
+ }
+
+}
Index: org/apache/commons/jelly/util/TagUtils.java
===================================================================
RCS file: org/apache/commons/jelly/util/TagUtils.java
diff -N org/apache/commons/jelly/util/TagUtils.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ org/apache/commons/jelly/util/TagUtils.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2002,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.commons.jelly.util;
+
+import java.util.List;
+
+import org.apache.commons.jelly.JellyTagException;
+import org.apache.commons.jelly.Script;
+import org.apache.commons.jelly.impl.CompositeTextScriptBlock;
+import org.apache.commons.jelly.impl.ScriptBlock;
+import org.apache.commons.jelly.impl.TextScript;
+import org.apache.commons.jelly.impl.WeakReferenceWrapperScript;
+
+/** Contains static methods to help tag developers.
+ * @author Hans Gilde
+ *
+ */
+public class TagUtils {
+ private TagUtils() {
+
+ }
+
+ /** Trims the whitespace from a script and its children.
+ *
+ */
+ public static void trimScript(Script body) {
+ synchronized(body) {
+ // #### should refactor this code into
+ // #### trimWhitespace() methods on the Script objects
+
+ if (body instanceof WeakReferenceWrapperScript) {
+ WeakReferenceWrapperScript wrrs = (WeakReferenceWrapperScript) body;
+ try {
+ wrrs.trimWhitespace();
+ } catch (JellyTagException e) {
+ //TODO handle this exception once the Tag interface allows JellyTagException to be thrown
+ return;
+ }
+ } else if ( body instanceof CompositeTextScriptBlock ) {
+ CompositeTextScriptBlock block = (CompositeTextScriptBlock) body;
+ List list = block.getScriptList();
+ int size = list.size();
+ if ( size > 0 ) {
+ Script script = (Script) list.get(0);
+ if ( script instanceof TextScript ) {
+ TextScript textScript = (TextScript) script;
+ textScript.trimStartWhitespace();
+ }
+ if ( size > 1 ) {
+ script = (Script) list.get(size - 1);
+ if ( script instanceof TextScript ) {
+ TextScript textScript = (TextScript) script;
+ textScript.trimEndWhitespace();
+ }
+ }
+ }
+ }
+ else
+ if ( body instanceof ScriptBlock ) {
+ ScriptBlock block = (ScriptBlock) body;
+ List list = block.getScriptList();
+ for ( int i = list.size() - 1; i >= 0; i-- ) {
+ Script script = (Script) list.get(i);
+ if ( script instanceof TextScript ) {
+ TextScript textScript = (TextScript) script;
+ String text = textScript.getText();
+ text = text.trim();
+ if ( text.length() == 0 ) {
+ list.remove(i);
+ }
+ else {
+ textScript.setText(text);
+ }
+ }
+ }
+ }
+ else if ( body instanceof TextScript ) {
+ TextScript textScript = (TextScript) body;
+ textScript.trimWhitespace();
+ }
+ }
+ }
+
+}