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/07 04:27:41 UTC

svn commit: r692767 - in /incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util: JspDocument.java StripesJspMigrator.java StripesJspMigratorTest.java

Author: ajaquith
Date: Sat Sep  6 19:27:40 2008
New Revision: 692767

URL: http://svn.apache.org/viewvc?rev=692767&view=rev
Log:
StripesJspMigrator changes and tests. Now properly parses JSPs, including tag & directive attributes.

Added:
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigratorTest.java
Modified:
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/JspDocument.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigrator.java

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/JspDocument.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/JspDocument.java?rev=692767&r1=692766&r2=692767&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/JspDocument.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/JspDocument.java Sat Sep  6 19:27:40 2008
@@ -1,6 +1,6 @@
 package com.ecyrd.jspwiki.util;
 
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Stack;
 
@@ -9,6 +9,57 @@
  */
 class JspDocument
 {
+    private static final int POSITION_NOT_SET = -1;
+
+    public static class Attribute
+    {
+        Attribute()
+        {
+            super();
+        }
+
+        public int getStart()
+        {
+            return start;
+        }
+
+        public int getEnd()
+        {
+            return end;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public Node getValue()
+        {
+            return value;
+        }
+
+        /**
+         * Returns the quote character used to delimit the attribute value; by
+         * definition, either ' or ".
+         * 
+         * @return the quote character
+         */
+        public char getQuoteChar()
+        {
+            return quote;
+        }
+
+        private String name = null;
+
+        private Node value = new JspDocument.Node( Node.Type.UNDEFINED );
+
+        private int start = POSITION_NOT_SET;
+
+        private int end = POSITION_NOT_SET;
+
+        private char quote = QUOTE_NOT_SET;
+    }
+
     /**
      * Element that has been parsed.
      */
@@ -17,70 +68,213 @@
         public enum Type
         {
             /** Root node */
-            ROOT("ROOT"),
+            ROOT("ROOT", null, null),
             /** Text node */
-            TEXT("TEXT"),
+            TEXT("TEXT", "", ""),
             /** HTML start tag */
-            HTML_START_TAG("HTML_START_TAG"),
+            HTML_START_TAG("HTML_START_TAG", "<", ">"),
             /** HTML end tag */
-            HTML_END_TAG("HTML_END_TAG"),
+            HTML_END_TAG("HTML_END_TAG", "</", ">"),
             /** HTML end tag */
-            HTML_COMBINED_TAG("HTML_COMBINED_TAG"),
+            HTML_COMBINED_TAG("HTML_COMBINED_TAG", "<", "/>"),
             /** HTML tag, but not sure whether it's a start, end or combined tag. */
-            UNDEFINED_HTML_TAG("UNDEFINED_HTML_TAG"),
+            UNDEFINED_HTML_TAG("UNDEFINED_HTML_TAG", "<", null),
             /** JSP comments, e.g., &lt;%-- comment --%&gt; */
-            JSP_COMMENT("JSP_COMMENT"),
+            JSP_COMMENT("JSP_COMMENT", "<%--", "--%>"),
             /**
              * JSP declaration, e.g., &lt;%! declaration; [ declaration; ]+ ...
              * %&gt;
              */
-            JSP_DECLARATION("JSP_DECLARATION"),
+            JSP_DECLARATION("JSP_DECLARATION", "<%!", "%>"),
             /** JSP expression, e.g., &lt;%= expression %&gt; */
-            JSP_EXPRESSION("JSP_EXPRESSION"),
+            JSP_EXPRESSION("JSP_EXPRESSION", "<%=", "%>"),
             /**
              * JSP scriptlet, e.g., &lt;% code fragment %&gt;. Note the
              * whitespace after the %.
              */
-            SCRIPTLET("SCRIPTLET"),
+            SCRIPTLET("SCRIPTLET", "<%", "%>"),
             /**
              * JSP page, import or taglib directive, e.g., &lt;%@ include...
              * %&gt; &lt;%@ page... %&gt; &lt;%@ taglib... %&gt;
              */
-            JSP_DIRECTIVE("JSP_DIRECTIVE"),
+            JSP_DIRECTIVE("JSP_DIRECTIVE", "<%@", "%>"),
             /** JSP tag, but not sure what kind.. */
-            UNDEFINED_JSP_TAG("UNEFINED_JSP_TAG"),
+            UNDEFINED_JSP_TAG("UNEFINED_JSP_TAG", null, null),
             /** Parser has seen &lt;, but hasn't figured out what it is yet. */
-            UNDEFINED("UNDEFINED");
-            Type( String description )
+            UNDEFINED("UNDEFINED", null, null);
+            Type( String description, String tagStart, String tagEnd )
             {
                 this.description = description;
+                this.tagStart = tagStart;
+                this.tagEnd = tagEnd;
             }
-    
-            private String description;
+
+            private final String description;
+
+            private final String tagStart;
+
+            private final String tagEnd;
         }
-    
+
         private Node.Type type;
-    
+
         private String text = null;
-        
-        private String revisedText = null;
-    
+
+        private List<JspDocument.Attribute> attributes = new ArrayList<JspDocument.Attribute>();
+
         private int level = 0;
-        
-        private int start = -1;
-    
-        private int end = -1;
-    
-        private int line = -1;
-    
-        private int col = -1;
-        
+
+        private int start = POSITION_NOT_SET;
+
+        private int end = POSITION_NOT_SET;
+
+        private int line = POSITION_NOT_SET;
+
+        private int col = POSITION_NOT_SET;
+
         private Node parent = null;
-        
-        private List<Node> children = new LinkedList<Node>();
-    
-        private List<Node> siblings = new LinkedList<Node>();
-        
+
+        private String name = null;
+
+        private List<Node> children = new ArrayList<Node>();
+
+        /**
+         * Returns the value of the node, which will be equal to the text of the
+         * node, minus the start and end delimiters specified for the node type.
+         * Thus, a node whose text is set to <code>&lt;/endtag&gt;</code> and
+         * whose type is {@link Node.Type#HTML_END_TAG} would return the value
+         * <code>endtag</code>.
+         * 
+         * @return the value
+         */
+        public String getValue()
+        {
+            if( text == null )
+            {
+                return null;
+            }
+            return text.substring( type.tagStart.length(), text.length() - type.tagEnd.length() );
+        }
+
+        /**
+         * Returns the name of the tag, if the node is an HTML start, end, or
+         * combined tag, or the directive name if a JSP directive; <code>null</code> otherwise.
+         * 
+         * @return the tag name
+         */
+        public String getName()
+        {
+            return name;
+        }
+
+        /**
+         * Returns the line of the source text the node starts on.
+         * 
+         * @return the line
+         */
+        public int getLine()
+        {
+            return line;
+        }
+
+        /**
+         * Returns the starting character position of the node, inclusive,
+         * relative to the beginning of the source text.
+         * 
+         * @return the start position
+         */
+        public int getStartChar()
+        {
+            return start;
+        }
+
+        public List<JspDocument.Attribute> getAttributes()
+        {
+            return attributes;
+        }
+
+        /**
+         * Returns the exnding character position of the node, exclusive,
+         * relative to the beginning of the source text.
+         * 
+         * @return the end position
+         */
+        public int getEndChar()
+        {
+            return end;
+        }
+
+        /**
+         * Returns the type of the node.
+         * 
+         * @return the type
+         */
+        public Node.Type getType()
+        {
+            return type;
+        }
+
+        /**
+         * Returns the column the node starts on, relative to the beginning of
+         * the line in the source text.
+         * 
+         * @return the column
+         */
+        public int getColumn()
+        {
+            return col;
+        }
+
+        /**
+         * Returns the "level" of the tag; that is, how far from the top-level
+         * nodes (which are level 1).
+         * 
+         * @return
+         */
+        public int getLevel()
+        {
+            return level;
+        }
+
+        /**
+         * Returns the "child" nodes relative to the current one.
+         * 
+         * @return the children
+         */
+        public List<Node> getChildren()
+        {
+            return children;
+        }
+
+        /**
+         * Returns the siblings of this node.
+         * 
+         * @return the siblings
+         */
+        public List<Node> getSiblings()
+        {
+            List<Node> siblings = new ArrayList<Node>();
+            for( Node sibling : parent.children )
+            {
+                if( !this.equals( sibling ) )
+                {
+                    siblings.add( sibling );
+                }
+            }
+            return siblings;
+        }
+
+        /**
+         * Returns the parent of this node, which may be null if a top-level
+         * node.
+         * 
+         * @return the parent
+         */
+        public Node getParent()
+        {
+            return parent.type == Node.Type.ROOT ? null : parent;
+        }
+
         /**
          * Constructs a new Node. Callers should use the
          * {@link JspDocument#createNode(com.ecyrd.jspwiki.util.JspDocument.Node.Type, int)}
@@ -92,59 +286,72 @@
         {
             this.type = type;
         }
-    
+
         public boolean isJspNode()
         {
             return type == Type.JSP_COMMENT || type == Type.JSP_DECLARATION || type == Type.JSP_EXPRESSION
                    || type == Type.SCRIPTLET || type == Type.JSP_DIRECTIVE || type == Type.UNDEFINED_JSP_TAG;
         }
-    
+
+        /**
+         * Returns <code>true</code> if the node can contain attributes,
+         * <code>false</code> otherwise.
+         * 
+         * @return the result
+         */
+        public boolean isTag()
+        {
+            return type == Type.HTML_START_TAG || type == Type.HTML_COMBINED_TAG || type == Type.UNDEFINED_HTML_TAG;
+        }
+
         public String toString()
         {
-            return "[" + type.description + "(pos=" + line + ":" + col + ",chars=" + start + ":" + end + ",L" + level + "):\"" + text + "\"]";
+            return "[" + type.description + "(pos=" + line + ":" + col + ",chars=" + start + ":" + end + ",L" + level + "):\""
+                   + text + "\"]";
         }
     }
 
+    private static final char QUOTE_NOT_SET = 0;
+
     private final Stack<JspDocument.Node> nodeStack = new Stack<JspDocument.Node>();
 
-    private final List<JspDocument.Node> allNodes = new LinkedList<JspDocument.Node>();
-    
-    private final List<Integer> lineBreaks = new LinkedList<Integer>();
-    
+    private final List<JspDocument.Node> allNodes = new ArrayList<JspDocument.Node>();
+
+    private final List<Integer> lineBreaks = new ArrayList<Integer>();
+
     private Node root = null;
-    
+
     /**
      * Constructs a new JspDocument.
      */
     public JspDocument()
     {
         super();
-        
-        // Add a fake root node, then erase it from the list of "all nodes"
-        createNode( Node.Type.ROOT, 0 );
-        nodeStack.push( root );
-        allNodes.clear();
     }
-    
+
     /**
-     * Returns the list of nodes parsed by {@link #parse(String)}, in the order parsed. 
+     * Returns the list of nodes parsed by {@link #parse(String)}, in the order
+     * parsed.
+     * 
      * @return the list of nodes
      */
     public List<JspDocument.Node> getNodes()
     {
         return allNodes;
     }
-    
+
     /**
-     * Returns the list of nodes of a specified type as parsed by {@link #parse(String)}, in the order parsed. 
+     * Returns the list of nodes of a specified type as parsed by
+     * {@link #parse(String)}, in the order parsed.
+     * 
      * @return the list of nodes
      */
     public List<JspDocument.Node> getNodes( JspDocument.Node.Type type )
     {
-        List<JspDocument.Node> typeNodes = new LinkedList<JspDocument.Node>();
-        for ( JspDocument.Node node : allNodes )
+        List<JspDocument.Node> typeNodes = new ArrayList<JspDocument.Node>();
+        for( JspDocument.Node node : allNodes )
         {
-            if ( node.type == type )
+            if( node.type == type )
             {
                 typeNodes.add( node );
             }
@@ -155,68 +362,188 @@
     /**
      * Factory method that constructs and returns a new Node. This node is
      * appended to the internal list of Nodes. 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.
+     * start position, line number, column number and level are set
+     * automatically based on JspDocument's internal cache of line-breaks and
+     * nodes.
      * 
      * @param type the node type
      * @param pos the start position for the node
      * @return the new Node
      */
-    public JspDocument.Node createNode( JspDocument.Node.Type type, int pos )
+    protected JspDocument.Node createNode( JspDocument.Node.Type type, int pos )
     {
-        JspDocument.Node node = new JspDocument.Node( type );
-        node.start = pos;
-        int lastLineBreakPos =lineBreaks.size() == 0 ? -1 : lineBreaks.get( lineBreaks.size() - 1 ); 
-        node.line = lineBreaks.size() + 1;
-        node.col = pos - lastLineBreakPos;
-        node.level = nodeStack.size();
-        
         // If last node added has no length (i.e., is null), get rid of it
-        if ( allNodes.size() > 0 )
+        Node parent = nodeStack.peek();
+        if( allNodes.size() > 0 )
         {
             JspDocument.Node lastNode = allNodes.get( allNodes.size() - 1 );
-            if ( lastNode.start == lastNode.end )
+            if( lastNode.start == lastNode.end )
             {
-                allNodes.remove( allNodes.size() - 1 );
+                allNodes.remove( lastNode );
+                parent.children.remove( lastNode );
             }
         }
-        
-        // Add the new node
+
+        // Create new Node and set parent/child relationships
+        JspDocument.Node node = new JspDocument.Node( type );
+        node.parent = parent;
+        parent.children.add( node );
         allNodes.add( node );
-        
-        // Set parent/child relationship, if Node is on stack
-        if (nodeStack.size() > 0 )
+
+        // Set the start, end, linebreak and level
+        node.start = pos;
+        int lastLineBreakPos = lineBreaks.size() == 0 ? POSITION_NOT_SET : lineBreaks.get( lineBreaks.size() - 1 );
+        node.line = lineBreaks.size() + 1;
+        node.col = pos - lastLineBreakPos;
+        node.level = nodeStack.size();
+
+        return node;
+    }
+
+    /**
+     * Parses a JSP file, supplied as a String, into Nodes.
+     * 
+     * @param source the JSP file contents
+     */
+    public void parse( String source )
+    {
+        // First, break the raw text into Nodes
+        parseNodes( source );
+
+        // Now, visit each Node and extract attributes (for HTML tags) or the directive name (for JSP directives)
+        for( Node node : allNodes )
         {
-            Node parent = nodeStack.peek();
-            node.parent = parent;
-            parent.children.add( node );
+            if( node.isTag() || node.getType() == Node.Type.JSP_DIRECTIVE )
+            {
+                String nodeValue = node.getValue().substring( node.getValue().indexOf( node.name ) + node.name.length() );
+                parseAttributes( node, nodeValue );
+            }
         }
-        
-        // If no root yet, set it
-        if ( root == null )
+    }
+    
+    /**
+     * Extracts the attributes for a supplied Node.
+     * @param source the text to parse
+     */
+    protected void parseAttributes( Node node, String source )
+    {
+        // Get the node text starting just after the tag name.
+        if ( source.length() == 0 )
         {
-            root = node;
+            return;
         }
-        else
+
+        // Parse the node's value string, character by character
+        int pos = 0;
+        JspDocument.Attribute attribute = null;
+        for( char ch : source.toCharArray() )
         {
-            root.end = node.end;
+            switch( ch )
+            {
+                case ('<'): {
+                    // If attribute already set, the left bracket will always
+                    // signal a nested JSP expression
+                    if( attribute != null && attribute.value.start == POSITION_NOT_SET )
+                    {
+                        attribute.value.start = pos;
+                        attribute.value.type = JspDocument.Node.Type.JSP_EXPRESSION;
+                    }
+                    break;
+                }
+
+                case (' '):
+                case ('\t'):
+                case ('\r'):
+                case ('\n'):
+                case ('\u000B'):
+                case ('\u000C'):
+                case ('\u001C'):
+                case ('\u001D'):
+                case ('\u001E'):
+                case ('\u001F'): {
+                    // If no current attribute, whitespace marks the
+                    // start
+                    if( attribute == null )
+                    {
+                        attribute = new Attribute();
+                    }
+                    break;
+                }
+
+                    // If single/double quote and HTML tag, start/stop/continue
+                    // an attribute
+                case ('\''):
+                case ('\"'): {
+                    if( attribute != null )
+                    {
+                        // If the same as the quote char used to start the
+                        // attribute, we're done; extract the attribute value
+                        if( attribute.quote == ch )
+                        {
+                            attribute.value.end = pos;
+                            attribute.value.text = source.substring( attribute.value.start, attribute.value.end );
+                            node.attributes.add( attribute );
+                            attribute = null;
+                        }
+                        else if( attribute.quote == QUOTE_NOT_SET )
+                        {
+                            attribute.quote = ch;
+                        }
+                        break;
+                    }
+                }
+
+                case ('='):
+                {
+                    if( attribute != null && attribute.name == null )
+                    {
+                        attribute.name = source.substring( attribute.start, pos );
+                    }
+                    break;
+                }
+
+                default: {
+                    // If inside an attribute, set the start position if not set
+                    if( attribute != null )
+                    {
+                        if( attribute.start == POSITION_NOT_SET )
+                        {
+                            attribute.start = pos;
+                        }
+                        else if( attribute.quote != QUOTE_NOT_SET && attribute.value.start == POSITION_NOT_SET )
+                        {
+                            attribute.value.start = pos;
+                            attribute.value.type = JspDocument.Node.Type.TEXT;
+                        }
+                    }
+                }
+            }
+            pos++;
         }
-        return node;
     }
 
     /**
-     * Parses a JSP file, supplied as a String, into Nodes.
+     * Parses a supplied String into its component Nodes. For simplicity's sake,
+     * this method does <em>not</em> parse each Node's attributes.
      * 
-     * @param source the JSP file contents
+     * @param source the string to parse
      */
-    public void parse( String source )
+    protected void parseNodes( String source )
     {
+        // Clear out the node cache and stack
         nodeStack.clear();
         allNodes.clear();
+
+        // Create a root node that contains all top-level siblings
+        root = new JspDocument.Node( Node.Type.ROOT );
+        nodeStack.push( root );
+
+        // Reset the character counter
         char lastCh = ' ';
         int pos = 0;
+        int directiveNameStart = POSITION_NOT_SET;
         JspDocument.Node node = createNode( JspDocument.Node.Type.TEXT, pos );
-        
+
         // Parse the file, character by character
         for( char ch : source.toCharArray() )
         {
@@ -272,8 +599,9 @@
                         }
                     }
 
-                    // Cleanup
-                    if( nodeStack.size() > 0 )
+                    // If the last node added was a blank/empty text node,
+                    // remove it
+                    if( nodeStack.size() > 1 )
                     {
                         node = nodeStack.pop();
                     }
@@ -309,8 +637,28 @@
                         {
                             node.type = JspDocument.Node.Type.UNDEFINED_HTML_TAG;
                         }
+
+                        // If inside JSP directive and name not set, set it
+                        if ( node.type == JspDocument.Node.Type.JSP_DIRECTIVE )
+                        {
+                            if ( node.name == null &&  directiveNameStart != POSITION_NOT_SET )
+                            {
+                                node.name = source.substring( directiveNameStart, pos );
+                            }
+                        }
+                        
+                        // If inside HTML tag, whitespace marks the end of the
+                        // tag name
+                        if( node.isTag() )
+                        {
+                            // Set the tag name if still empty
+                            if( node.name == null )
+                            {
+                                node.name = source.substring( node.start + node.type.tagStart.length(), pos );
+                            }
+                        }
                     }
-                    
+
                     // Reset the line/column counters if we encounter linebreaks
                     if( ch == '\r' || ch == '\n' )
                     {
@@ -324,6 +672,7 @@
                     if( node.type == JspDocument.Node.Type.UNDEFINED )
                     {
                         node.type = JspDocument.Node.Type.UNDEFINED_JSP_TAG;
+                        directiveNameStart = POSITION_NOT_SET;
                     }
                     break;
                 }
@@ -346,7 +695,8 @@
                     break;
                 }
 
-                    // Equals after starting <% means JSP expression
+                    // Equals after starting <% means JSP expression; inside
+                    // attribute means end of name
                 case ('='): {
                     if( node.type == JspDocument.Node.Type.UNDEFINED_JSP_TAG && lastCh == '%' )
                     {
@@ -365,10 +715,18 @@
                 }
 
                 default: {
+                    // If node is still undefined, any other character is by
+                    // definition part of a text block
                     if( node.type == JspDocument.Node.Type.UNDEFINED )
                     {
                         node.type = JspDocument.Node.Type.UNDEFINED_HTML_TAG;
                     }
+                    
+                    // If in JSP directive and name start not set, start it here
+                    else if ( node.type == JspDocument.Node.Type.JSP_DIRECTIVE && directiveNameStart == POSITION_NOT_SET )
+                    {
+                        directiveNameStart = pos;
+                    }
                 }
             }
 
@@ -376,16 +734,21 @@
             lastCh = ch;
             pos++;
         }
-        
+
         // Set the end point for the last node
-        if ( node != null )
+        if( node != null )
         {
             node.end = pos;
-            if (node.start == node.end)
+            if( node.start == node.end )
+            {
+                allNodes.remove( node );
+                node.parent.children.remove( node );
+            }
+            else
             {
-                allNodes.remove( allNodes.size() -1 );
+                node.text = source.substring( node.start, node.end );
             }
         }
     }
 
-}
\ No newline at end of file
+}

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigrator.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigrator.java?rev=692767&r1=692766&r2=692767&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigrator.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigrator.java Sat Sep  6 19:27:40 2008
@@ -75,10 +75,10 @@
                 migrate( src, dest );
             }
 
-            // Otherwise it's a file, so migrate it
+            // Otherwise it's a file, so migrate it if it's a JSP
             else
             {
-                if( src.getName().endsWith( "LoginForm.jsp" ) )
+                if( src.getName().endsWith( ".jsp" ) )
                 {
                     migrateFile( src, dest );
                 }
@@ -96,25 +96,18 @@
     {
         // Read in the file
         System.out.println( "Migrating " + src.getPath() + " ----> " + dest.getPath() );
-        FileReader reader = new FileReader( src );
-        StringBuffer s = new StringBuffer();
-        int ch = 0;
-        while ( (ch = reader.read()) != -1 )
-        {
-            s.append( (char) ch );
-        }
-        reader.close();
+        String s = readSource( src );
 
         // Parse the contents of the file
-        JspDocument tree = new JspDocument();
-        tree.parse( s.toString() );
-        for ( JspDocument.Node node : tree.getNodes() )
+        JspDocument doc = new JspDocument();
+        doc.parse( s.toString() );
+        for ( JspDocument.Node node : doc.getNodes() )
         {
             System.out.println( node.toString() );
         }
 
         // Write the migrated contents to disk
-        writeDestination( dest, tree.toString() );
+        writeDestination( dest, doc.toString() );
         System.out.println( "    done [" + s.length() + " chars]." );
     }
 
@@ -131,5 +124,19 @@
         writer.append( contents );
         writer.close();
     }
+    
+    protected String readSource( File src ) throws IOException
+    {
+        // Read in the file
+        FileReader reader = new FileReader( src );
+        StringBuffer s = new StringBuffer();
+        int ch = 0;
+        while ( (ch = reader.read()) != -1 )
+        {
+            s.append( (char) ch );
+        }
+        reader.close();
+        return s.toString();
+    }
 
 }

Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigratorTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigratorTest.java?rev=692767&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigratorTest.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/util/StripesJspMigratorTest.java Sat Sep  6 19:27:40 2008
@@ -0,0 +1,422 @@
+package com.ecyrd.jspwiki.util;
+
+import java.io.File;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class StripesJspMigratorTest extends TestCase
+{
+    public StripesJspMigratorTest( String s )
+    {
+        super( s );
+    }
+
+    public void testParse() throws Exception
+    {
+        StripesJspMigrator m = new StripesJspMigrator();
+        File src = new File( "src/webdocs/LoginForm.jsp" );
+        String s = m.readSource( src );
+
+        // Parse the contents of the file
+        JspDocument doc = new JspDocument();
+        doc.parse( s.toString() );
+
+        // Should result in 19 nodes parsed (11 tags/directives + 8 text/whitespace nodes
+        JspDocument.Node node;
+        JspDocument.Attribute attribute;
+        List<JspDocument.Node> nodes = doc.getNodes();
+        assertEquals( 19, 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.getStartChar() );
+        assertEquals( 39, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "org.apache.log4j.*", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 40, node.getColumn() );
+        assertEquals( 39, node.getStartChar() );
+        assertEquals( 40, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        
+        // Test line 2 aka nodes 2+3
+        node = nodes.get( i );
+        assertEquals( 2, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 40, node.getStartChar() );
+        assertEquals( 80, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "com.ecyrd.jspwiki.*", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 2, node.getLine() );
+        assertEquals( 41, node.getColumn() );
+        assertEquals( 80, node.getStartChar() );
+        assertEquals( 81, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+
+        // Test line 3 aka nodes 4+5
+        node = nodes.get( i );
+        assertEquals( 3, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 81, node.getStartChar() );
+        assertEquals( 128, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "import", attribute.getName() );
+        assertEquals( "com.ecyrd.jspwiki.action.*", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 3, node.getLine() );
+        assertEquals( 48, node.getColumn() );
+        assertEquals( 128, node.getStartChar() );
+        assertEquals( 129, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        
+        // Test line 4 aka nodes 6+7
+        node = nodes.get( i );
+        assertEquals( 4, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 129, node.getStartChar() );
+        assertEquals( 163, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "page", node.getName() );
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "errorPage", attribute.getName() );
+        assertEquals( "/Error.jsp", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 4, node.getLine() );
+        assertEquals( 35, node.getColumn() );
+        assertEquals( 163, node.getStartChar() );
+        assertEquals( 164, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        
+        // Test line 5 aka nodes 8+9
+        node = nodes.get( i );
+        assertEquals( 5, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 164, node.getStartChar() );
+        assertEquals( 218, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "taglib", node.getName() );
+        assertEquals( 2, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "uri", attribute.getName() );
+        assertEquals( "/WEB-INF/jspwiki.tld", attribute.getValue().getValue() );
+        attribute = node.getAttributes().get( 1 );
+        assertEquals( "prefix", attribute.getName() );
+        assertEquals( "wiki", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 5, node.getLine() );
+        assertEquals( 55, node.getColumn() );
+        assertEquals( 218, node.getStartChar() );
+        assertEquals( 219, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+
+        // Test line 6 aka nodes 10+11
+        node = nodes.get( i );
+        assertEquals( 6, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 219, node.getStartChar() );
+        assertEquals( 276, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_DIRECTIVE, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "taglib", node.getName() );
+        assertEquals( 2, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "uri", attribute.getName() );
+        assertEquals( "/WEB-INF/stripes.tld", attribute.getValue().getValue() );
+        attribute = node.getAttributes().get( 1 );
+        assertEquals( "prefix", attribute.getName() );
+        assertEquals( "stripes", attribute.getValue().getValue() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 6, node.getLine() );
+        assertEquals( 58, node.getColumn() );
+        assertEquals( 276, node.getStartChar() );
+        assertEquals( 277, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        
+        // Test line 7 aka nodes 12+13
+        node = nodes.get( i );
+        assertEquals( 7, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 277, node.getStartChar() );
+        assertEquals( 354, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "stripes:useActionBean", node.getName() );
+        
+        // Node 12 should have 1 attribute: beanclass="com.ecyrd.jspwiki.action.LoginActionBean"
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "beanclass", attribute.getName() );
+        assertEquals ( JspDocument.Node.Type.TEXT, attribute.getValue().getType());
+        assertEquals( "com.ecyrd.jspwiki.action.LoginActionBean", attribute.getValue().getValue() );
+        assertEquals( '"', node.getAttributes().get( 0 ).getQuoteChar() );
+        i++;
+        
+        // Test line 7, node 13 (line break)
+        node = nodes.get( i );
+        assertEquals( 7, node.getLine() );
+        assertEquals( 78, node.getColumn() );
+        assertEquals( 354, node.getStartChar() );
+        assertEquals( 355, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+
+        // Test lines 8-19 aka nodes 14+15
+        node = nodes.get( i );
+        assertEquals( 8, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 355, node.getStartChar() );
+        assertEquals( 767, node.getEndChar() );
+        assertEquals( JspDocument.Node.Type.JSP_DECLARATION, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        node = nodes.get( i );
+        assertEquals( 19, node.getLine() );
+        assertEquals( 3, node.getColumn() );
+        assertEquals( 767, node.getStartChar() );
+        assertEquals( 768, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+        
+        // Test line 20-33 aka node 16
+        node = nodes.get( i );
+        assertEquals( 20, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 768, node.getStartChar() );
+        assertEquals( 1513, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.SCRIPTLET, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        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.getStartChar() );
+        assertEquals( 1553, node.getEndChar() );
+        assertEquals( 1, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 17, node.getSiblings().size() );
+        assertEquals( "wiki:Include", node.getName() );
+        
+        // Node 17 should have 1 attribute: page="<%=contentPage%>" 
+        assertEquals( 1, node.getAttributes().size() );
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "page", attribute.getName() );
+        assertEquals ( JspDocument.Node.Type.JSP_EXPRESSION, attribute.getValue().getType());
+        assertEquals( "contentPage", attribute.getValue().getValue() );
+        assertEquals( '"', node.getAttributes().get( 0 ).getQuoteChar() );
+        i++;
+        
+        // Test child tag of second tag on line 33 aka node 18
+        node = nodes.get( i );
+        assertEquals( 33, node.getLine() );
+        assertEquals( 23, node.getColumn() );
+        assertEquals( 1533, node.getStartChar() );
+        assertEquals( 1549, node.getEndChar() );
+        assertEquals( 0, node.getChildren().size() );
+        assertEquals( JspDocument.Node.Type.JSP_EXPRESSION, node.getType() );
+        assertEquals( nodes.get( i - 1 ), node.getParent() );
+        assertEquals( 2, node.getLevel() );
+        assertEquals( 0, node.getSiblings().size() );
+        assertEquals( null, node.getName() );
+        assertEquals( 0, node.getAttributes().size() );
+        i++;
+    }
+    
+    public void testParseNested()
+    {
+        JspDocument doc = new JspDocument();
+        doc.parse( "  <wiki:Include page=\"<%=contentPage%>\" var=\'Foo\' />  " );
+        
+        List<JspDocument.Node> nodes = doc.getNodes();
+        JspDocument.Node node;
+        assertEquals( 4, nodes.size());
+        
+        // Node 1: text node
+        node = nodes.get( 0 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 1, node.getColumn() );
+        assertEquals( 0, node.getStartChar() );
+        assertEquals( 2, node.getEndChar() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( null, node.getName() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+        
+        // Node 2: HTML tag with nested child
+        node = nodes.get( 1 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 3, node.getColumn() );
+        assertEquals( 2, node.getStartChar() );
+        assertEquals( 52, node.getEndChar() );
+        assertEquals( JspDocument.Node.Type.HTML_COMBINED_TAG, node.getType() );
+        assertEquals( "wiki:Include page=\"<%=contentPage%>\" var=\'Foo\' ", node.getValue() );
+        assertEquals( "wiki:Include", node.getName() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 1, node.getChildren().size() );
+        assertEquals( nodes.get( 2 ), node.getChildren().get( 0 ) );
+        
+        // Node 2: test attributes
+        assertEquals( 2, node.getAttributes().size() );
+        JspDocument.Attribute attribute;
+        attribute = node.getAttributes().get( 0 );
+        assertEquals( "page", attribute.getName() );
+        assertEquals( '"', attribute.getQuoteChar() );
+        assertEquals( JspDocument.Node.Type.JSP_EXPRESSION, attribute.getValue().getType() );
+        assertEquals( "contentPage", attribute.getValue().getValue() );
+        attribute = node.getAttributes().get( 1 );
+        assertEquals( "var", attribute.getName() );
+        assertEquals( '\'', attribute.getQuoteChar() );
+        assertEquals( JspDocument.Node.Type.TEXT, attribute.getValue().getType() );
+        assertEquals( "Foo", attribute.getValue().getValue() );
+        
+        // Node 3: nested JSP expression
+        node = nodes.get( 2 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 23, node.getColumn() );
+        assertEquals( 22, node.getStartChar() );
+        assertEquals( 38, node.getEndChar() );
+        assertEquals( JspDocument.Node.Type.JSP_EXPRESSION, node.getType() );
+        assertEquals( "contentPage", node.getValue() );
+        assertEquals( null, node.getName() );
+        assertEquals( nodes.get( 1 ), node.getParent() );
+        assertEquals( 2, node.getLevel() );
+        assertEquals( 0, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+        
+        // Node 4: text
+        node = nodes.get( 3 );
+        assertEquals( 1, node.getLine() );
+        assertEquals( 53, node.getColumn() );
+        assertEquals( 52, node.getStartChar() );
+        assertEquals( 54, node.getEndChar() );
+        assertEquals( JspDocument.Node.Type.TEXT, node.getType() );
+        assertEquals( "  ", node.getValue() );
+        assertEquals( null, node.getName() );
+        assertEquals( null, node.getParent() );
+        assertEquals( 1, node.getLevel() );
+        assertEquals( 2, node.getSiblings().size() );
+        assertEquals( 0, node.getChildren().size() );
+    }
+
+}