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/10/05 05:44:23 UTC
svn commit: r701746 [1/2] -
/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/
Author: ajaquith
Date: Sat Oct 4 20:44:22 2008
New Revision: 701746
URL: http://svn.apache.org/viewvc?rev=701746&view=rev
Log:
Even more refactoring of JSP migration code. Now able to chomp through quite a sizable chunk of the existing JSPs, although there are still some NPEs that need chasing.
Added:
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigratorTest.java
Removed:
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDirective.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Markup.java
Modified:
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/AbstractNode.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Attribute.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformer.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformerTest.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocumentTest.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigrator.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java
incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Text.java
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/AbstractNode.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/AbstractNode.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/AbstractNode.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/AbstractNode.java Sat Oct 4 20:44:22 2008
@@ -119,28 +119,6 @@
/*
* (non-Javadoc)
*
- * @see com.ecyrd.jspwiki.ui.stripes.Node#getLevel()
- */
- public int getLevel()
- {
- if( m_parent == null )
- {
- return -1;
- }
-
- int level = 0;
- Node node = this;
- while ( node.getType() != NodeType.ROOT )
- {
- level++;
- node = node.getParent();
- }
- return level;
- }
-
- /*
- * (non-Javadoc)
- *
* @see com.ecyrd.jspwiki.ui.stripes.Node#getLine()
*/
public int getLine()
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Attribute.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Attribute.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Attribute.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Attribute.java Sat Oct 4 20:44:22 2008
@@ -28,7 +28,11 @@
@Override
public void setType( NodeType type )
{
- throw new UnsupportedOperationException( "Attributes are always of type NodeType.ATTRIBUTE; illegal to call this method." );
+ if ( type != NodeType.ATTRIBUTE && type != NodeType.DYNAMIC_ATTRIBUTE )
+ {
+ throw new UnsupportedOperationException( "Attributes are always of type NodeType.ATTRIBUTE or NodeType.DYNAMIC_ATTRIBUTE." );
+ }
+ super.setType( type );
}
/**
@@ -37,14 +41,21 @@
public String toString()
{
StringBuilder sb = new StringBuilder();
- sb.append( m_name );
- sb.append( '=' );
- sb.append( m_quote );
- for ( Node valueNode : m_children )
+ if ( m_type == NodeType.ATTRIBUTE )
+ {
+ sb.append( m_name );
+ sb.append( '=' );
+ sb.append( m_quote );
+ for ( Node valueNode : m_children )
+ {
+ sb.append( valueNode.toString() );
+ }
+ sb.append( m_quote );
+ }
+ else
{
- sb.append( valueNode.toString() );
+ sb.append( getValue() );
}
- sb.append( m_quote );
return sb.toString();
}
}
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformer.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformer.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformer.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformer.java Sat Oct 4 20:44:22 2008
@@ -30,9 +30,9 @@
removeSetBundle( tag );
}
- // Advise user about <input type="hidden"> tags
+ // Advise user about <input type="hidden"> or <stripes:hidden> tags
boolean isTypeHidden = false;
- isTypeHidden = "stripes:form".equals( tag.getName() );
+ isTypeHidden = "stripes:hidden".equals( tag.getName() ) && tag.getType() != NodeType.HTML_END_TAG;
if( "input".equals( tag.getName() ) )
{
Attribute attribute = tag.getAttribute( "type" );
@@ -41,7 +41,7 @@
if( isTypeHidden )
{
Attribute hidden = tag.getAttribute( "name" );
- message( hidden, "NOTE: hidden form input \"" + hidden.getValue()
+ message( hidden, "NOTE: hidden form input with name \"" + hidden.getValue()
+ "\" should probably correspond to a Stripes ActionBean getter/settter. Refactor?" );
}
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformerTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformerTest.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformerTest.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JSPWikiJspTransformerTest.java Sat Oct 4 20:44:22 2008
@@ -1,5 +1,6 @@
package com.ecyrd.jspwiki.ui.stripes;
+import java.io.File;
import java.util.HashMap;
import java.util.Map;
@@ -72,6 +73,14 @@
assertEquals( "form", node.getName() );
}
+ public void testParseWeirdDoc() throws Exception
+ {
+ File src = new File( "src/webdocs/Captcha.jsp" );
+ String s = JspMigrator.readSource( src );
+
+ JspDocument doc = new JspParser().parse( s );
+ m_transformer.transform( m_sharedState, doc );
+ }
public static Test suite()
{
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocumentTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocumentTest.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocumentTest.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocumentTest.java Sat Oct 4 20:44:22 2008
@@ -30,8 +30,6 @@
assertEquals( 5, endTag.getStart() );
assertEquals( 11, endTag.getEnd() );
assertEquals( "foo", endTag.getName() );
-
- Node child = new Tag( doc, NodeType.HTML_COMBINED_TAG );
}
public static Test suite()
Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigrator.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigrator.java?rev=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigrator.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigrator.java Sat Oct 4 20:44:22 2008
@@ -151,7 +151,7 @@
writer.close();
}
- protected String readSource( File src ) throws IOException
+ protected static String readSource( File src ) throws IOException
{
// Read in the file
FileReader reader = new FileReader( src );
Added: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigratorTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigratorTest.java?rev=701746&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigratorTest.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspMigratorTest.java Sat Oct 4 20:44:22 2008
@@ -0,0 +1,27 @@
+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 JspMigratorTest 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 JspMigratorTest( String s )
+ {
+ super( s );
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite( JspMigratorTest.class );
+ }
+}
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParser.java Sat Oct 4 20:44:22 2008
@@ -8,15 +8,18 @@
*/
public class JspParser
{
- private static final ParserDelegate TEXT_PARSER = new TextParser();
+ private static final Parser TEXT_PARSER = new TextParser();
- private static final JspTagParser JSP_TAG_PARSER = new JspTagParser();
-
- private static final ParserDelegate HTML_TAG_PARSER = new HtmlTagParser();
+ private static final Parser TAG_PARSER = new TagParser();
private static final AttributeParser ATTRIBUTE_PARSER = new AttributeParser();
+
+ private static final DynamicAttributeParser DYNAMIC_ATTRIBUTE_PARSER = new DynamicAttributeParser();
- public static class AttributeParser extends ParserDelegate
+ /**
+ * Parses dynamic attributes in a Tag declaration.
+ */
+ public static class DynamicAttributeParser implements Parser
{
public void beginStage()
{
@@ -26,10 +29,75 @@
{
}
+ public void handle( char ch )
+ {
+ ParseContext ctx = ParseContext.currentContext();
+ int leftAngleBrackets = 1;
+ boolean increment = false;
+ do
+ {
+ // Get character at current position
+ // Increment position
+ if ( increment )
+ {
+ ctx.incrementPosition();
+ }
+ ch = ctx.getSource().charAt( ctx.position() );
+
+ switch (ch) {
+
+ case ('<'):
+ {
+ leftAngleBrackets++;
+ break;
+ }
+ case ('>'):
+ {
+ leftAngleBrackets--;
+ break;
+ }
+ default:
+ {
+ // Ignore any other character
+ }
+ increment = true;
+ }
+
+ } while ( leftAngleBrackets != 0 );
+
+ // Set the end position, name and value.
+ Attribute attribute = (Attribute)ctx.getNode();
+ ctx.setEndPosition( attribute );
+ attribute.setType( NodeType.DYNAMIC_ATTRIBUTE );
+ attribute.setValue( ctx.getSource().substring( ctx.getMarkerForStage( Stage.CODE_OR_COMMENT), attribute.getEnd() ) );
+
+ // Add to parent
+ Tag parent = (Tag)ctx.getParentContext().getNode();
+ parent.addAttribute( attribute );
+
+ // Pop the ParseContext and exit
+ ParseContext.pop();
+ }
+ }
+
+ public static class AttributeParser implements Parser
+ {
+ public void beginStage()
+ {
+ ParseContext ctx = ParseContext.currentContext();
+ Node attribute = new Attribute( ctx.getDocument() );
+ ctx.setNode( attribute );
+ }
+
+ public void endStage()
+ {
+ ParseContext ctx = ParseContext.currentContext();
+ Node attribute = ctx.getNode();
+ attribute.setEnd( ctx.position() );
+ }
+
/**
- * Handles {@link NodeLifecycle#TAG_WHITESPACE},
- * {@link NodeLifecycle#ATTRIBUTE_EQUALS},
- * {@link NodeLifecycle#ATTRIBUTE_VALUE}.
+ * {@link Stage#NAME}.
*/
public void handle( char ch )
{
@@ -38,76 +106,38 @@
switch( ctx.getStage() )
{
- // Whitespace between node name and first attribute, or
- // between attributes.
- case TAG_WHITESPACE: {
- switch( ch )
- {
- case (' '): {
- break;
- }
- case ('/'): {
- // If we see /, switch back to HTML tag parser
- ctx.setParser( HTML_TAG_PARSER, NodeLifecycle.TAG_WHITESPACE );
- break;
- }
- case ('%'): {
- // Ignore the % because we might be in a JSP
- // directive/element
- break;
- }
- case ('>'): {
- // Switch back to HTML tag parser so its endStage()
- // method is called
- ctx.setParser( HTML_TAG_PARSER );
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
- break;
- }
- default: {
- // Create new attribute
- Attribute attribute = new Attribute( ctx.getDocument() );
- attribute.setParent( ctx.getNode() );
- ctx.setAttribute( attribute );
- ctx.setStage( NodeLifecycle.ATTRIBUTE_NAME );
- }
- }
- break;
- }
-
- // Characters that name an attribute, after whitespace but
- // before equals (=).
- case ATTRIBUTE_NAME: {
+ // Characters that name an attribute, after whitespace but
+ // before equals (=).
+ case NAME: {
if( ch == '=' )
{
// Set the attribute name
- Attribute attribute = ctx.getAttribute();
+ Attribute attribute = (Attribute) ctx.getNode();
attribute.setName( ctx.getSource().substring( attribute.getStart(), pos ) );
- ctx.setStage( NodeLifecycle.ATTRIBUTE_EQUALS );
+
+ // The next character will be a single/double quote
+ ctx.incrementPosition();
+ char delimiter = ctx.getSource().charAt( ctx.position() );
+ attribute.setAttributeDelimiter( delimiter );
+
+ // Start a new ParseContext, and Text node in position
+ // after quote
+ ctx = ParseContext.push();
+ ctx.setStartPosition( ctx.getNode(), ctx.position() + 1 );
}
break;
}
- // The equals (=) that separates the attribute name and
- // value.
- case ATTRIBUTE_EQUALS: {
- if( ch == '\'' || ch == '\"' )
- {
- // Save the quote delimiter for later
- Attribute attribute = ctx.getAttribute();
- attribute.setAttributeDelimiter( ch );
-
- // Push current ParseContext and Node onto stack
- ctx = ctx.push();
- ctx.pushNode( attribute );
-
- // Assign new text node to ParseContext, set as child of
- // attribute
- Text text = new Text( ctx.getDocument() );
- text.setParent( ctx.getParentNode() );
- ctx.setNode( text );
- ctx.setStartPosition( text, ctx.position() );
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
- }
+ case ATTRIBUTE_END: {
+ // Add the finished attribute to the parent
+ Attribute attribute = (Attribute) ctx.getNode();
+ Tag parent = (Tag) attribute.getParent();
+ parent.addAttribute( attribute );
+
+ // Retrieve the Tag ParseContext & fire the handler method
+ ctx = ParseContext.pop();
+ Parser parser = ctx.getParser();
+ parser.handle( ch );
break;
}
}
@@ -115,85 +145,182 @@
}
- public static class HtmlTagParser extends ParserDelegate
+ public static class TagParser implements Parser
{
- public void beginStage()
+ /**
+ * Factory method that initializes a supplied Node. When initialized,
+ * 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 the stage to set at the end of the initialization
+ */
+ private void initNode( Node node, Stage stage )
{
+ ParseContext ctx = ParseContext.currentContext();
+ ctx.setNode( node );
+
+ // Skip ahead if tag start > 1 char long
+ int increment = node.getType().getTagStart().length() - 1;
+ for( int i = 0; i < increment; i++ )
+ {
+ ctx.incrementPosition();
+ }
+
+ // Set the new stage and mark it at the next character
+ ctx.setStage( stage, 1 );
}
- public void endStage()
+ public void beginStage()
{
ParseContext ctx = ParseContext.currentContext();
- Node node = ctx.getNode();
- // Finalize the node type if it is still undefined
- if( node.getType() == NodeType.UNRESOLVED_HTML_TAG )
+ // Figure out what this tag is
+ String lookahead = ctx.lookahead( 4 );
+ String lookahead9 = ctx.lookahead( 9 );
+ JspDocument doc = ctx.getDocument();
+
+ // <%- means hidden JSP comment
+ if( lookahead.startsWith( NodeType.JSP_COMMENT.getTagStart() ) )
{
- char lastCh = ctx.getSource().charAt( ctx.position() - 1 );
- if( lastCh == '/' )
- {
- node.setType( NodeType.HTML_COMBINED_TAG );
- }
- else
+ initNode( new Text( doc, NodeType.JSP_COMMENT ), Stage.CODE_OR_COMMENT );
+ }
+
+ // <%! means JSP declaration
+ else if( lookahead.startsWith( NodeType.JSP_DECLARATION.getTagStart() ) )
+ {
+ initNode( new Text( doc, NodeType.JSP_DECLARATION ), Stage.CODE_OR_COMMENT );
+ }
+
+ // <%= means JSP expression
+ else if( lookahead.startsWith( NodeType.JSP_EXPRESSION.getTagStart() ) )
+ {
+ initNode( new Text( doc, NodeType.JSP_EXPRESSION ), Stage.CODE_OR_COMMENT );
+ }
+
+ // <%@ + space means JSP directive
+ else if( lookahead.startsWith( NodeType.JSP_DIRECTIVE.getTagStart() ) )
+ {
+ initNode( new Tag( doc, NodeType.JSP_DIRECTIVE ), Stage.NAME );
+ }
+
+ // <!-- means HTML comment
+ else if( lookahead.startsWith( NodeType.HTML_COMMENT.getTagStart() ) )
+ {
+ initNode( new Text( doc, NodeType.HTML_COMMENT ), Stage.CODE_OR_COMMENT );
+ }
+
+ // Whitespace after <% means
+ // scriptlet
+ else if( lookahead.startsWith( NodeType.SCRIPTLET.getTagStart() ) )
+ {
+ if( lookahead.length() >= 3 && Character.isWhitespace( lookahead.charAt( 2 ) ) )
{
- // If no /, it's an HTML start tag, and new nodes should be
- // children of it
- node.setType( NodeType.HTML_START_TAG );
- ctx.pushNode( node );
+ initNode( new Text( doc, NodeType.SCRIPTLET ), Stage.CODE_OR_COMMENT );
}
}
+
+ // <![CDATA[ means CDATA
+ else if( lookahead9.startsWith( NodeType.CDATA.getTagStart() ) )
+ {
+ initNode( new Text( doc, NodeType.CDATA ), Stage.CODE_OR_COMMENT );
+ }
- // Set the end position
- ctx.setEndPosition( node );
+ // If </, it's an HTML end tag
+ else if( lookahead.startsWith( NodeType.HTML_END_TAG.getTagStart() ) )
+ {
+ initNode( new Tag( doc, NodeType.HTML_END_TAG ), Stage.NAME );
+ }
- // If node length is > 0, add it to the parent
- if( node.getEnd() > node.getStart() )
+ // Any other char means its HTML start tag
+ // or combined tag
+ else
{
- node.getParent().addChild( node );
+ initNode( new Tag( doc, NodeType.UNRESOLVED_HTML_TAG ), Stage.NAME );
+ }
+ }
+
+ public void endStage()
+ {
+ ParseContext ctx = ParseContext.currentContext();
+ Node node = ctx.getNode();
+
+ if( node != null )
+ {
+ // Set the end position
+ ctx.setEndPosition( node );
+
+ // If node length is > 0, add it to the parent
+ if( node.getEnd() > node.getStart() )
+ {
+ node.getParent().addChild( node );
+ }
}
}
/**
- * Handles {@link NodeLifecycle#TAG_NAME}.
+ * Handles {@link Stage#NAME}.
*/
public void handle( char ch )
{
ParseContext ctx = ParseContext.currentContext();
+ Node node = ctx.getNode();
switch( ctx.getStage() )
{
- // After < but before whitespace that delimit attributes.
- case TAG_NAME: {
+ // Characters that supply the tag name; immediately after <
+ case NAME: {
switch( ch )
{
- // If current character is whitespace, set the name and
- // move
- // to attributes stage
+ // Whitespace == end of the name
case (' '): {
- finalizeTagName();
- ctx.setParser( ATTRIBUTE_PARSER );
- ctx.setStage( NodeLifecycle.TAG_WHITESPACE );
+ int nameStart = ctx.getMarkerForStage( Stage.NAME );
+ int nameEnd = ctx.position();
+ node.setName( ctx.getSource().substring( nameStart, nameEnd ) );
+ ctx.setStage( Stage.WHITESPACE, 0 );
break;
}
// Right angle bracket == end of the node
case ('>'): {
- finalizeTagName();
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
+ handleTagEnd();
break;
}
}
break;
}
- // Whitespace immediately before >
- case TAG_WHITESPACE: {
+ // Whitespace between <%! and name, or between attributes.
+ case WHITESPACE: {
switch( ch )
{
+ case ('/'):
+ case (' '):
+ case ('%'): {
+ break;
+ }
+
+ // It's the start of a new dynamic attribute
+ case ('<'): {
+ ctx = ParseContext.push();
+ ctx.setParser( DYNAMIC_ATTRIBUTE_PARSER, Stage.CODE_OR_COMMENT, 0 );
+ ctx.setNode( new Attribute( ctx.getDocument() ) );
+ break;
+ }
+
case ('>'): {
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
+ handleTagEnd();
break;
}
+
+ default: {
+ // It's the start of a new attribute
+ ctx = ParseContext.push();
+ ctx.setParser( ATTRIBUTE_PARSER, Stage.NAME, 0 );
+ }
}
break;
}
@@ -201,11 +328,11 @@
case CODE_OR_COMMENT: {
switch( ch )
{
- // Terminating %> means the end of the comment
+ // Terminating %> or --> means the end of the comment
case ('>'): {
- Node node = ctx.getNode();
- String lookbehind = ctx.lookbehind( 3 );
- if( lookbehind.equals( NodeType.HTML_COMMENT.getTagEnd() ) )
+ String tagEnd = node.getType().getTagEnd();
+ String lookbehind = ctx.lookbehind( tagEnd.length() );
+ if( lookbehind.equals( tagEnd ) )
{
// Set the end position
node.setEnd( ctx.position() + 1 );
@@ -215,7 +342,7 @@
node.setValue( ctx.getSource().substring( node.getStart() + type.getTagStart().length(),
node.getEnd() - type.getTagEnd().length() ) );
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
+ ctx.setParser( TEXT_PARSER, Stage.TEXT, 1 );
}
break;
}
@@ -225,119 +352,89 @@
}
}
- private void finalizeTagName()
- {
- ParseContext ctx = ParseContext.currentContext();
- Node node = ctx.getNode();
- int nameStart = node.getStart() + node.getType().getTagStart().length();
- int nameEnd = ctx.position();
- if( nameEnd - nameStart > 0 )
- {
- if( ctx.getSource().charAt( nameEnd - 1 ) == '/' )
- {
- nameEnd--;
- }
- node.setName( ctx.getSource().substring( nameStart, nameEnd ) );
- }
- }
- }
-
- public static class JspTagParser extends ParserDelegate
- {
- public void beginStage()
- {
- }
-
- public void endStage()
- {
- }
-
/**
- * Handles {@link NodeLifecycle#TAG_WHITESPACE},
- * {@link NodeLifecycle#TAG_NAME},
- * {@link NodeLifecycle#CODE_OR_COMMENT}.
+ * <p>
+ * Finishes up an HTML or JSP tag when > is detected by the handler
+ * method {@link #handle(char)}, but before {@link #endStage()}
+ * executes. Because HTML parsing can be messy, this method resolves
+ * several edge cases:
+ * </p>
+ * <ul>
+ * <li>If the tag's type has not been determined (that is, its current
+ * type is {@link NodeType#UNRESOLVED_HTML_TAG}, its type is resolved
+ * to either {@link NodeType#HTML_COMBINED_TAG} or
+ * {@link NodeType#HTML_START_TAG}, depending on whether the last
+ * character was /.
+ * <li>
+ * <li>If the tag's name has not been set, because the parser has not
+ * encountered whitespace that delimits attributes, its name is set.</li>
+ * <li>If the tag is of type {@link NodeType#HTML_START_TAG} or
+ * {@link NodeType#HTML_START_TAG}, the current ParseContext is pushed
+ * on, or popped off, of the stack. In addition, if the tag is an end
+ * tag, its parent is re-wired to the same parent as the start tag. This
+ * makes the start and end tag logical peers, as they should be.</li>
+ * </ul>
+ * <p>
+ * After these cases are resolved, the current node is re-set to a Text
+ * node, in the character position starting after the right angle
+ * bracket (>).
+ * </p>
*/
- public void handle( char ch )
+ private void handleTagEnd()
{
ParseContext ctx = ParseContext.currentContext();
Node node = ctx.getNode();
- switch( ctx.getStage() )
+ // Resolve tag type if not set
+ if( node.getType() == NodeType.UNRESOLVED_HTML_TAG )
{
- // Whitespace between node name and first attribute, or
- // between attributes.
- case TAG_WHITESPACE: {
- switch( ch )
- {
- case (' '): {
- break;
- }
- default: {
- // If directive name not set, start new ParseContext (and set marker)
- if ( node.getName() == null )
- {
- ctx = ctx.push();
- ctx.setParser( JSP_TAG_PARSER );
- ctx.setStage( NodeLifecycle.TAG_NAME ); // Sets the marker too
- }
-
- // Otherwise, it's the start of a new attribute
- else
- {
- }
- }
- }
- break;
+ String lookbehind = ctx.lookbehind( 2 );
+ if( NodeType.HTML_COMBINED_TAG.getTagEnd().equals( lookbehind ) )
+ {
+ node.setType( NodeType.HTML_COMBINED_TAG );
}
- // Characters that supply the JSP directive name.
- case TAG_NAME: {
- if( ch == ' ' )
- {
- int nameStart = ctx.getMarker( NodeLifecycle.TAG_NAME ); // Retrieve the marker
- ctx = ctx.pop();
- Node directive = ctx.getNode();
- directive.setName( ctx.getSource().substring( nameStart, ctx.position() ) );
- ctx.setParser( ATTRIBUTE_PARSER );
- ctx.setStage( NodeLifecycle.TAG_WHITESPACE );
- }
- break;
+ else
+ {
+ node.setType( NodeType.HTML_START_TAG );
}
+ }
- case CODE_OR_COMMENT: {
- switch( ch )
- {
- // Terminating %> means the end of the scriptlet
- case ('>'): {
- String lookbehind = ctx.lookbehind( 2 );
- if( lookbehind.equals( NodeType.SCRIPTLET.getTagEnd() ) )
- {
- // Set the end position
- node.setEnd( ctx.position() + 1 );
-
- // Set the value
- NodeType type = node.getType();
- node.setValue( ctx.getSource().substring( node.getStart() + type.getTagStart().length(),
- node.getEnd() - type.getTagEnd().length() ) );
+ // Set the name if not set
+ if( node.getName() == null )
+ {
+ int nameStart = ctx.getMarkerForStage( Stage.NAME );
+ int nameEnd = ctx.position() + 1 - node.getType().getTagEnd().length();
+ node.setName( ctx.getSource().substring( nameStart, nameEnd ) );
+ }
- // If node length is > 0, add it to the parent
- if( node.getEnd() > node.getStart() )
- {
- node.getParent().addChild( node );
- }
- ctx.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
- }
- break;
- }
- }
+ // If start or end tag, push/pop as needed;
+ // otherwise start new Text
+ switch( node.getType() )
+ {
+ case HTML_START_TAG: {
+ // Add the start tag to parent, and push it onto stack
+ endStage();
+ ctx = ParseContext.push();
+ break;
+ }
+ case HTML_END_TAG: {
+ // Make end tag the peer of the start tag
+ Node startTag = node.getParent();
+ node.setParent( startTag.getParent() );
+
+ // Get rid of the current node in the parent context
+ ctx = ParseContext.pop();
+ ctx.setNode( null );
break;
}
}
+ // Start new Text node after the >
+ ctx.setParser( TEXT_PARSER, Stage.TEXT, 1 );
}
-
}
- public static abstract class ParserDelegate
+ public interface Parser
{
public abstract void beginStage();
@@ -346,24 +443,16 @@
public abstract void handle( char ch );
}
- public static class TextParser extends ParserDelegate
+ public static class TextParser implements Parser
{
public void beginStage()
{
+ // Create Text node and set start at next character
ParseContext ctx = ParseContext.currentContext();
- int pos = ctx.position() + 1;
-
- // Create new Text
Text text = new Text( ctx.getDocument() );
-
- // Set parent relationship
- text.setParent( ctx.getParentNode() );
ctx.setNode( text );
- ctx.setAttribute( null );
-
- // Set the start, end, linebreak
- ctx.setStartPosition( text, pos );
+ ctx.setStartPosition( ctx.getNode(), ctx.position() + 1 );
}
public void endStage()
@@ -389,122 +478,44 @@
}
/**
- * Handles {@link NodeLifecycle#PARSING_TEXT}.
+ * Handles {@link Stage#TEXT}.
*/
public void handle( char ch )
{
ParseContext ctx = ParseContext.currentContext();
switch( ctx.getStage() )
{
- case PARSING_TEXT: {
+ case TEXT: {
switch( ch )
{
// If we see a quote, check to see if it's a part of a
// parent attribute
case ('\''):
case ('"'): {
- if( ctx.hasParentContext() )
+ Node node = ctx.getNode();
+ Node parent = node.getParent();
+ if( parent instanceof Attribute )
{
- Attribute attribute = ctx.getParentContext().getAttribute();
- if( attribute != null && ch == attribute.getAttributeDelimiter() )
+ Attribute attribute = (Attribute) parent;
+ if( ch == attribute.getAttributeDelimiter() )
{
- // Pop the ParseContext (and run its
- // endStage method) and Node
- ctx = ctx.pop();
- ctx.popNode();
-
- // Finish the parent attribute
- Node node = attribute.getParent();
- attribute.setEnd( ctx.position() + 1 );
- if( node.isHtmlNode() )
- {
- ((Tag) node).addAttribute( attribute );
- }
- else if( node.getType() == NodeType.JSP_DIRECTIVE )
- {
- ((JspDirective) node).addAttribute( attribute );
- }
- ctx.setAttribute( null );
- ctx.setParser( ATTRIBUTE_PARSER, NodeLifecycle.TAG_WHITESPACE );
+ ctx = ParseContext.pop();
+ ctx.setStage( Stage.ATTRIBUTE_END, 0 );
}
}
break;
}
case ('<'): {
-
- // Figure out what this tag is
- String lookahead = ctx.lookahead( 4 );
- JspDocument doc = ctx.getDocument();
-
- // <%- means hidden JSP comment
- if( lookahead.startsWith( NodeType.JSP_COMMENT.getTagStart() ) )
- {
- ctx.setParser( JSP_TAG_PARSER, NodeLifecycle.CODE_OR_COMMENT );
- initNode( new Markup( doc, NodeType.JSP_COMMENT ) );
- }
-
- // <%! means JSP declaration
- else if( lookahead.startsWith( NodeType.JSP_DECLARATION.getTagStart() ) )
- {
- ctx.setParser( JSP_TAG_PARSER, NodeLifecycle.CODE_OR_COMMENT );
- initNode( new Markup( doc, NodeType.JSP_DECLARATION ) );
- }
-
- // <%= means JSP expression
- else if( lookahead.startsWith( NodeType.JSP_EXPRESSION.getTagStart() ) )
+ // Valid XML or JSP tag start?
+ String lookahead = ctx.lookahead( 2 );
+ if( lookahead.length() == 2 )
{
- ctx.setParser( JSP_TAG_PARSER, NodeLifecycle.CODE_OR_COMMENT );
- initNode( new Markup( doc, NodeType.JSP_EXPRESSION ) );
- }
-
- // <%@ means JSP directive
- else if( lookahead.startsWith( NodeType.JSP_DIRECTIVE.getTagStart() ) )
- {
- ctx.setParser( JSP_TAG_PARSER, NodeLifecycle.TAG_WHITESPACE );
- initNode( new JspDirective( doc ) );
- }
-
- // <!-- means HTML comment
- else if( lookahead.startsWith( NodeType.HTML_COMMENT.getTagStart() ) )
- {
- ctx.setParser( HTML_TAG_PARSER, NodeLifecycle.CODE_OR_COMMENT );
- initNode( new Markup( doc, NodeType.HTML_COMMENT ) );
- }
-
- // Whitespace after <% means
- // scriptlet
- else if( lookahead.startsWith( NodeType.SCRIPTLET.getTagStart() ) )
- {
- if( lookahead.length() >= 3 && Character.isWhitespace( lookahead.charAt( 2 ) ) )
+ char nextChar = lookahead.charAt( 1 );
+ if( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!/%_:".indexOf( nextChar ) != -1 )
{
- ctx.setParser( JSP_TAG_PARSER, NodeLifecycle.CODE_OR_COMMENT );
- initNode( new Markup( doc, NodeType.SCRIPTLET ) );
+ ctx.setParser( TAG_PARSER, Stage.TAG_START, 0 );
}
}
-
- // If </, it's an HTML end tag
- else if( lookahead.startsWith( NodeType.HTML_END_TAG.getTagStart() ) )
- {
- ctx.setParser( HTML_TAG_PARSER, NodeLifecycle.TAG_NAME );
- initNode( new Tag( doc, NodeType.HTML_END_TAG ) );
- }
-
- // If < plus space, it's just ordinary
- // (albeit sloppy) markup
- else if( "< ".equals( lookahead.subSequence( 0, 2 ) ) )
- {
- ctx.setStage( NodeLifecycle.PARSING_TEXT );
- initNode( new Text( doc ) );
- }
-
- // Any other char means its HTML start tag
- // or combined tag
- else
- {
- ctx.setParser( HTML_TAG_PARSER, NodeLifecycle.TAG_NAME );
- initNode( new Tag( doc, NodeType.UNRESOLVED_HTML_TAG ) );
- }
-
break;
}
}
@@ -514,42 +525,6 @@
}
- /**
- * Factory method that initializes a supplied Node. When initialized,
- * 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
- */
- private void initNode( Node node )
- {
- ParseContext ctx = ParseContext.currentContext();
-
- // If HTML end tag, pop the node stack first
- if( node.getType() == NodeType.HTML_END_TAG )
- {
- ctx.popNode();
- }
-
- // Set parent relationship
- node.setParent( ctx.getParentNode() );
- ctx.setNode( node );
- ctx.setAttribute( null );
-
- // Set the start, end, linebreak
- ctx.setStartPosition( node, ctx.position() );
-
- // Skip ahead if tag start > 1 char long
- int increment = node.getType().getTagStart().length() - 1;
- for( int i = 0; i < increment; i++ )
- {
- ctx.incrementPosition();
- }
- }
-
}
private static final class Counter
@@ -572,37 +547,30 @@
}
}
- private enum NodeLifecycle
+ private enum Stage
{
+ /**
+ * Parsing the left-angle bracket that starts the node (<).
+ */
+ TAG_START,
/** Parsing any text outside of a tag or element. */
- PARSING_TEXT,
+ TEXT,
/**
- * Characters after the opening left bracket (<), but before
- * whitespace that delimit the attributes.
+ * Characters that name a node. For tags, the node name begins after the
+ * opening left bracket (<) and ends before the first whitespace
+ * character. For attributes, the name begins after any whitespace and
+ * ends before the equals (=) character.
*/
- TAG_NAME,
+ NAME,
/**
* Whitespace between the node or directive name and the first
* attribute, and between attributes.
*/
- TAG_WHITESPACE,
- /**
- * 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,
+ WHITESPACE,
/** Any text inside of a scriptlet, JSP comment, or JSP declaration. */
CODE_OR_COMMENT,
+ /** Finishing an attribute. */
+ ATTRIBUTE_END
}
/**
@@ -610,8 +578,6 @@
*/
private static class ParseContext
{
- private static final Stack<Node> NODE_STACK = new Stack<Node>();
-
private static final Stack<ParseContext> CONTEXT_STACK = new Stack<ParseContext>();
private static ParseContext CURRENT_CONTEXT;
@@ -623,42 +589,36 @@
public static ParseContext initialContext( JspDocument doc, String source )
{
- NODE_STACK.clear();
CONTEXT_STACK.clear();
ParseContext context = new ParseContext( doc, source, new Counter() );
- context.pushNode( doc.getRoot() );
CURRENT_CONTEXT = context;
// Set the default stage to TEXT
Text text = new Text( doc );
- text.setParent( doc.getRoot() );
context.setNode( text );
- context.setAttribute( null );
context.setStartPosition( text, 0 );
- context.m_stage = NodeLifecycle.PARSING_TEXT;
+ context.m_stage = Stage.TEXT;
context.m_parser = TEXT_PARSER;
// Return the init'ed context
return context;
}
- private ParserDelegate m_parser = null;
+ private Parser m_parser = null;
private final List<Integer> lineBreaks = new ArrayList<Integer>();
private Node m_node = null;
- private Attribute m_attribute = null;
-
private final Counter m_counter;
private final String m_source;
- private NodeLifecycle m_stage = NodeLifecycle.PARSING_TEXT;
+ private Stage m_stage = Stage.TEXT;
private JspDocument m_doc;
- private Map<NodeLifecycle, Integer> m_markers = new HashMap<NodeLifecycle, Integer>();
+ private Map<Stage, Integer> m_markers = new HashMap<Stage, Integer>();
private ParseContext( JspDocument doc, String source, Counter counter )
{
@@ -706,16 +666,6 @@
return m_source.substring( startPos, endPos );
}
- public Node getParentNode()
- {
- return NODE_STACK.peek();
- }
-
- public Attribute getAttribute()
- {
- return m_attribute;
- }
-
public Counter getCounter()
{
return m_counter;
@@ -734,7 +684,7 @@
* @param stage the stage for which the marker position is desired
* @return the position of the marker.
*/
- public int getMarker( NodeLifecycle stage )
+ public int getMarkerForStage( Stage stage )
{
Integer mark = m_markers.get( stage );
return mark == null ? Node.POSITION_NOT_SET : mark.intValue();
@@ -748,22 +698,21 @@
/**
* Sets the active Parser without changing the stage or incrementing the
* position. Calling this method does <em>not</em> execute either the
- * {@link ParserDelegate#beginStage()} or
- * {@link ParserDelegate#endStage()} methods.
+ * {@link Parser#beginStage()} or {@link Parser#endStage()} methods.
*
* @param parser the parser to set
*/
- public void setParser( ParserDelegate parser )
+ public void setParser( Parser parser )
{
m_parser = parser;
}
public ParseContext getParentContext()
{
- return CONTEXT_STACK.peek();
+ return CONTEXT_STACK.size() == 0 ? null : CONTEXT_STACK.peek();
}
- public ParserDelegate getParser()
+ public Parser getParser()
{
return m_parser;
}
@@ -773,7 +722,7 @@
return m_source;
}
- public NodeLifecycle getStage()
+ public Stage getStage()
{
return m_stage;
}
@@ -803,26 +752,12 @@
}
/**
- * 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.
- */
- public void mark()
- {
- m_markers.put( getStage(), position() );
- }
-
- /**
* Pops the topmost ParseContext from the stack and replaces the
* JspParser's current ParseContext with it. Before popping the
- * ParseContext, the current stage's {@link ParserDelegate#endStage()}
- * method is executed.
+ * ParseContext, the current stage's {@link Parser#endStage()} method is
+ * executed.
*/
- public ParseContext pop()
+ public static ParseContext pop()
{
// Run the endStage method for the current stage
ParseContext ctx = ParseContext.currentContext();
@@ -833,11 +768,6 @@
return ctx;
}
- public void popNode()
- {
- NODE_STACK.pop();
- }
-
public int position()
{
return m_counter.position();
@@ -846,76 +776,98 @@
/**
* Pushes this ParseContext onto the stack and replaces the JspParser's
* current ParseContext with a new one. This method does <em>not</em>
- * call the current ParserDelegate's {@link ParserDelegate#endStage()}
- * method.
+ * call the current Parser's {@link Parser#endStage()} method.
*
* @return the new ParseContext
*/
- public ParseContext push()
+ public static ParseContext push()
{
- CONTEXT_STACK.push( this );
- ParseContext context = new ParseContext( m_doc, m_source, m_counter );
- CURRENT_CONTEXT = context;
+ ParseContext oldCtx = currentContext();
+ CONTEXT_STACK.push( oldCtx );
+ ParseContext ctx = new ParseContext( oldCtx.m_doc, oldCtx.m_source, oldCtx.m_counter );
+ CURRENT_CONTEXT = ctx;
// Set the default stage to TEXT
- context.setParser( TEXT_PARSER, NodeLifecycle.PARSING_TEXT );
-
- return context;
- }
-
- public void pushNode( Node node )
- {
- NODE_STACK.push( node );
+ Node text = new Text( ctx.m_doc );
+ ctx.setNode( text );
+ ctx.m_stage = Stage.TEXT;
+ ctx.m_parser = TEXT_PARSER;
+ return ctx;
}
/**
- * Sets the ParseContext's current attribute, and sets it start position
- * if not null.
+ * Sets the current Node to a supplied node. If the start position is
+ * not set, it set to the current position. If not already set, the
+ * parent is set to the parent ParseContext's node, or else the
+ * JspDocument's root node.
*
- * @param attribute
+ * @param node the node to set. If <code>null</code>, the current
+ * node is removed
*/
- public void setAttribute( Attribute attribute )
+ public void setNode( Node node )
{
- m_attribute = attribute;
- if( attribute != null )
+ m_node = node;
+ if( node == null )
{
- setStartPosition( attribute, position() );
+ return;
}
- }
- public void setNode( Node node )
- {
- m_node = node;
+ // If start not set, set it now
+ if( node.getStart() == Node.POSITION_NOT_SET )
+ {
+ setStartPosition( node, position() );
+ }
+
+ // Set the parent relationship
+ if( node.getParent() == null )
+ {
+ if( getParentContext() == null )
+ {
+ node.setParent( m_doc.getRoot() );
+ }
+ else
+ {
+ node.setParent( getParentContext().getNode() );
+ }
+ }
}
/**
- * Sets the current lifecycle stage, without resetting the current
- * parser.
+ * Sets the current lifecycle stage and mark its position, without
+ * resetting the current parser. The "marker" is set relative to the
+ * current position (as reported by {@link #position()}. The marker can
+ * be retrieved later via
+ * {@link #getMarkerForStage(com.ecyrd.jspwiki.ui.stripes.JspParser.Stage)}.
*
* @param stage
+ * @param increment the number of characters ahead of the current
+ * position to set the marker
*/
- public void setStage( NodeLifecycle stage )
+ public void setStage( Stage stage, int increment )
{
- // Set the new stage and set a marker at the current position
+ // Set the new stage.
m_stage = stage;
- mark();
+ m_markers.put( getStage(), position() + increment );
}
/**
* <p>
- * Ends the current {@link NodeLifecycle} and starts another, and sets a
- * marker for the current position. When this method is called, the
- * active {@link ParserDelegate} is finalized for the previous stage by
- * calling its {@link ParserDelegate#endStage()} method. Then, the
- * current text parser is replaced with the one that corresponds to the
- * correct one for the new stage, and a marker is set. Finally, the new
+ * Ends the current {@link Stage} and starts another, and sets a marker
+ * for the next character position. When this method is called, the
+ * active {@link Parser} is finalized for the previous stage by calling
+ * its {@link Parser#endStage()} method. Then, the current text parser
+ * is replaced with the one that corresponds to the correct one for the
+ * new stage, and a marker is set at the next position. Finally, the new
* stage is initialized by calling the new parser's
- * {@link ParserDelegate #beginStage()} method.
+ * {@link Parser #beginStage()} method.
* </p>
*
- * @param stage
+ * @param parser the parser to set
+ * @param stage the stage to set
+ * @increment the number of characters ahead to set the marker for the
+ * new stage. Must be zero or higher.
*/
- public void setParser( ParserDelegate parser, NodeLifecycle stage )
+ public void setParser( Parser parser, Stage stage, int increment )
{
// Finish the parser's current stage
if( parser != null && m_parser != null )
@@ -923,9 +875,9 @@
m_parser.endStage();
}
- // Set the new stage and set a marker at the current position
+ // Set the new stage and set a marker at the next position
m_stage = stage;
- mark();
+ m_markers.put( stage, position() + increment );
// Replace the parser and start it up
if( parser != null )
@@ -1002,7 +954,7 @@
char ch = isWhitespace ? ' ' : currentChar; // For case statements
// Handle the current character
- ParserDelegate parser = ctx.getParser();
+ Parser parser = ctx.getParser();
parser.handle( ch );
// Increment the character position
@@ -1015,11 +967,7 @@
node.setEnd( ctx.position() );
if( node.getType() == NodeType.TEXT )
{
- node.setValue( ctx.getSource().substring( node.getStart(), node.getEnd() ) );
- if( node.getEnd() > node.getStart() )
- {
- node.getParent().addChild( node );
- }
+ ctx.getParser().endStage();
}
return doc;
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspParserTest.java Sat Oct 4 20:44:22 2008
@@ -14,19 +14,141 @@
super( s );
}
- public void testCombinedTag() throws Exception
+ public void testNestedAttributes() throws Exception
{
- String s = "<foo />";
+ String s = "<a <b test=\"c\">selected=\"d\"</b> >Foo</a>";
// Parse the contents
JspParser parser = new JspParser();
JspDocument doc = parser.parse( s );
+ // Verify three nodes total
+ List<Node> nodes = doc.getNodes();
+ assertEquals( 3, nodes.size() );
+
+ // First node is a start tag
+ Node node;
+ node = nodes.get( 0 );
+ assertEquals( "a", node.getName() );
+ assertEquals( NodeType.HTML_START_TAG, node.getType() );
+ assertEquals( "<a <b test=\"c\">selected=\"d\"</b> >", node.toString() );
+
+ // Second node is a Text node
+ node = nodes.get( 1 );
+ assertEquals( NodeType.TEXT, node.getType() );
+ assertEquals( "Foo", node.getValue() );
+
+ // Third node is an end tag
+ node = nodes.get( 2 );
+ assertEquals( "a", node.getName() );
+ assertEquals( NodeType.HTML_END_TAG, node.getType() );
+
+ // First and third node are children of the root
+ assertEquals( 2, doc.getRoot().getChildren().size() );
+ assertEquals( NodeType.HTML_START_TAG, doc.getRoot().getChildren().get( 0 ).getType() );
+ assertEquals( NodeType.HTML_END_TAG, doc.getRoot().getChildren().get( 1 ).getType() );
+
+ // Test first node: should have 3 attributes (2 dynamic)
+ Tag tag = (Tag)nodes.get( 0 );
+ assertEquals( 3, tag.getAttributes().size() );
+ Attribute attribute;
+ attribute = tag.getAttributes().get( 0 );
+ assertEquals( null, attribute.getName() );
+ assertEquals( NodeType.DYNAMIC_ATTRIBUTE, attribute.getType() );
+ assertEquals( "<b test=\"c\">", attribute.getValue() );
+ assertEquals( "<b test=\"c\">", attribute.toString() );
+ attribute = tag.getAttributes().get( 1 );
+ assertEquals( "selected", attribute.getName() );
+ assertEquals( "d", attribute.getValue() );
+ assertEquals( "selected=\"d\"", attribute.toString() );
+ attribute = tag.getAttributes().get( 2 );
+ assertEquals( null, attribute.getName() );
+ assertEquals( NodeType.DYNAMIC_ATTRIBUTE, attribute.getType() );
+ assertEquals( "</b>", attribute.getValue() );
+ assertEquals( "</b>", attribute.toString() );
+ }
+
+ public void testAttributes() throws Exception
+ {
+ String s = "<a b=\"cd\"/>";
+
+ // Parse the contents
+ JspParser parser = new JspParser();
+ JspDocument doc = parser.parse( s );
+
// Results in one node
List<Node> nodes = doc.getNodes();
assertEquals( 1, nodes.size() );
Tag node;
+
+ // Verify HTML start tag
+ node = (Tag) nodes.get( 0 );
+ assertEquals( "a", node.getName() );
+ assertEquals( null, node.getValue() );
+ assertEquals( 0, node.getChildren().size() );
+ assertEquals( NodeType.HTML_COMBINED_TAG, node.getType() );
+ assertEquals( "<a b=\"cd\"/>", node.toString() );
+
+ // Verify attributes
+ assertEquals( 1, node.getAttributes().size() );
+ Attribute attribute = node.getAttribute( "b" );
+ assertEquals( "b", attribute.getName() );
+ assertEquals( "cd", attribute.getValue() );
+ assertEquals( 3, attribute.getStart() );
+ assertEquals( 9, attribute.getEnd() );
+ }
+
+ public void testCdata() throws Exception
+ {
+ String s = " <![CDATA[ foo ]]> ";
+
+ // Parse the contents
+ JspParser parser = new JspParser();
+ JspDocument doc = parser.parse( s );
+
+ // Results in 3 nodes
+ List<Node> nodes = doc.getNodes();
+ assertEquals( 3, nodes.size() );
+ Node node;
+
+ // Verify text tag (0)
+ node = nodes.get( 0 );
+ assertEquals( "(TEXT)", node.getName() );
+ assertEquals( " ", node.getValue() );
+ assertEquals( 0, node.getChildren().size() );
+ assertEquals( NodeType.TEXT, node.getType() );
+ assertEquals( " ", node.toString() );
+
+ // Verify CDATA tag (1)
+ node = nodes.get( 1 );
+ assertEquals( "(TEXT)", node.getName() );
+ assertEquals( " foo ", node.getValue() );
+ assertEquals( 0, node.getChildren().size() );
+ assertEquals( NodeType.CDATA, node.getType() );
+ assertEquals( "<![CDATA[ foo ]]>", node.toString() );
+ // Verify text tag (2)
+ node = nodes.get( 2 );
+ assertEquals( "(TEXT)", node.getName() );
+ assertEquals( " ", node.getValue() );
+ assertEquals( 0, node.getChildren().size() );
+ assertEquals( NodeType.TEXT, node.getType() );
+ assertEquals( " ", node.toString() );
+ }
+
+ public void testCombinedTag() throws Exception
+ {
+ String s = "<foo />";
+
+ // Parse the contents
+ JspParser parser = new JspParser();
+ JspDocument doc = parser.parse( s );
+
+ // Results in one node
+ List<Node> nodes = doc.getNodes();
+ assertEquals( 1, nodes.size() );
+ Tag node;
+
// Verify HTML combined tag
node = (Tag) nodes.get( 0 );
assertEquals( "foo", node.getName() );
@@ -47,15 +169,15 @@
// Results in one node
List<Node> nodes = doc.getNodes();
assertEquals( 1, nodes.size() );
- Markup node;
+ Text node;
// Verify comment
- node = (Markup) nodes.get( 0 );
- assertEquals( "(MARKUP)", node.getName() );
+ node = (Text) nodes.get( 0 );
+ assertEquals( "(TEXT)", node.getName() );
assertEquals( " This is a comment ", node.getValue() );
assertEquals( 0, node.getChildren().size() );
}
-
+
public void testParseDirective() throws Exception
{
String s = "<%@ page import=\"org.apache.log4j.*\" %>";
@@ -67,11 +189,11 @@
// Results in one node
List<Node> nodes = doc.getNodes();
assertEquals( 1, nodes.size() );
- JspDirective node;
+ Tag node;
Node attribute;
// Verify directive
- node = (JspDirective) nodes.get( 0 );
+ node = (Tag) nodes.get( 0 );
assertEquals( "page", node.getName() );
assertEquals( 1, node.getAttributes().size() );
attribute = node.getAttributes().get( 0 );
@@ -81,9 +203,8 @@
public void testParse() throws Exception
{
- JspMigrator m = new JspMigrator();
File src = new File( "src/webdocs/LoginForm.jsp" );
- String s = m.readSource( src );
+ String s = JspMigrator.readSource( src );
// Parse the contents of the file
JspParser parser = new JspParser();
@@ -106,11 +227,10 @@
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( 1, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "import", attribute.getName() );
assertEquals( "org.apache.log4j.*", attribute.getValue() );
i++;
@@ -122,7 +242,6 @@
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++;
@@ -136,11 +255,10 @@
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( 1, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "import", attribute.getName() );
assertEquals( "com.ecyrd.jspwiki.*", attribute.getValue() );
i++;
@@ -152,7 +270,6 @@
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++;
@@ -166,11 +283,10 @@
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( 1, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "import", attribute.getName() );
assertEquals( "com.ecyrd.jspwiki.action.*", attribute.getValue() );
i++;
@@ -182,7 +298,6 @@
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++;
@@ -196,11 +311,10 @@
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( 1, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "errorPage", attribute.getName() );
assertEquals( "/Error.jsp", attribute.getValue() );
i++;
@@ -212,7 +326,6 @@
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++;
@@ -226,14 +339,13 @@
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( 2, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "uri", attribute.getName() );
assertEquals( "/WEB-INF/jspwiki.tld", attribute.getValue() );
- attribute = ((JspDirective) node).getAttributes().get( 1 );
+ attribute = ((Tag) node).getAttributes().get( 1 );
assertEquals( "prefix", attribute.getName() );
assertEquals( "wiki", attribute.getValue() );
i++;
@@ -245,7 +357,6 @@
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++;
@@ -259,14 +370,13 @@
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( 2, ((Tag) node).getAttributes().size() );
+ attribute = ((Tag) node).getAttributes().get( 0 );
assertEquals( "uri", attribute.getName() );
assertEquals( "/WEB-INF/stripes.tld", attribute.getValue() );
- attribute = ((JspDirective) node).getAttributes().get( 1 );
+ attribute = ((Tag) node).getAttributes().get( 1 );
assertEquals( "prefix", attribute.getName() );
assertEquals( "stripes", attribute.getValue() );
i++;
@@ -278,7 +388,6 @@
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++;
@@ -292,7 +401,6 @@
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() );
@@ -315,7 +423,6 @@
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++;
@@ -328,9 +435,8 @@
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( "(MARKUP)", node.getName() );
+ assertEquals( "(TEXT)", node.getName() );
i++;
node = nodes.get( i );
assertEquals( 19, node.getLine() );
@@ -340,7 +446,6 @@
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++;
@@ -354,9 +459,8 @@
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( "(MARKUP)", node.getName() );
+ assertEquals( "(TEXT)", node.getName() );
i++;
// Test second tag on line 33 aka node 17
@@ -368,7 +472,6 @@
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() );
@@ -509,7 +612,6 @@
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() );
@@ -524,7 +626,6 @@
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() );
@@ -557,7 +658,6 @@
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() );
}
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Node.java Sat Oct 4 20:44:22 2008
@@ -62,15 +62,6 @@
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
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/NodeType.java Sat Oct 4 20:44:22 2008
@@ -8,9 +8,13 @@
/** Root node */
ROOT(null, null),
/** Attribute node */
- ATTRIBUTE(null,null),
+ ATTRIBUTE("",""),
+ /** Attribute node generated by an embedded JSP tag. */
+ DYNAMIC_ATTRIBUTE("<",">"),
/** Text node */
TEXT("", ""),
+ /** CDATA node. */
+ CDATA("<![CDATA[","]]>"),
/** HTML comment tag */
HTML_COMMENT("<!--", "-->"),
/** HTML start tag */
@@ -39,7 +43,7 @@
* JSP page, import or taglib directive, e.g., <%@ include... %>
* <%@ page... %> <%@ taglib... %>
*/
- JSP_DIRECTIVE("<%@", "%>");
+ JSP_DIRECTIVE("<%@ ", "%>");
private final String m_tagStart;
private final String m_tagEnd;
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java Sat Oct 4 20:44:22 2008
@@ -46,7 +46,7 @@
Node lastTaglib = null;
for ( Node node : nodes )
{
- JspDirective directive = (JspDirective)node;
+ Tag directive = (Tag)node;
if ( "taglib".equals( node.getName() ) )
{
lastTaglib = node;
@@ -62,7 +62,8 @@
{
Text linebreak = new Text( doc );
linebreak.setValue( System.getProperty( "line.separator" ) );
- JspDirective directive = new JspDirective( doc );
+ linebreak.setParent( doc.getRoot() );
+ Tag directive = new Tag( doc, NodeType.JSP_DIRECTIVE );
directive.setName( "taglib" );
Attribute attribute = new Attribute( doc );
attribute.setName( "uri" );
@@ -165,7 +166,7 @@
if( actionUrl != null )
{
int qmark = actionUrl.indexOf( '?' );
- if( qmark < actionUrl.length() - 1 )
+ if( qmark != -1 && qmark < actionUrl.length() - 1 )
{
// Change "action" attribute"
String trimmedPath = actionUrl.substring( 0, qmark );
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformerTest.java Sat Oct 4 20:44:22 2008
@@ -1,5 +1,6 @@
package com.ecyrd.jspwiki.ui.stripes;
+import java.io.File;
import java.util.HashMap;
import java.util.Map;
@@ -108,9 +109,9 @@
node = doc.getNodes().get( 0 );
assertEquals( NodeType.JSP_DIRECTIVE, node.getType() );
assertEquals( "taglib", node.getName() );
- attribute = ((JspDirective) node).getAttribute( "prefix" );
+ attribute = ((Tag) node).getAttribute( "prefix" );
assertEquals( "stripes", attribute.getValue() );
- attribute = ((JspDirective) node).getAttribute( "uri" );
+ attribute = ((Tag) node).getAttribute( "uri" );
assertEquals( "/WEB-INF/stripes.tld", attribute.getValue() );
// Verify linebreak
Modified: 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=701746&r1=701745&r2=701746&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/Tag.java Sat Oct 4 20:44:22 2008
@@ -69,43 +69,6 @@
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();
- }
-
/**
* Adds a child to the current Node. If the Node is of type
* {@link NodeType#HTML_COMBINED_TAG}, the tag will be split into two nodes
@@ -190,23 +153,43 @@
*/
public String toString()
{
+ // Root node is easy!
+ if ( m_type == NodeType.ROOT )
+ {
+ return "ROOT";
+ }
+
StringBuilder sb = new StringBuilder();
- sb.append( m_type.getTagStart() );
+
+ // Calculate start and end nodes
+ String tagStart= m_type.getTagStart();
+ String tagEnd = m_type.getTagEnd();
+ if ( tagStart == null ) tagStart = "?";
+ if ( tagEnd == null ) tagEnd = "?";
+
+ // Print tag start
+ sb.append( tagStart );
- // HTML nodes and JSP directives are formatted in mostly the same way.
+ // If Tag, print start/end plus attributes.
if( isHtmlNode() || m_type == NodeType.JSP_DIRECTIVE )
{
- if( m_type == NodeType.JSP_DIRECTIVE )
- {
- sb.append( ' ' );
- }
sb.append( m_name );
if( m_attributes.size() > 0 )
{
+ sb.append( ' ' );
+ NodeType lastType = null;
for( Attribute attr : m_attributes )
{
- sb.append( ' ' );
+ if ( attr.getType() == lastType )
+ {
+ sb.append( ' ' );
+ }
sb.append( attr.toString() );
+ lastType = attr.getType();
+ }
+ if ( lastType == NodeType.DYNAMIC_ATTRIBUTE )
+ {
+ sb.append( ' ' );
}
}
}
@@ -220,7 +203,8 @@
}
}
- sb.append( m_type.getTagEnd() );
+ // Print tag end
+ sb.append( tagEnd );
return sb.toString();
}