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/11/30 16:59:27 UTC

svn commit: r721834 - /incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/

Author: ajaquith
Date: Sun Nov 30 07:59:27 2008
New Revision: 721834

URL: http://svn.apache.org/viewvc?rev=721834&view=rev
Log:
Added feature to JSPWikiJspTransformer to look for WikiEngine.createContext() statements and prepend the correct <stripes:useActionBean> tag.

Modified:
    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/JspDocument.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/JspTransformer.java
    incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/StripesJspTransformer.java

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=721834&r1=721833&r2=721834&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 Sun Nov 30 07:59:27 2008
@@ -12,6 +12,19 @@
         super(doc, NodeType.ATTRIBUTE);
     }
 
+    /**
+     * Convenience method that creates an attribute with a name and string value.
+     * @param doc the JspDocument the Attribute is a child of
+     * @param name the Attribute's name
+     * @param value the Attribute's value
+     */
+    public Attribute( JspDocument doc, String name, String value )
+    {
+        super(doc, NodeType.ATTRIBUTE);
+        setName( name );
+        setValue( value );
+    }
+
     public char getAttributeDelimiter()
     {
         return m_quote;

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=721834&r1=721833&r2=721834&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 Sun Nov 30 07:59:27 2008
@@ -1,18 +1,31 @@
 package com.ecyrd.jspwiki.ui.stripes;
 
-import java.util.List;
-import java.util.Map;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import net.sourceforge.stripes.action.ActionBean;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.action.HandlerInfo;
+import com.ecyrd.jspwiki.action.WikiActionBean;
 
 /**
  * Transforms a JspDocument from standard JSP markup to Stripes markup.
  */
 public class JSPWikiJspTransformer extends AbstractJspTransformer
 {
+    private static final Pattern CONTEXT_PATTERN = Pattern.compile( "\\.createContext\\(.*?WikiContext.([A-Z]*?)\\s*\\);" );
+
+    private Map<String,HandlerInfo> m_contextMap = new HashMap<String,HandlerInfo>();
+
     /**
      * {@inheritDoc}
      */
-    public void initialize( Map<String, Object> sharedState )
+    public void initialize( Set<Class<? extends ActionBean>> beanClasses, Map<String, Object> sharedState )
     {
+        m_contextMap = cacheRequestContexts( beanClasses );
         System.out.println( "Initialized JSPWikiJspTransformer." );
     }
 
@@ -69,7 +82,63 @@
                              "Consider using <stripes:errors> tags instead of <wiki:Messages> for displaying validation errors." );
                 }
             }
+
+            // Look for WikiEngine.createContext() statements, and add matching <stripes:useActionBean> tag
+            else if ( node.getType() == NodeType.JSP_DECLARATION || node.getType() == NodeType.SCRIPTLET )
+            {
+                String scriptlet = node.getValue();
+                Matcher m = CONTEXT_PATTERN.matcher( scriptlet );
+                if (m.find()) {
+                    String context = m.group(1).trim();     // EDIT, COMMENT etc.
+                    HandlerInfo handler = m_contextMap.get( context );
+                    if ( handler != null )
+                    {
+                        // Add the <stripes:useActionBean> tag
+                        addUseActionBeanTag( doc, handler.getActionBeanClass(), handler.getEventName() );
+                        
+                        // Now add the Stripes taglib declaration
+                        if ( StripesJspTransformer.addStripesTaglib( doc ) )
+                        {
+                            message( doc.getRoot(), "Added Stripes taglib directive." );
+                        }
+                    }
+                }
+                
+            }
+        }
+    }
+
+    private void addUseActionBeanTag( JspDocument doc, Class<? extends ActionBean> beanClass, String event )
+    {
+        // Create Tag
+        Tag tag = new Tag( doc, NodeType.EMPTY_ELEMENT_TAG );
+        tag.setName( "stripes:useActionBean" );
+        tag.addAttribute( new Attribute( doc, "beanClass", beanClass.getName() ) );
+        if ( event != null )
+        {
+            tag.addAttribute( new Attribute( doc, "event", event ) );
+        }
+        
+        // Create linebreak
+        Text linebreak = new Text( doc );
+        linebreak.setValue( System.getProperty( "line.separator" ) );
+        Node root = doc.getRoot();
+        linebreak.setParent( root );
+        
+        // Figure out where to put it
+        List<Node> directives = doc.getNodes( NodeType.JSP_DIRECTIVE );
+        if ( directives.size() == 0 )
+        {
+            root.addChild( linebreak, 0 );
+            root.addChild( tag, 0 );
+        }
+        else
+        {
+            Node lastDirective = directives.get( directives.size() - 1 );
+            lastDirective.addSibling( tag );
+            lastDirective.addSibling( linebreak );
         }
+        message( doc.getRoot(), "Added <stripes:useActionBean beanClass=\"" + beanClass.getName() + "\" event=\"" + event + "\" />" );
     }
 
     /**
@@ -115,4 +184,50 @@
         }
     }
 
+    /**
+     * Using introspection, creates a cached Map of with request context field names as keys, and ActionBean classes as values.
+     */
+    @SuppressWarnings("unchecked")
+    private Map<String,HandlerInfo> cacheRequestContexts( Set<Class<? extends ActionBean>> beanClasses )
+    {
+        // Create a map with of all String constant; key: constant value, value: constant name
+        // e.g., "login", "LOGIN"
+        Map<String,String> fields = new HashMap<String,String>(); 
+        for ( Field field : WikiContext.class.getDeclaredFields() )
+        {
+            if ( String.class.equals( field.getType() ) )
+            {
+                String fieldName = field.getName();
+                String fieldValue = null;
+                try
+                {
+                    fieldValue = (String)field.get( null );
+                    fields.put( fieldValue, fieldName );
+                }
+                catch( Exception e )
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+        
+        // Match WikiRequestContext annotations with WikiContext field values
+        Map<String,HandlerInfo> contextMap = new HashMap<String,HandlerInfo>();
+        for ( Class<? extends ActionBean> beanClass : beanClasses )
+        {
+            Collection<HandlerInfo> handlers = HandlerInfo.getHandlerInfoCollection( (Class<? extends WikiActionBean>)beanClass ).values();
+            
+            for ( HandlerInfo handler : handlers )
+            {
+                String eventName = handler.getRequestContext();
+                String fieldName = fields.get( eventName );
+                if ( fieldName != null )
+                {
+                    contextMap.put( fieldName, handler );
+                }
+            }
+        }
+        return contextMap;
+    }
+
 }

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=721834&r1=721833&r2=721834&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 Sun Nov 30 07:59:27 2008
@@ -1,7 +1,10 @@
 package com.ecyrd.jspwiki.ui.stripes;
 
+import java.security.ProtectionDomain;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -14,6 +17,11 @@
     protected JspTransformer m_transformer = new JSPWikiJspTransformer();
     protected JspDocument m_doc = new JspDocument();
     
+    public void setUp()
+    {
+        m_transformer.initialize( JspMigrator.findBeanClasses(), m_sharedState );
+    }
+
     public JSPWikiJspTransformerTest( String s )
     {
         super( s );
@@ -72,6 +80,29 @@
         assertEquals( "form", node.getName() );
     }
     
+    public void testUseActionBean()
+    {
+        String s = "<% engine.createContext( request, WikiContext.EDIT ); %>";
+        JspDocument doc = new JspParser().parse( s );
+
+        // Should be 1 node: scriptlet
+        assertEquals( 1, doc.getNodes().size() );
+        Node node = doc.getNodes().get( 0 );
+        assertEquals( NodeType.SCRIPTLET, node.getType() );
+
+        // Run the transformer
+        m_transformer.transform( m_sharedState, doc );
+
+        // Should be 5 nodes: Stripes taglib + <useActionBean> tag + scriptlet + 2 whitespace nodes
+        assertEquals( 5, doc.getNodes().size() );
+        Tag tag = (Tag)doc.getNodes().get( 2 );
+        assertEquals( "stripes:useActionBean", tag.getName() );
+        assertEquals( "beanClass", tag.getAttributes().get( 0 ).getName() );
+        assertEquals( "com.ecyrd.jspwiki.action.EditActionBean", tag.getAttributes().get( 0 ).getValue() );
+        assertEquals( "event", tag.getAttributes().get( 1 ).getName() );
+        assertEquals( "edit", tag.getAttributes().get( 1 ).getValue() );
+    }
+    
     public static Test suite()
     {
         return new TestSuite( JSPWikiJspTransformerTest.class );

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocument.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocument.java?rev=721834&r1=721833&r2=721834&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocument.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspDocument.java Sun Nov 30 07:59:27 2008
@@ -58,14 +58,8 @@
         // Create new directive
         Tag directive = new Tag( this, NodeType.JSP_DIRECTIVE );
         directive.setName( "taglib" );
-        Attribute attribute = new Attribute( this );
-        attribute.setName( "uri" );
-        attribute.setValue( "/WEB-INF/stripes.tld" );
-        directive.addAttribute( attribute );
-        attribute = new Attribute( this );
-        attribute.setName( "prefix" );
-        attribute.setValue( "stripes" );
-        directive.addAttribute( attribute );
+        directive.addAttribute( new Attribute( this, "uri", uri ) );
+        directive.addAttribute( new Attribute( this, "prefix", prefix ) );
         
         // Create linebreak
         Text linebreak = new Text( this );

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=721834&r1=721833&r2=721834&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 Sun Nov 30 07:59:27 2008
@@ -6,6 +6,11 @@
 import java.io.IOException;
 import java.util.*;
 
+import net.sourceforge.stripes.action.ActionBean;
+import net.sourceforge.stripes.util.ResolverUtil;
+
+import com.ecyrd.jspwiki.action.WikiContextFactory;
+
 public class JspMigrator
 {
 
@@ -102,6 +107,7 @@
         JspMigrator migrator = new JspMigrator();
         migrator.addTransformer( new StripesJspTransformer() );
         migrator.addTransformer( new JSPWikiJspTransformer() );
+        migrator.initialize( new HashMap<String,Object>() );
         try
         {
             migrator.migrate( src, dest );
@@ -142,23 +148,50 @@
     }
 
     /**
-     * Migrates the contents of an entire directory from one location to
-     * another.
-     * 
-     * @param sourceDir the source directory
-     * @param destDir the destination directory
+     * Initializes the JspMigrator with a shared-state Map containing key/value pairs. Each
+     * {@link JspTransformer} added to the transformer via {@link #addTransformer(JspTransformer)}
+     * is initialized in sequence by calling its respective {@link JspTransformer#initialize(Map)}
+     * method. Each JspTransformer is passed a Set of discovered {@link net.sourceforge.stripes.action.ActionBean}
+     * classes, plus the shared-state Map.
+     * @param sharedState the shared-state Map passed to all JspTransformers at time of initialization
      */
-    public void migrate( File sourceDir, File destDir ) throws IOException
+    public void initialize( Map<String, Object> sharedState )
     {
-        // Clear the shared state
-        m_sharedState.clear();
+        m_sharedState = sharedState;
         
         // Initialize the transformers
         for ( JspTransformer transformer: m_transformers )
         {
-            transformer.initialize( m_sharedState );
+            transformer.initialize( findBeanClasses(), m_sharedState );
         }
+    }
+
+    /**
+     * Returns the ActionBean implementations found on the classpath.
+     * @return
+     */
+    protected static Set<Class<? extends ActionBean>> findBeanClasses()
+    {
+        // Find all ActionBean implementations on the classpath
+        String beanPackagesProp = System.getProperty( WikiContextFactory.PROPS_ACTIONBEAN_PACKAGES,
+                                                      WikiContextFactory.DEFAULT_ACTIONBEAN_PACKAGES ).trim();
+        String[] beanPackages = beanPackagesProp.split( "," );
+        ResolverUtil<ActionBean> resolver = new ResolverUtil<ActionBean>();
+        resolver.findImplementations( ActionBean.class, beanPackages );
+        Set<Class<? extends ActionBean>> beanClasses = resolver.getClasses();
+        
+        return beanClasses;
+    }
 
+    /**
+     * Migrates the contents of an entire directory from one location to
+     * another.
+     * 
+     * @param sourceDir the source directory
+     * @param destDir the destination directory
+     */
+    public void migrate( File sourceDir, File destDir ) throws IOException
+    {
         // Find the files we need to migrate
         String sourcePath = sourceDir.getPath();
         List<File> allFiles = Collections.unmodifiableList( getFiles( sourceDir, ".jsp" ) );

Modified: incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java?rev=721834&r1=721833&r2=721834&view=diff
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java (original)
+++ incubator/jspwiki/branches/JSPWIKI_2_9_STRIPES_BRANCH/tests/com/ecyrd/jspwiki/ui/stripes/JspTransformer.java Sun Nov 30 07:59:27 2008
@@ -1,6 +1,9 @@
 package com.ecyrd.jspwiki.ui.stripes;
 
 import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.stripes.action.ActionBean;
 
 /**
  * Strategy interface for transforming JSPs.
@@ -10,12 +13,12 @@
     /**
      * Initializes the transformer. This method should be called only once, when
      * the transformer is initialized.
-     * 
-     * @param sharedState a map containing key/value pairs that represent any
+     * @param beanClasses the Set of ActionBean classes discovered by
+     * @param sharedState a Map containing key/value pairs that represent any
      *            shared-state information that this method might need during
      *            transformation.
      */
-    public void initialize( Map<String, Object> sharedState );
+    public void initialize( Set<Class<? extends ActionBean>> beanClasses, Map<String, Object> sharedState );
 
     /**
      * Executes the transformation on the JSP and returns the result. This

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=721834&r1=721833&r2=721834&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 Sun Nov 30 07:59:27 2008
@@ -8,9 +8,6 @@
 
 import net.sourceforge.stripes.action.ActionBean;
 import net.sourceforge.stripes.action.UrlBinding;
-import net.sourceforge.stripes.util.ResolverUtil;
-
-import com.ecyrd.jspwiki.action.WikiContextFactory;
 
 /**
  * Transforms a JspDocument from standard JSP markup to Stripes markup.
@@ -24,16 +21,8 @@
     /**
      * {@inheritDoc}
      */
-    public void initialize( Map<String, Object> sharedState )
+    public void initialize( Set<Class<? extends ActionBean>> beanClasses, Map<String, Object> sharedState )
     {
-        // Find all ActionBean implementations on the classpath
-        String beanPackagesProp = System.getProperty( WikiContextFactory.PROPS_ACTIONBEAN_PACKAGES,
-                                                      WikiContextFactory.DEFAULT_ACTIONBEAN_PACKAGES ).trim();
-        String[] beanPackages = beanPackagesProp.split( "," );
-        ResolverUtil<ActionBean> resolver = new ResolverUtil<ActionBean>();
-        resolver.findImplementations( ActionBean.class, beanPackages );
-        Set<Class<? extends ActionBean>> beanClasses = resolver.getClasses();
-
         // Fetch the URL bindings
         initUrlBindingCache( beanClasses );
 
@@ -43,6 +32,11 @@
         System.out.println( "Initialized StripesJspTransformer." );
     }
 
+    /**
+     * Using introspection, creates a Map of key/value pairs where the key is an {@link net.sourceforge.stripes.action.UrlBinding} annotation
+     * value, and the corresponding value is the {@link net.sourceforge.stripes.action.ActionBean} classes it annotates.
+     * @param beanClasses the set of ActionBean classes to inspect
+     */
     private void initUrlBindingCache( Set<Class<? extends ActionBean>> beanClasses )
     {
         for( Class<? extends ActionBean> beanClass : beanClasses )
@@ -55,6 +49,11 @@
         }
     }
 
+    /**
+     * Using introspection, creates a Map of key/value pairs where the key is an ActionBean class, and its corresponding
+     * value is a Set of property names the bean has (as Strings).
+     * @param beanClasses the set of ActionBean classes to inspect
+     */
     private void initActionBeanPropertyCache( Set<Class<? extends ActionBean>> beanClasses )
     {
         for( Class<? extends ActionBean> beanClass : beanClasses )
@@ -144,7 +143,10 @@
         // If we did any work here, add Stripes taglib entry
         if( migrated )
         {
-            addStripesTaglib( doc );
+            if ( addStripesTaglib( doc ) )
+            {
+                message( doc.getRoot(), "Added Stripes taglib directive." );
+            }
         }
     }
 
@@ -158,16 +160,19 @@
      * <code>/WEB-INF/stripes.tld</code>.
      * 
      * @param doc the JspDocument to process
+     * @return <code>true</code> if the Stripes taglib declaration was
+     * actually added, <code>false</code> if it already exists
      */
-    private void addStripesTaglib( JspDocument doc )
+    static protected boolean addStripesTaglib( JspDocument doc )
     {
         // Add the Stripes taglib declaration if it's not there already
         List<Tag> nodes = doc.getTaglibDirective( "*", "stripes" );
         if( nodes.size() == 0 )
         {
             doc.addTaglibDirective( "/WEB-INF/stripes.tld", "stripes" );
-            message( doc.getRoot(), "Added Stripes taglib directive." );
+            return true;
         }
+        return true;
     }
 
     /**