You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2008/09/15 16:21:35 UTC

svn commit: r695481 [2/2] - in /incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH: doc/ tests/com/ecyrd/jspwiki/ui/stripes/ tests/com/ecyrd/jspwiki/util/

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,726 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.*;
+
+/**
+ * Parser that reads JSP document and constructs a {@link JspDocument} with the
+ * results.
+ */
+class JspParser
+{
+    private static final class Counter
+    {
+        private int m_pos;
+
+        Counter()
+        {
+            m_pos = 0;
+        }
+
+        public void increment()
+        {
+            m_pos++;
+        }
+
+        public int position()
+        {
+            return m_pos;
+        }
+    }
+
+    private enum NodeLifecycle
+    {
+        TAG_RESOLUTION,
+        /**
+         * Characters after the directive tag start (<) and whitespace, but
+         * before whitespace that delimit the attributes.
+         */
+        /**
+         * Characters after the opening left bracket (<), but before
+         * whitespace that delimit the attributes.
+         */
+        TAG_NAME,
+        /**
+         * After <@ that determines that it's a JSP element, but before we
+         * know for sure what it is.
+         */
+        JSP_DIRECTIVE_NAME,
+        /**
+         * Whitespace between the node name and the first attribute, and between
+         * attributes.
+         */
+        BETWEEN_ATTRIBUTES,
+        /**
+         * Characters that name an attribute, after whitespace but before the
+         * equals (=) character.
+         */
+        ATTRIBUTE_NAME,
+        /**
+         * When the current character is the equals (=) character that separates
+         * the attribute name and value.
+         */
+        ATTRIBUTE_EQUALS,
+        /**
+         * The opening quote, closing quote, and all characters in between, that
+         * denote an attribute's value.
+         */
+        ATTRIBUTE_VALUE,
+        /** Any outside of a tag or element (i.e., part of a text node). */
+        TEXT_NODE,
+        /** Any text inside of a scriptlet, JSP comment, or JSP declaration. */
+        CODE_OR_COMMENT,
+    }
+
+    /**
+     * Encapsulates the current state of document parsing.
+     */
+    private static class ParseContext
+    {
+        private Node m_node = null;
+
+        private Attribute m_attribute = null;
+
+        private Counter m_counter = null;;
+
+        private NodeLifecycle m_stage = NodeLifecycle.TEXT_NODE;
+
+        public ParseContext( Counter counter )
+        {
+            m_counter = counter;
+        }
+        
+        private Map<NodeLifecycle,Integer> m_markers = new HashMap<NodeLifecycle,Integer>();
+
+        /**
+         * Sets a "marker" for the current stage (as reported by
+         * {@link #getStage()} at the current position (as reported by
+         * {@link #position()}. The marker can be retrieved later via
+         * {@link #getMarker(com.ecyrd.jspwiki.ui.stripes.JspParser.NodeLifecycle)}.
+         * Callers may place only one marker per lifecycle stage. Generally,
+         * markers are used to set character positions that are important to
+         * retrieve later, for example the position of the left angle-bracket
+         * during the {@link NodeLifecycle#TAG_RESOLUTION} stage.
+         */
+        public void mark()
+        {
+            m_markers.put( getStage(), position() );
+        }
+
+        /**
+         * Retrieves the position of the marker set for the current stage (as set by {@link #mark()}).
+         * If no marker was set, this method returns {@link Node#POSITION_NOT_SET}.
+         * @param stage the stage for which the marker position is desired
+         * @return the position of the marker.
+         */
+        public int getMarker( NodeLifecycle stage )
+        {
+            Integer mark = m_markers.get( stage );
+            return mark == null ? Node.POSITION_NOT_SET : mark.intValue();
+        }
+
+        public Attribute getAttribute()
+        {
+            return m_attribute;
+        }
+
+        public Counter getCounter()
+        {
+            return m_counter;
+        }
+
+        public Node getNode()
+        {
+            return m_node;
+        }
+
+        public NodeLifecycle getStage()
+        {
+            return m_stage;
+        }
+
+        public void incrementPosition()
+        {
+            m_counter.increment();
+        }
+
+        public int position()
+        {
+            return m_counter.position();
+        }
+
+        public void setAttribute( Attribute attribute )
+        {
+            m_attribute = attribute;
+        }
+
+        public void setNode( Node node )
+        {
+            m_node = node;
+        }
+
+        public void setStage( NodeLifecycle stage )
+        {
+            m_stage = stage;
+        }
+    }
+
+    private final List<Integer> lineBreaks = new ArrayList<Integer>();
+
+    private JspDocument doc = null;
+
+    protected Stack<ParseContext> contextStack = new Stack<ParseContext>();
+
+    private Stack<Node> nodeStack = new Stack<Node>();
+
+    private String m_source;
+
+    /** The current parsing context. */
+    private ParseContext context;
+
+    /**
+     * Constructs a new JspDocument.
+     */
+    public JspParser()
+    {
+        super();
+    }
+
+    /**
+     * Parses a JSP file, supplied as a String, into Nodes.
+     * 
+     * @param m_source the JSP file contents
+     */
+    public JspDocument parse( String source )
+    {
+        // Initialize the cached document, m_source, and stack variables
+        this.doc = new JspDocument();
+        m_source = source;
+        contextStack.clear();
+        nodeStack.clear();
+        nodeStack.push( doc.getRoot() );
+
+        // Create new parse context and put it on the stack
+        context = new ParseContext( new Counter() );
+        initText( context.position() );
+
+        // Initialize parser delegates
+        ParserDelegate textParser = new TextParser();
+
+        // Parse the file, character by character
+        for( char currentChar : source.toCharArray() )
+        {
+            // Is the current character whitespace?
+            boolean isWhitespace = Character.isWhitespace( currentChar );
+            char ch = isWhitespace ? ' ' : currentChar; // For case statements
+            int pos = context.position();
+
+            switch( context.getStage() )
+            {
+                // Part of a text node.
+                case TEXT_NODE: {
+                    textParser.handle( ch, context );
+                    switch( ch )
+                    {
+                        // If we see a quote, check to see if it's a part of a
+                        // parent attribute
+                        case ('\''):
+                        case ('"'): {
+                            if( contextStack.size() > 0 )
+                            {
+                                Attribute parentAttribute = contextStack.peek().getAttribute();
+                                if( parentAttribute != null && ch == parentAttribute.getAttributeDelimiter() )
+                                {
+                                    // Finish the current text node and attach
+                                    // it to the parent attribute
+                                    finalizeText();
+
+                                    // Restore the parent ParseContext and Node
+                                    context = contextStack.pop();
+                                    nodeStack.pop();
+
+                                    // Finish the parent attribute
+                                    finalizeAttribute();
+                                }
+                            }
+                            break;
+                        }
+                        case ('<'): {
+                            // Finalize current node and start a new
+                            // (unresolved) one
+                            finalizeText();
+                            initTag( NodeType.UNRESOLVED, context.position() );
+                            context.setStage( NodeLifecycle.TAG_RESOLUTION );
+                            break;
+                        }
+                    }
+                    break;
+                }
+
+                case TAG_RESOLUTION: {
+                    Node node = context.getNode();
+                    switch( node.getType() )
+                    {
+
+                        case UNRESOLVED: {
+                            switch( ch )
+                            {
+                                // If <%, it's a JSP element
+                                case ('%'): {
+                                    // Re-initialize the node as a JSPMarkup
+                                    // node
+                                    initJspMarkup();
+                                    break;
+                                }
+
+                                    // If </, it's an HTML end tag
+                                case ('/'): {
+                                    // Re-initialize the node as an end tag
+                                    initTag( NodeType.HTML_END_TAG, node.getStart() );
+                                    context.setStage( NodeLifecycle.TAG_NAME );
+                                    break;
+                                }
+
+                                    // If < plus space, it's just ordinary
+                                    // (albeit sloppy) markup
+                                case (' '): {
+                                    // Re-initialize the node as a text node
+                                    initText( node.getStart() );
+                                    context.setStage( NodeLifecycle.TEXT_NODE );
+                                    break;
+                                }
+
+                                    // Any other char means its HTML start tag
+                                    // or combined tag
+                                default: {
+                                    node.setType( NodeType.UNRESOLVED_HTML_TAG );
+                                    context.setStage( NodeLifecycle.TAG_NAME );
+                                }
+                            }
+                            break;
+                        }
+
+                            // If JSP element, next character narrows it down
+                        case UNRESOLVED_JSP_TAG: {
+                            switch( ch )
+                            {
+                                // Dash after <% means hidden JSP
+                                // comment
+                                case ('-'): {
+                                    node.setType( NodeType.JSP_COMMENT );
+                                    context.setStage( NodeLifecycle.CODE_OR_COMMENT );
+                                    break;
+                                }
+
+                                    // Bang after <% means JSP
+                                    // declaration
+                                case ('!'): {
+                                    node.setType( NodeType.JSP_DECLARATION );
+                                    context.setStage( NodeLifecycle.CODE_OR_COMMENT );
+                                    break;
+                                }
+
+                                    // Equals after <% means JSP
+                                    // expression
+                                case ('='): {
+                                    node.setType( NodeType.JSP_EXPRESSION );
+                                    context.setStage( NodeLifecycle.CODE_OR_COMMENT );
+                                    break;
+                                }
+
+                                    // At-sign after <% means JSP
+                                    // directive
+                                case ('@'): {
+                                    // Re-initialize the node as a JspDirective
+                                    initJspDirective();
+                                    context.setStage( NodeLifecycle.BETWEEN_ATTRIBUTES );
+                                    break;
+                                }
+
+                                    // Whitespace after <% means
+                                    // scriptlet
+                                case (' '): {
+                                    node.setType( NodeType.SCRIPTLET );
+                                    context.setStage( NodeLifecycle.CODE_OR_COMMENT );
+                                    break;
+                                }
+                            }
+                            break;
+                        }
+                    }
+                    break;
+                }
+
+                case CODE_OR_COMMENT: {
+                    switch( ch )
+                    {
+                        // Terminating %> means the end of the scriptlet
+                        case ('>'): {
+                            if( source.charAt( pos - 1 ) == '%' )
+                            {
+                                finalizeJspMarkup();
+                                initText( pos + 1 );
+                            }
+                            break;
+                        }
+                    }
+                    break;
+                }
+
+                    // Characters that supply the JSP directive name.
+                case JSP_DIRECTIVE_NAME: {
+                    if( isWhitespace )
+                    {
+                        Node node = context.getNode();
+                        Attribute directive = context.getAttribute();
+                        node.setName( m_source.substring( directive.getStart(), context.position() ) );
+                        context.setAttribute( null );
+                        context.setStage( NodeLifecycle.BETWEEN_ATTRIBUTES );
+                    }
+                    break;
+                }
+
+                    // After < but before whitespace that delimit attributes.
+                case TAG_NAME: {
+                    switch( ch )
+                    {
+                        // If current character is whitespace, set the name and
+                        // move
+                        // to attributes stage
+                        case (' '): {
+                            finalizeTagName();
+                            context.setStage( NodeLifecycle.BETWEEN_ATTRIBUTES );
+                            break;
+                        }
+
+                            // Right angle bracket == end of the node
+                        case ('>'): {
+                            finalizeTagName();
+                            finalizeNode( pos + 1 );
+                            initText( pos + 1 );
+                            break;
+                        }
+                    }
+                    break;
+                }
+
+                    // Whitespace between node name and first attribute, or
+                    // between attributes.
+                case BETWEEN_ATTRIBUTES: {
+                    switch( ch )
+                    {
+                        case (' '): {
+                            break;
+                        }
+                        case ('/'): {
+                            // Ignore the / because we might be in HTML
+                            // combined tag
+                            break;
+                        }
+                        case ('%'): {
+                            // Ignore the % because we might be in a JSP
+                            // directive/element
+                            break;
+                        }
+                        case ('>'): {
+                            finalizeNode( pos + 1 );
+                            initText( pos + 1 );
+                            break;
+                        }
+                        default:
+                            initAttribute();
+                    }
+                    break;
+                }
+
+                    // Characters that name an attribute, after whitespace but
+                    // before equals (=).
+                case ATTRIBUTE_NAME: {
+                    if( ch == '=' )
+                    {
+                        Attribute attribute = context.getAttribute();
+                        attribute.setName( m_source.substring( attribute.getStart(), pos ) );
+                        context.setStage( NodeLifecycle.ATTRIBUTE_EQUALS );
+                    }
+                    break;
+                }
+
+                    // The equals (=) that separates the attribute name and
+                    // value.
+                case ATTRIBUTE_EQUALS: {
+                    if( ch == '\'' || ch == '\"' )
+                    {
+                        // Save the quote delimiter for later
+                        Attribute attribute = context.getAttribute();
+                        attribute.setAttributeDelimiter( ch );
+
+                        // Push current ParseContext and Node onto stack
+                        contextStack.push( context );
+                        nodeStack.push( attribute );
+
+                        // Create new context, with text node as child of
+                        // attribute
+                        context = new ParseContext( context.getCounter() );
+                        initText( context.position() + 1 );
+                        context.getNode().setParent( attribute );
+                    }
+                    break;
+                }
+
+            }
+
+            // Reset the line/column counters if we encounter linebreaks
+            if( currentChar == '\r' || currentChar == '\n' )
+            {
+                lineBreaks.add( pos );
+            }
+
+            // Increment the character position
+            context.incrementPosition();
+        }
+
+        // Finalize the last node and return the parsed JSP
+        finalizeNode( context.position() );
+        return doc;
+    }
+
+    private void finalizeJspMarkup()
+    {
+        Node node = context.getNode();
+        NodeType type = node.getType();
+
+        // Set the end position
+        node.setEnd( context.position() + 1 );
+
+        node.setValue( m_source
+            .substring( node.getStart() + type.getTagStart().length(), node.getEnd() - type.getTagEnd().length() ) );
+
+        // If node length is > 0, add it to the parent
+        if( node.getEnd() > node.getStart() )
+        {
+            node.getParent().addChild( node );
+        }
+    }
+
+    private void finalizeAttribute()
+    {
+        Attribute attribute = context.getAttribute();
+        Node node = attribute.getParent();
+        attribute.setEnd( context.position() + 1 );
+        if( node.isHtmlNode() )
+        {
+            ((Tag) node).addAttribute( attribute );
+        }
+        else if( node.getType() == NodeType.JSP_DIRECTIVE )
+        {
+            ((JspDirective) node).addAttribute( attribute );
+        }
+        context.setAttribute( null );
+        context.setStage( NodeLifecycle.BETWEEN_ATTRIBUTES );
+    }
+
+    private void finalizeText()
+    {
+        Node node = context.getNode();
+
+        // Set the end position
+        node.setEnd( context.position() );
+
+        node.setValue( m_source.substring( node.getStart(), node.getEnd() ) );
+
+        // If node length is > 0, add it to the parent
+        if( node.getEnd() > node.getStart() )
+        {
+            node.getParent().addChild( node );
+        }
+    }
+
+    /**
+     * Finalizes the current Tag (returned by {@link ParseContext#getNode()}),
+     * adds it as a child to the parent node, and initializes a new {@link Text}
+     * node that will begin at a specified character position. The parent node
+     * is determined by taking the Node currently at the top of the internal
+     * node stack.
+     * 
+     * @param pos the desired start position for the new text node
+     */
+    private void finalizeNode( int pos )
+    {
+        Node node = context.getNode();
+        NodeType type = node.getType();
+
+        // Set the end position
+        node.setEnd( pos );
+
+        // Finalize the node type if it is still undefined
+        if( type == NodeType.UNRESOLVED_HTML_TAG )
+        {
+            char lastCh = m_source.charAt( pos - 2 );
+            if( lastCh == '/' )
+            {
+                node.setType( NodeType.HTML_COMBINED_TAG );
+            }
+            else
+            {
+                // If no /, it's an HTML start tag, and new nodes should be
+                // children of it
+                node.setType( NodeType.HTML_START_TAG );
+                nodeStack.push( node );
+            }
+        }
+        else if( type == NodeType.TEXT )
+        {
+            node.setValue( m_source.substring( node.getStart(), node.getEnd() ) );
+        }
+        else if( node.isJspNode() )
+        {
+            node.setValue( m_source.substring( node.getStart() + type.getTagStart().length(), node.getEnd()
+                                                                                              - type.getTagEnd().length() ) );
+        }
+
+        // If node length is > 0, add it to the parent
+        if( node.getEnd() > node.getStart() )
+        {
+            node.getParent().addChild( node );
+        }
+    }
+
+    private void finalizeTagName()
+    {
+        Node node = context.getNode();
+        int nameStart = node.getStart() + node.getType().getTagStart().length();
+        int pos = context.position();
+        if( pos - nameStart > 0 )
+        {
+            node.setName( m_source.substring( nameStart, pos ) );
+        }
+    }
+
+    private void initAttribute()
+    {
+        Attribute attribute = new Attribute( doc );
+        attribute.setParent( context.getNode() );
+        context.setAttribute( attribute );
+
+        // Set the start, end, linebreak
+        updatePosition( attribute, context.position() );
+
+        // Set the correct lifecycle stage
+        Node node = context.getNode();
+        if( node.getType() == NodeType.JSP_DIRECTIVE && node.getName() == null )
+        {
+            context.setStage( NodeLifecycle.JSP_DIRECTIVE_NAME );
+        }
+        else
+        {
+            context.setStage( NodeLifecycle.ATTRIBUTE_NAME );
+        }
+    }
+
+    /**
+     * Sets the start, end and line/column positions for a supplied node, based
+     * on the position in the ParseContext.
+     * 
+     * @param node the node to set
+     */
+    private void updatePosition( Node node, int pos )
+    {
+        // Set the start, end, linebreak
+        node.setStart( pos );
+        int lastLineBreakPos = lineBreaks.size() == 0 ? Node.POSITION_NOT_SET : lineBreaks.get( lineBreaks.size() - 1 );
+        node.setLine( lineBreaks.size() + 1 );
+        node.setColumn( pos - lastLineBreakPos );
+    }
+
+    /**
+     * Factory method that returns a new JspDirective node.
+     */
+    private void initJspDirective()
+    {
+        // Create new JspDirective
+        JspDirective node = new JspDirective( doc );
+
+        // Set parent relationship
+        node.setParent( nodeStack.peek() );
+        context.setNode( node );
+        context.setAttribute( null );
+
+        // Set the start, end, linebreak
+        updatePosition( node, context.position() - 2 );
+    }
+
+    /**
+     * Factory method that returns a new JspMarkup node.
+     */
+    private void initJspMarkup()
+    {
+        // Create new JspMarkup
+        JspMarkup node = new JspMarkup( doc, NodeType.UNRESOLVED_JSP_TAG );
+
+        // Set parent relationship
+        node.setParent( nodeStack.peek() );
+        context.setNode( node );
+        context.setAttribute( null );
+
+        // Set the start, end, linebreak
+        updatePosition( node, context.position() - 1 );
+    }
+
+    /**
+     * Factory method that constructs and returns a new Tag. When constructed,
+     * the node's start position, line number, column number and level are set
+     * automatically based on JspDocument's internal cache of line-breaks and
+     * nodes. Note that the new node is not actually added to the internal node
+     * tree until the method {@link #finalizeNode(Node, int)} is called.
+     * 
+     * @param type the node type
+     * @param pos the start position for the tag
+     */
+    private void initTag( NodeType type, int pos )
+    {
+        // Create new Tag
+        Tag tag = new Tag( doc, type );
+
+        // If HTML end tag, pop the node stack first
+        if( tag.getType() == NodeType.HTML_END_TAG )
+        {
+            nodeStack.pop();
+        }
+
+        // Set parent relationship
+        tag.setParent( nodeStack.peek() );
+        context.setNode( tag );
+        context.setAttribute( null );
+
+        // Set the start, end, linebreak
+        updatePosition( tag, pos );
+    }
+
+    private void initText( int pos )
+    {
+        // Create new Text
+        Text text = new Text( doc );
+
+        // Set parent relationship
+        text.setParent( nodeStack.peek() );
+        context.setNode( text );
+        context.setAttribute( null );
+
+        // Set the start, end, linebreak
+        updatePosition( text, pos );
+        context.setStage( NodeLifecycle.TEXT_NODE );
+    }
+
+    public static abstract class ParserDelegate
+    {
+        public abstract void handle( char ch, ParseContext context );
+    }
+
+    public static class TextParser extends ParserDelegate
+    {
+        public void handle( char ch, ParseContext context )
+        {
+        }
+
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,499 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.io.File;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+public class JspParserTest extends TestCase
+{
+    public JspParserTest( String s )
+    {
+        super( s );
+    }
+
+    public void testParse() throws Exception
+    {
+        JspMigrator m = new JspMigrator();
+        File src = new File( "src/webdocs/LoginForm.jsp" );
+        String s = m.readSource( src );
+
+        // Parse the contents of the file
+        JspParser parser = new JspParser();
+        JspDocument doc = parser.parse( s );
+
+        // Should result in 18 nodes parsed (10 tags/directives + 8 text/whitespace nodes
+        Node node;
+        Node attribute;
+        List<Node> nodes = doc.getNodes();
+        assertEquals( 18, nodes.size() );
+        int i = 0;
+
+        // Test line 1 aka nodes 0+1
+        node = nodes.get( i );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 0, node.getStart() );
+        assertEquals( 39, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "org.apache.log4j.*", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 40, node.getColumn() );
+        assertEquals( 39, node.getStart() );
+        assertEquals( 40, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+        
+        // Test line 2 aka nodes 2+3
+        node = nodes.get( i );
+        assertEquals( 2, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 40, node.getStart() );
+        assertEquals( 80, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "com.ecyrd.jspwiki.*", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 2, node.getLine() );
+        assertEquals( 41, node.getColumn() );
+        assertEquals( 80, node.getStart() );
+        assertEquals( 81, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+
+        // Test line 3 aka nodes 4+5
+        node = nodes.get( i );
+        assertEquals( 3, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 81, node.getStart() );
+        assertEquals( 128, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "com.ecyrd.jspwiki.action.*", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 3, node.getLine() );
+        assertEquals( 48, node.getColumn() );
+        assertEquals( 128, node.getStart() );
+        assertEquals( 129, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+        
+        // Test line 4 aka nodes 6+7
+        node = nodes.get( i );
+        assertEquals( 4, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 129, node.getStart() );
+        assertEquals( 163, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "errorPage", attribute.getName() );
+        assertEquals( "/Error.jsp", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 4, node.getLine() );
+        assertEquals( 35, node.getColumn() );
+        assertEquals( 163, node.getStart() );
+        assertEquals( 164, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+        
+        // Test line 5 aka nodes 8+9
+        node = nodes.get( i );
+        assertEquals( 5, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 164, node.getStart() );
+        assertEquals( 218, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "taglib", node.getName() );
+        assertEquals( 2, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "uri", attribute.getName() );
+        assertEquals( "/WEB-INF/jspwiki.tld", attribute.getValue() );
+        attribute = ((JspDirective)node).getAttributes().get( 1 );
+        assertEquals( "prefix", attribute.getName() );
+        assertEquals( "wiki", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 5, node.getLine() );
+        assertEquals( 55, node.getColumn() );
+        assertEquals( 218, node.getStart() );
+        assertEquals( 219, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+
+        // Test line 6 aka nodes 10+11
+        node = nodes.get( i );
+        assertEquals( 6, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 219, node.getStart() );
+        assertEquals( 276, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "taglib", node.getName() );
+        assertEquals( 2, ((JspDirective)node).getAttributes().size() );
+        attribute = ((JspDirective)node).getAttributes().get( 0 );
+        assertEquals( "uri", attribute.getName() );
+        assertEquals( "/WEB-INF/stripes.tld", attribute.getValue() );
+        attribute = ((JspDirective)node).getAttributes().get( 1 );
+        assertEquals( "prefix", attribute.getName() );
+        assertEquals( "stripes", attribute.getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 6, node.getLine() );
+        assertEquals( 58, node.getColumn() );
+        assertEquals( 276, node.getStart() );
+        assertEquals( 277, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+        
+        // Test line 7 aka nodes 12+13
+        node = nodes.get( i );
+        assertEquals( 7, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 277, node.getStart() );
+        assertEquals( 354, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "stripes:useActionBean", node.getName() );
+        
+        // AbstractNode 12 should have 1 attribute: beanclass="com.ecyrd.jspwiki.action.LoginActionBean"
+        assertEquals( 1, ((Tag)node).getAttributes().size() );
+        attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( "beanclass", attribute.getName() );
+        assertEquals ( NodeType.ATTRIBUTE, attribute.getType());
+        assertEquals( "com.ecyrd.jspwiki.action.LoginActionBean", attribute.getValue() );
+        assertEquals( 'c', ((Tag)node).getAttributes().get( 0 ).getValue().charAt( 0 ) );
+        i++;
+        
+        // Test line 7, node 13 (line break)
+        node = nodes.get( i );
+        assertEquals( 7, node.getLine() );
+        assertEquals( 78, node.getColumn() );
+        assertEquals( 354, node.getStart() );
+        assertEquals( 355, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+
+        // Test lines 8-19 aka nodes 14+15
+        node = nodes.get( i );
+        assertEquals( 8, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 355, node.getStart() );
+        assertEquals( 767, node.getEnd() );
+        assertEquals( NodeType.JSP_DECLARATION, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 19, node.getLine() );
+        assertEquals( 3, node.getColumn() );
+        assertEquals( 767, node.getStart() );
+        assertEquals( 768, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "(TEXT)", node.getName() );
+        i++;
+        
+        // Test line 20-33 aka node 16
+        node = nodes.get( i );
+        assertEquals( 20, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 768, node.getStart() );
+        assertEquals( 1513, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.SCRIPTLET, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        i++;
+        
+        // Test second tag on line 33 aka node 17
+        node = nodes.get( i );
+        assertEquals( 33, node.getLine() );
+        assertEquals( 3, node.getColumn() );
+        assertEquals( 1513, node.getStart() );
+        assertEquals( 1553, node.getEnd() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "wiki:Include", node.getName() );
+        
+        // AbstractNode 17 should have 1 attribute: page="<%=contentPage%>" 
+        assertEquals( 1, ((Tag)node).getAttributes().size() );
+        attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( "page", attribute.getName() );
+        assertEquals ( NodeType.ATTRIBUTE, attribute.getType());
+        assertEquals( "<%=contentPage%>", attribute.getValue() );
+        assertEquals( 1, attribute.getChildren().size() );
+        assertEquals ( NodeType.JSP_EXPRESSION, attribute.getChildren().get( 0 ).getType() );
+        assertEquals ( "contentPage", attribute.getChildren().get( 0 ).getValue() );
+        i++;
+    }
+    
+    public void testParseNestedTags() {
+        String s= "  <foo attribute1=\"1\">  <bar attribute2=\"2\" attribute3=\"3\"/>  </foo>  ";
+        JspDocument doc = new JspParser().parse( s );
+        
+        // Total number of nodes (depth-first search) is 7
+        List<Node> nodes = doc.getNodes();
+        Node node;
+        Node attribute;
+        assertEquals( 7, nodes.size());
+        
+        // First, check the root node. Should have 4 children (2 text nodes + 2 html nodes)
+        node = doc.getRoot();
+        assertEquals( 4, node.getChildren().size() );
+        
+        // AbstractNode 0 is whitespace
+        node = nodes.get( 0 );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "(TEXT)", node.getName() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( doc.getRoot(), node.getParent() );
+        assertEquals( 0, node.getStart() );
+        assertEquals( 2, node.getEnd() );
+        
+        // AbstractNode 1 is <foo> with 1 attribute
+        node = nodes.get( 1 );
+        assertEquals( NodeType.HTML_START_TAG, node.getType() );
+        assertEquals( "<foo attribute1=\"1\">",  node.toString() );
+        assertEquals( "foo",  node.getName() );
+        assertEquals( "  <bar attribute2=\"2\" attribute3=\"3\"/>  ",  node.getValue() );
+        assertEquals( 2, node.getStart() );
+        assertEquals( 22, node.getEnd() );
+        
+        // AbstractNode 1: attributes test
+        assertEquals( 1, ((Tag)node).getAttributes().size() );
+        attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( "attribute1", attribute.getName() );
+        assertEquals( "1", attribute.getValue() );
+        assertEquals( 7, attribute.getStart() );
+        assertEquals( 21, attribute.getEnd() );
+        
+        // AbstractNode 1 also has 3 child elements: <bar> plus two whitespace nodes
+        assertEquals( 3, node.getChildren().size() );
+        
+        // Check AbstractNode 1, child 0 -- should be whitespace
+        node = nodes.get( 1 ).getChildren().get( 0 );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "(TEXT)",  node.getName() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( nodes.get( 1 ), node.getParent() );
+        assertEquals( 22, node.getStart() );
+        assertEquals( 24, node.getEnd() );
+        
+        // Check AbstractNode 1, child 1 -- should be <bar>
+        node = nodes.get( 1 ).getChildren().get( 1 );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( "<bar attribute2=\"2\" attribute3=\"3\"/>", node.toString() );
+        assertEquals( "bar", node.getName() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( 24, node.getStart() );
+        assertEquals( 60, node.getEnd() );
+        assertEquals( 2, ((Tag)node).getAttributes().size() );
+        assertEquals( "attribute2", ((Tag)node).getAttributes().get( 0 ).getName() );
+        assertEquals( "2", ((Tag)node).getAttributes().get( 0 ).getValue() );
+        assertEquals( "attribute3", ((Tag)node).getAttributes().get( 1 ).getName() );
+        assertEquals( "3", ((Tag)node).getAttributes().get( 1 ).getValue() );
+        
+        // Check AbstractNode 1, child 2 -- should be whitespace
+        node = nodes.get( 1 ).getChildren().get( 2 );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "(TEXT)",  node.getName() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( nodes.get( 1 ), node.getParent() );
+        assertEquals( 60, node.getStart() );
+        assertEquals( 62, node.getEnd() );
+
+        // AbstractNode 5 (</foo) has no attributes
+        node = nodes.get( 5 );
+        assertEquals( NodeType.HTML_END_TAG, node.getType() );
+        assertEquals( null,  node.getValue() );
+        assertEquals( "foo",  node.getName() );
+        assertEquals( 0, ((Tag)node).getAttributes().size() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( 62, node.getStart() );
+        assertEquals( 68, node.getEnd() );
+        
+        // AbstractNode 6 is whitespace
+        node = nodes.get( 6 );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "(TEXT)",  node.getName() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( doc.getRoot(), node.getParent() );
+        assertEquals( 68, node.getStart() );
+        assertEquals( 70, node.getEnd() );
+
+        // The children of AbstractNode 1 == Nodes 2, 3 and 4 from doc.getNodes()
+        node = nodes.get( 1 );
+        assertEquals( nodes.get( 2 ), node.getChildren().get( 0 ) );
+        assertEquals( nodes.get( 3 ), node.getChildren().get( 1 ) );
+        assertEquals( nodes.get( 4 ), node.getChildren().get( 2 ) );
+        
+    }
+    
+    public void testParseNestedExpression()
+    {
+        String s = "  <wiki:Include page=\"<%=contentPage%>\" var=\'Foo\' />  ";
+        JspDocument doc = new JspParser().parse( s );
+        
+        List<Node> nodes = doc.getNodes();
+        Node node;
+        assertEquals( 3, nodes.size());
+        
+        // AbstractNode 1: text node
+        node = nodes.get( 0 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 0, node.getStart() );
+        assertEquals( 2, node.getEnd() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( "(TEXT)", node.getName() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+        
+        // AbstractNode 2: HTML tag with attribute containing JSP expression
+        node = nodes.get( 1 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 3, node.getColumn() );
+        assertEquals( 2, node.getStart() );
+        assertEquals( 52, node.getEnd() );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( "<wiki:Include page=\"<%=contentPage%>\" var=\'Foo\'/>", node.toString() );
+        assertEquals( "wiki:Include", node.getName() );
+        assertEquals( null, node.getValue() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+        
+        // AbstractNode 2: test attributes
+        assertEquals( 2, ((Tag)node).getAttributes().size() );
+        Node attribute;
+        attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( NodeType.ATTRIBUTE, attribute.getType() );
+        assertEquals( "page", attribute.getName() );
+        assertEquals( "<%=contentPage%>", attribute.getValue() );
+        assertEquals( 1, attribute.getChildren().size() );
+        assertEquals( NodeType.JSP_EXPRESSION, attribute.getChildren().get( 0 ).getType() );
+        assertEquals( "contentPage", attribute.getChildren().get( 0 ).getValue() );
+        
+        attribute = ((Tag)node).getAttributes().get( 1 );
+        assertEquals( NodeType.ATTRIBUTE, attribute.getType() );
+        assertEquals( "var", attribute.getName() );
+        assertEquals( "Foo", attribute.getValue() );
+        assertEquals( 1, attribute.getChildren().size() );
+        assertEquals( NodeType.TEXT, attribute.getChildren().get( 0 ).getType() );
+        assertEquals( "Foo", attribute.getChildren().get( 0 ).getValue() );
+        
+        // AbstractNode 3: text
+        node = nodes.get( 2 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 53, node.getColumn() );
+        assertEquals( 52, node.getStart() );
+        assertEquals( 54, node.getEnd() );
+        assertEquals( NodeType.TEXT, node.getType() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( "(TEXT)", node.getName() );
+        assertEquals( NodeType.ROOT, node.getParent().getType() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+    }
+
+    public static Test suite()
+    {
+        return new TestSuite( JspParserTest.class );
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,19 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.Map;
+
+/**
+ * Strategy interface for transforming JSPs.
+ */
+public interface JspTransformer
+{
+    /**
+     * Executes the transformation on the JSP and returns the result.
+     * 
+     * @param sharedState a map containing key/value pairs that represent any
+     *            shared-state information that this method might need during
+     *            transformation.
+     * @param doc the JSP to transform.
+     */
+    public void transform( Map<String, Object> sharedState, JspDocument doc );
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,150 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.List;
+
+public interface Node
+{
+
+    public static final int POSITION_NOT_SET = -1;
+
+    /**
+     * Returns the JspDocument the Node belongs to. 
+     * @return the document
+     */
+    public abstract JspDocument getJspDocument();
+    
+    /**
+     * Adds a child to the current AbstractNode. If the AbstractNode is of type
+     * {@link NodeType#HTML_COMBINED_TAG}, the tag will be split into two nodes
+     * (start tag and end tag), with the child AbstractNode inserted between the two.
+     * 
+     * @param node the node to insert
+     * @param value the node to insert in between the split nodes
+     * @throws IllegalArgumentException if the supplied node to split is not of
+     *             type {@link NodeType#HTML_START_TAG},
+     *             {@link NodeType#HTML_START_TAG} or
+     *             {@link NodeType#HTML_COMBINED_TAG}
+     * @throws IllegalStateException if the current AbstractNode must be split, and does
+     *             not have a parent.
+     */
+    public abstract void addChild( Node node );
+
+    /**
+     * Returns the child nodes of this node, as a defensive copy of the
+     * internally-cached list.
+     * 
+     * @return the children
+     */
+    public abstract List<Node> getChildren();
+
+    /**
+     * Returns the column the node starts on, relative to the beginning of the
+     * line in the source text.
+     * 
+     * @return the column
+     */
+    public abstract int getColumn();
+
+    /**
+     * Returns the exnding character position of the node, exclusive, relative
+     * to the beginning of the source text.
+     * 
+     * @return the end position
+     */
+    public abstract int getEnd();
+
+    /**
+     * Returns the "level" of the tag; that is, how far from the top-level nodes
+     * (which are level 1). If the parent of this node is not set, this method
+     * returns -1.
+     * 
+     * @return
+     */
+    public abstract int getLevel();
+
+    /**
+     * Returns the line of the source text the node starts on.
+     * 
+     * @return the line
+     */
+    public abstract int getLine();
+
+    /**
+     * Returns the m_name of the tag, if the node is an HTML start, end, or
+     * combined tag, or the directive m_name if a JSP directive;
+     * <code>null</code> otherwise.
+     * 
+     * @return the tag m_name
+     */
+    public abstract String getName();
+
+    /**
+     * Returns the parent of this node, which may be null if a top-level node.
+     * 
+     * @return the parent
+     */
+    public abstract Node getParent();
+
+    /**
+     * Returns the siblings of this node.
+     * 
+     * @return the siblings
+     */
+    public abstract List<Node> getSiblings();
+
+    /**
+     * Returns the starting character position of the node, inclusive, relative
+     * to the beginning of the source text.
+     * 
+     * @return the start position
+     */
+    public abstract int getStart();
+
+    /**
+     * Returns the type of the node.
+     * 
+     * @return the type
+     */
+    public abstract NodeType getType();
+
+    /**
+     * Returns the value of the node, which will be all characters between
+     * a matched pair of start and end tags (for Tags), all characters between
+     * matching quotes (for Attributes), or text characters (for Texts).
+     * 
+     * @return the value
+     */
+    public abstract String getValue();
+
+    public abstract boolean isHtmlNode();
+
+    public abstract boolean isJspNode();
+
+    public abstract void removeChild( Node node );
+
+    public abstract void setColumn( int i );
+
+    public abstract void setEnd( int pos );
+
+    public abstract void setLine( int i );
+
+    /**
+     * For Node types that support it, sets the logical name of the Node.
+     * @param name a String representing the name.
+     */
+    public abstract void setName( String name );
+
+    public abstract void setParent( Node parent );
+
+    public abstract void setStart( int pos );
+
+    public abstract void setType( NodeType type );
+
+    /**
+     * Convenience method that replaces all child Nodes with a single text node
+     * whose value is supplied by the caller.
+     * @param value the value to replace
+     */
+    public abstract void setValue( String value );
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,69 @@
+/**
+ * 
+ */
+package com.ecyrd.jspwiki.ui.stripes;
+
+public enum NodeType
+{
+    /** Root node */
+    ROOT(null, null),
+    /** Attribute node */
+    ATTRIBUTE(null,null),
+    /** Text node */
+    TEXT("", ""),
+    /** HTML start tag */
+    HTML_START_TAG("<", ">"),
+    /** HTML end tag */
+    HTML_END_TAG("</", ">"),
+    /** HTML end tag */
+    HTML_COMBINED_TAG("<", "/>"),
+    /** HTML tag, but not sure whether it's a start, end or combined tag. */
+    UNRESOLVED_HTML_TAG("<", null),
+    /** JSP comments, e.g., &lt;%-- comment --%&gt; */
+    JSP_COMMENT("<%--", "--%>"),
+    /**
+     * JSP declaration, e.g., &lt;%! declaration; [ declaration; ]+ ...
+     * %&gt;
+     */
+    JSP_DECLARATION("<%!", "%>"),
+    /** JSP expression, e.g., &lt;%= expression %&gt; */
+    JSP_EXPRESSION("<%=", "%>"),
+    /**
+     * JSP scriptlet, e.g., &lt;% code fragment %&gt;. Note the whitespace
+     * after the %.
+     */
+    SCRIPTLET("<%", "%>"),
+    /**
+     * JSP page, import or taglib directive, e.g., &lt;%@ include... %&gt;
+     * &lt;%@ page... %&gt; &lt;%@ taglib... %&gt;
+     */
+    JSP_DIRECTIVE("<%@", "%>"),
+    /** JSP tag, but not sure what kind.. */
+    UNRESOLVED_JSP_TAG(null, null),
+    /** Parser has seen &lt;, but hasn't figured out what it is yet. */
+    UNRESOLVED(null, null);
+    private final String m_tagStart;
+
+    private final String m_tagEnd;
+
+    NodeType(String tagStart, String tagEnd )
+    {
+        m_tagStart = tagStart;
+        m_tagEnd = tagEnd;
+    }
+
+    public String getTagEnd()
+    {
+        return m_tagEnd;
+    }
+
+    public String getTagStart()
+    {
+        return m_tagStart;
+    }
+    
+    public String toString() {
+        return name();
+    }
+    
+}
\ No newline at end of file

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,186 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Transforms a JspDocument from standard JSP markup to Stripes markup.
+ */
+public class StripesJspTransformer extends AbstractJspTransformer
+{
+
+    public void transform( Map<String, Object> sharedState, JspDocument doc )
+    {
+
+        // Add the Stripes taglib declaration if it's not there already
+        List<Node> nodes = doc.getNodes( NodeType.JSP_DIRECTIVE );
+        boolean declaresStripesTaglib = false;
+        for ( Node node : nodes )
+        {
+            Tag tag = (Tag)node;
+            if ( "taglib".equals( node.getName() ) )
+            {
+                Attribute attribute = tag.getAttribute( "prefix" );
+                if ( attribute != null )
+                {
+                    declaresStripesTaglib = true;
+                    break;
+                }
+            }
+        }
+        if ( !declaresStripesTaglib )
+        {
+            Tag tag = new Tag( doc, NodeType.JSP_DIRECTIVE );
+            tag.setName( "taglib" );
+            Attribute attribute = new Attribute( doc );
+            attribute.setName( "uri" );
+            attribute.setValue( "/WEB-INF/stripes.tld" );
+            tag.addAttribute( attribute );
+            attribute = new Attribute( doc );
+            attribute.setName( "prefix" );
+            attribute.setValue( "stripes" );
+            tag.addAttribute( attribute );
+            doc.getRoot().addChild( tag );
+            message( doc.getRoot(), "Added Stripes taglib directive." );
+        }
+        
+        // Process HTML nodes
+        nodes = doc.getNodes();
+        for( Node node : nodes )
+        {
+            // For all HTML tags...
+            if( node.isHtmlNode() )
+            {
+                Tag tag = (Tag)node;
+                
+                // Change <form> to <stripes:form>
+                if( "form".equals( tag.getName() ) )
+                {
+                    migrateFormTag( tag );
+                }
+
+                // Change <input type="*"> tags to <stripes:*>
+                else if( "input".equals( tag.getName() ) )
+                {
+                    migrateInputTag( tag );
+                }
+            }
+        }
+    }
+
+    /**
+     * Migrates the &lt;input&gt; tag.
+     * @param tag the AbstractNode that represents the form tag being processed.
+     */
+    private void migrateInputTag( Tag tag )
+    {
+
+        // Move 'type' attribute value to the localname
+        Attribute attribute = tag.getAttribute( "type" );
+        if( attribute != null )
+        {
+            // If a submit input, tell user to change the "name"
+            // value to something useful for Stripes
+            if( "submit".equals( attribute.getValue() ) )
+            {
+                Node nameAttribute = tag.getAttribute( "name" );
+                String nameValue = nameAttribute == null ? "(not set)" : nameAttribute.getName();
+                message( nameAttribute, "NOTE: the \"name\" attribute of <input type=\"submit\" is \"" + nameValue
+                                        + "\"" );
+            }
+
+            // Move type attribute to qname
+            String type = attribute.getValue();
+            message( attribute, "Changed <input type=\"" + type + "\"> to <stripes:" + type + ">." );
+            tag.setName( "stripes:" + type );
+            tag.removeAttribute( attribute );
+        }
+
+        // If embedded markup in "value" attribute, move to child
+        // nodes
+        attribute = tag.getAttribute( "value" );
+        if( attribute != null )
+        {
+            List<Node> children = attribute.getChildren();
+            if( children.size() > 1 || (children.size() == 1 && children.get( 0 ).getType() != NodeType.TEXT) )
+            {
+                // Remove the attribute
+                tag.removeAttribute( attribute );
+                // Move all of the attribute's nodes to the
+                // children nodes
+                for( Node valueNode : attribute.getChildren() )
+                {
+                    tag.addChild( valueNode );
+                }
+                message( attribute,
+                         "Moved embedded tag(s) in <input> \"value\" attribute to the tag body. These are now child element(s) of <input>." );
+            }
+        }
+    }
+
+    /**
+     * Migrates the &lt;form&gt; tag.
+     * @param tag the AbstractNode that represents the form tag being processed.
+     */
+    private void migrateFormTag( Tag tag )
+    {
+        message( tag, "Changed name to <stripes:form>." );
+        tag.setName( "stripes:form" );
+
+        // Change "accept-charset" attribute to acceptcharset
+        Node attribute = tag.getAttribute( "accept-charset" );
+        if( attribute != null )
+        {
+            message( attribute, "Changed name to \"acceptcharset\"." );
+            attribute.setName( "acceptcharset" );
+        }
+
+        // If URL has parameters, add them as child <stripes:param>
+        // elements
+        // e.g., param in <form action="Login.jsp?tab=profile>
+        // becomes <stripes:param name="tab" value="profile">
+        attribute = tag.getAttribute( "action" );
+        if( attribute != null )
+        {
+            String actionUrl = attribute.getValue();
+            if( actionUrl != null )
+            {
+                int qmark = actionUrl.indexOf( '?' );
+                if( qmark < actionUrl.length() - 1 )
+                {
+                    // Change "action" attribute"
+                    String trimmedPath = actionUrl.substring( 0, qmark );
+                    message( attribute, "Trimmed value to \"" + trimmedPath + "\"");
+                    attribute.setValue( trimmedPath );
+
+                    // Split the parameters and add a new
+                    // <stripes:param> child element for each
+                    String[] params = actionUrl.substring( qmark + 1 ).split( "&" );
+                    for( String param : params )
+                    {
+                        if( param.length() > 1 )
+                        {
+                            JspDocument doc = tag.getJspDocument();
+                            String name = param.substring( 0, param.indexOf( '=' ) );
+                            String value = param.substring( name.length() +1 );
+                            Tag stripesParam = new Tag( doc, NodeType.HTML_COMBINED_TAG );
+                            stripesParam.setName( "stripes:param" );
+                            Attribute nameAttribute = new Attribute( doc );
+                            nameAttribute.setName( "name" );
+                            nameAttribute.setValue( name );
+                            stripesParam.addAttribute( nameAttribute );
+                            Attribute valueAttribute = new Attribute( doc );
+                            valueAttribute.setName( "value" );
+                            valueAttribute.setValue( value );
+                            stripesParam.addAttribute( valueAttribute );
+                            tag.addChild( stripesParam );
+                            message( tag, "Created <stripes:form> child element <stripes:param name=\"" + name + "\""
+                                           + " value=\"" + value + "\"/>." );
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,97 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+public class StripesJspTransformerTest extends TestCase
+{
+    protected Map<String,Object> m_sharedState = new HashMap<String,Object>();
+    protected JspTransformer m_transformer = new StripesJspTransformer();
+    protected JspDocument m_doc = new JspDocument();
+    
+    public StripesJspTransformerTest( String s )
+    {
+        super( s );
+    }
+    
+    public void testFormWithParams() throws Exception
+    {
+        String s = "<form action=\"Login.jsp?tab=profile\"/>";
+        JspDocument doc = new JspParser().parse( s );
+        m_transformer.transform( m_sharedState, doc );
+        
+        assertEquals( 3, doc.getNodes().size() );
+        Node node = doc.getNodes().get( 0 );
+        assertEquals( "stripes:form", node.getName() );
+        assertEquals( 1, ((Tag)node).getAttributes().size() );
+        Node attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( "Login.jsp", attribute.getValue() );
+    }
+
+    public void testFormCombinedTag() throws Exception
+    {
+        String s = "<form accept-charset=\"UTF-8\" method=\"POST\" />";
+        JspDocument doc = new JspParser().parse( s );
+        m_transformer.transform( m_sharedState, doc );
+
+        assertEquals( 1, doc.getNodes().size() );
+        Node node = doc.getNodes().get( 0 );
+        assertEquals( "stripes:form", node.getName() );
+        
+        assertEquals( 2, ((Tag)node).getAttributes().size() );
+        Node attribute = ((Tag)node).getAttributes().get( 0 );
+        assertEquals( "acceptcharset", attribute.getName() );
+    }
+
+    public void testPasswordTag() throws Exception
+    {
+        String s = "<input type=\"password\" size=\"24\" value=\"\" name=\"j_username\" id=\"j_username\" />";
+        JspDocument doc = new JspParser().parse( s );
+        Node node;
+        
+        // Before transformation, 1 node, with 5 attributes
+        node = doc.getNodes().get( 0 );
+        assertEquals( 1, doc.getNodes().size() );
+        assertEquals( 5, ((Tag)node).getAttributes().size() );
+        m_transformer.transform( m_sharedState, doc );
+
+        // After transformation, the "type" attribute is deleted
+        assertEquals( 1, doc.getNodes().size() );
+        node = doc.getNodes().get( 0 );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( "stripes:password", node.getName() );
+        assertEquals( 4, ((Tag)node).getAttributes().size() );
+        assertEquals( 0, node.getChildren().size() );
+    }
+    
+    public void testPasswordTagComplex() throws Exception
+    {
+        String s = "<input type=\"password\" size=\"24\" value=\"<wiki:Variable var='uid' default='' />\" name=\"j_username\" id=\"j_username\" />";
+        JspDocument doc = new JspParser().parse( s );
+        assertEquals( 1, doc.getNodes().size() );
+        m_transformer.transform( m_sharedState, doc );
+
+        // After transformation, the "type" and "value" attributes are deleted; value becomes child node
+        assertEquals( 3, doc.getNodes().size() );
+        Node node = doc.getNodes().get( 0 );
+        assertEquals( NodeType.HTML_START_TAG, node.getType() );
+        assertEquals( "stripes:password", node.getName() );
+        assertEquals( 3, ((Tag)node).getAttributes().size() );
+        
+        // The value attribute should show up as a child node
+        assertEquals( 1, node.getChildren().size() );
+        node = node.getChildren().get( 0 );
+        assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( "wiki:Variable", node.getName() );
+    }
+    
+    public static Test suite()
+    {
+        return new TestSuite( StripesJspTransformerTest.class );
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,156 @@
+/**
+ * 
+ */
+package com.ecyrd.jspwiki.ui.stripes;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Node implementation representing an HTML or XML tag.
+ */
+public class Tag extends AbstractNode
+{
+    private List<Attribute> m_attributes = new ArrayList<Attribute>();
+
+    /**
+     * 
+     * @param doc the parent JspDocument
+     * @param type
+     */
+    public Tag ( JspDocument doc, NodeType type )
+    {
+        super( doc, type );
+    }
+
+    public void addAttribute( Attribute attribute )
+    {
+        m_attributes.add( attribute );
+    }
+
+    /**
+     * Returns the attribute whose name matches a supplied string, or
+     * <code>null</code> if not found.
+     * 
+     * @param name the named attribute to search for
+     * @return the attribute if found, or <code>null</code>
+     */
+    public Attribute getAttribute( String name )
+    {
+        if( name == null )
+        {
+            throw new IllegalArgumentException( "Name cannot be null. " );
+        }
+        for( Attribute attribute : m_attributes )
+        {
+            if( name.equals( attribute.getName() ) )
+            {
+                return attribute;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the attributes of this node, as a defensive copy of the
+     * internally-cached list.
+     * 
+     * @return
+     */
+    public List<Attribute> getAttributes()
+    {
+        List<Attribute> attributesCopy = new ArrayList<Attribute>();
+        attributesCopy.addAll( m_attributes );
+        return Collections.unmodifiableList( attributesCopy );
+    }
+
+    public void removeAttribute( Attribute attribute )
+    {
+        m_attributes.remove( attribute );
+    }
+
+    private String diagnostic()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append( "[" );
+        sb.append( m_type.toString() );
+        sb.append( "(pos=" );
+        sb.append( m_line );
+        sb.append( ":" );
+        sb.append( m_col );
+        sb.append( ",chars=" );
+        sb.append( m_start );
+        sb.append( ":" );
+        sb.append( m_end );
+        sb.append( ",L" );
+        sb.append( getLevel() );
+        sb.append( ")," );
+        sb.append( "name=\"" );
+        sb.append( m_name );
+        sb.append( "\"," );
+        if( m_attributes.size() > 0 )
+        {
+            sb.append( "attributes=" );
+            for( Attribute attr : m_attributes )
+            {
+                sb.append( "[" );
+                sb.append( attr.toString() );
+                sb.append( "\"]" );
+            }
+            sb.append( "," );
+        }
+        sb.append( "value=\"" );
+        sb.append( getValue() );
+        sb.append( "\"]" );
+
+        return sb.toString();    }
+    
+    public String  getValue()
+    {
+        if ( m_type != NodeType.HTML_START_TAG )
+        {
+            return null;
+        }
+        return super.getValue();
+    }
+    
+    /**
+     * Returns the string that represents the Tag, including the name and attributes, but not any child nodes.
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append( m_type.getTagStart() );
+        
+        // HTML nodes and JSP directives are formatted in mostly the same way.
+        if ( isHtmlNode() || m_type == NodeType.JSP_DIRECTIVE )
+        {
+            if ( m_type == NodeType.JSP_DIRECTIVE )
+            {
+                sb.append( ' ' );
+            }
+            sb.append(  m_name );
+            if( m_attributes.size() > 0 )
+            {
+                for( Attribute attr : m_attributes )
+                {
+                    sb.append( ' ' );
+                    sb.append( attr.toString() );
+                }
+            }
+        }
+        
+        // Everything else is just the start/end tags plus the children nodes
+        else {
+            for ( Node child : m_children )
+            {
+                sb.append( child.toString() );
+            }
+        }
+        
+        sb.append( m_type.getTagEnd() );
+        return sb.toString();
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Text.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Text.java?rev=695481&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Text.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Text.java Mon Sep 15 07:21:34 2008
@@ -0,0 +1,44 @@
+package com.ecyrd.jspwiki.ui.stripes;
+
+public class Text extends AbstractNode
+{
+
+    private String m_value = null;
+    
+    public Text( JspDocument doc )
+    {
+        super( doc, NodeType.TEXT );
+    }
+
+    /**
+     * Always returns \"(TEXT)\".
+     */
+    @Override
+    public String getName()
+    {
+        return "(TEXT)";
+    }
+    
+    public String getValue()
+    {
+        return m_value;
+    }
+
+    public void setName( String name )
+    {
+        throw new UnsupportedOperationException( "Text nodes cannot have names.");
+    }
+
+    public void setValue( String value )
+    {
+        m_value = value;
+    }
+    
+    /**
+     * Returns the string that represents the Tag, including the name and attributes, but not any child nodes.
+     */
+    public String toString()
+    {
+        return m_value;
+    }
+}

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/AllTests.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/AllTests.java?rev=695481&r1=695480&r2=695481&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/AllTests.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/AllTests.java Mon Sep 15 07:21:34 2008
@@ -2,6 +2,8 @@
 package com.ecyrd.jspwiki.util;
 
 
+import com.ecyrd.jspwiki.ui.stripes.JspParserTest;
+
 import junit.framework.*;
 
 public class AllTests extends TestCase
@@ -23,6 +25,7 @@
         suite.addTest( SerializerTest.suite() );
         suite.addTest( TextUtilTest.suite() );
         suite.addTest( TimedCounterListTest.suite() );
+        suite.addTest( JspParserTest.suite() );
         
         return suite;
     }