portals-portalapps-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rwat...@apache.org
Subject svn commit: r891414 - in /portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent: portlet/ rewriter/ rewriter/html/ rewriter/html/neko/ rewriter/xml/
Date Wed, 16 Dec 2009 20:19:03 GMT
Author: rwatler
Date: Wed Dec 16 20:19:02 2009
New Revision: 891414

URL: http://svn.apache.org/viewvc?rev=891414&view=rev
Log:
Jetspeed DynamicPage Support - WebContent Maintenance
-----------------------------------------------------------
- extended WebContentPortlet to support derived implementations with custom rewriters
- implemented locking on stateful WebContentPortlet rewriter to prevent unsafe parallel access
- extend rewriter protocols to support url rewriting of tag text


Modified:
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/portlet/WebContentPortlet.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractRewriter.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/BasicRewriter.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/Rewriter.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/RulesetRewriterImpl.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/SwingParserAdaptor.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/neko/CallbackElementRemover.java
    portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/xml/SaxParserAdaptor.java

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/portlet/WebContentPortlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/portlet/WebContentPortlet.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/portlet/WebContentPortlet.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/portlet/WebContentPortlet.java
Wed Dec 16 20:19:02 2009
@@ -36,6 +36,8 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
@@ -67,6 +69,7 @@
 import org.apache.portals.applications.webcontent.rewriter.xml.SaxParserAdaptor;
 import org.apache.portals.bridges.velocity.GenericVelocityPortlet;
 import org.apache.portals.messaging.PortletMessaging;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,7 +105,8 @@
     protected final static Logger log = LoggerFactory.getLogger(WebContentPortlet.class);
     public final static String defaultEncoding = "UTF-8";
 
-    // Data Members    
+    // Data Members
+    private Lock rewriterLock = new ReentrantLock();
     private RulesetRewriter rewriter = null;
     private RewriterController rewriteController = null;
 
@@ -181,7 +185,8 @@
                 }
             }             
             return ;   // proceed to doView() with adjusted history
-        }        
+        }
+        
         // Check if an action parameter was defined        
         String webContentURL = actionRequest.getParameter(WebContentRewriter.ACTION_PARAMETER_URL);
         String webContentMethod = actionRequest.getParameter(WebContentRewriter.ACTION_PARAMETER_METHOD);
@@ -247,38 +252,32 @@
             currentPage = new WebContentHistoryPage(sourceURL);
         }
 
-        // Initialize the controller if it's not already done
-        if (rewriteController == null)
+        byte[] content = null;
+        try
         {
-            PortletContext portletApplication = getPortletContext(); 
-            String path = portletApplication.getRealPath("/WEB-INF");
-            String contextPath = path + "/";
+            // initialize the controller if it's not already done
+            // and lock stateful rewriter
+            initializeRewriter();
+
+            // get content from current page
+            response.setContentType("text/html");
             try
             {
-                // Create rewriter adaptor
-                rewriteController = getController(contextPath);
+                content = doWebContent(currentPage.getUrl(), currentPage.getParams(), currentPage.isPost(),
request, response);
             }
-            catch (Exception e)
+            catch (Throwable t)
             {
-                response.getWriter().print("<p>WebContentPortlet failed to create rewriter
controller.</p>");
+                PrintWriter writer = response.getWriter();
+                writer.print("Error retrieveing web content:" + t.getMessage());
                 return;
             }
+            // System.out.println("Rewritten content is\n..."+new String(content));
         }
-
-        // get content from current page
-        response.setContentType("text/html");
-        byte[] content = null;
-        try
-        {
-            content = doWebContent(currentPage.getUrl(), currentPage.getParams(), currentPage.isPost(),
request, response);
-        }
-        catch (Throwable t)
+        finally
         {
-            PrintWriter writer = response.getWriter();
-            writer.print("Error retrieveing web content:" + t.getMessage());
-            return;
+            // unlock stateful rewriter
+            freeRewriter();
         }
-        // System.out.println("Rewritten content is\n..."+new String(content));
         
         // write the meta-control navigation header
         PrintWriter writer = response.getWriter();
@@ -317,8 +316,34 @@
     }
         
     /*
-     * Privaye helpers for generating WebContent
+     * Protected helpers for generating WebContent
      */
+
+    protected void initializeRewriter() throws PortletException
+    {
+        initializeRewriter(WebContentRewriter.class);
+    }
+
+    protected void initializeRewriter(Class rewriterClass) throws PortletException
+    {
+        rewriterLock.lock();
+        if (rewriteController == null)
+        {
+            PortletContext portletApplication = getPortletContext(); 
+            String path = portletApplication.getRealPath("/WEB-INF");
+            String contextPath = path + "/";
+            try
+            {
+                // Create rewriter adaptor
+                rewriteController = getController(contextPath, rewriterClass);
+            }
+            catch (Exception e)
+            {
+                throw new PortletException("WebContentPortlet failed to create rewriter controller:
"+e, e);
+            }
+        }
+    }
+    
     protected byte[] doWebContent(String sourceAttr, Map sourceParams, boolean isPost, RenderRequest
request, RenderResponse response)
         throws PortletException
     {
@@ -506,13 +531,10 @@
     /*
      * Generate a rewrite controller using the basic rules file
      */
-    private RewriterController getController(String contextPath) throws Exception
+    protected RewriterController getController(String contextPath, Class rewriterClass) throws
Exception
     {
-        Class[] rewriterClasses = new Class[]
-        { WebContentRewriter.class, WebContentRewriter.class};
-        
-        Class[] adaptorClasses = new Class[]
-        { NekoParserAdaptor.class, SaxParserAdaptor.class};
+        Class[] rewriterClasses = new Class[] { rewriterClass, rewriterClass};
+        Class[] adaptorClasses = new Class[] { NekoParserAdaptor.class, SaxParserAdaptor.class};
         RewriterController rwc = new MappingRewriterController(contextPath + "conf/rewriter-rules-mapping.xml",
Arrays
                 .asList(rewriterClasses), Arrays.asList(adaptorClasses));
 
@@ -523,6 +545,16 @@
         rewriter = rwc.createRewriter(ruleset);
         return rwc;
     }
+    
+    protected RulesetRewriter getRewriter()
+    {
+        return rewriter;
+    }
+    
+    protected void freeRewriter()
+    {
+        rewriterLock.unlock();
+    }
 
     protected HttpClient getHttpClient(RenderRequest request) throws IOException
     {
@@ -661,7 +693,7 @@
 
     static final int BLOCK_SIZE = 4096;
 
-    private void drain(Reader r, Writer w) throws IOException
+    protected void drain(Reader r, Writer w) throws IOException
     {
         char[] bytes = new char[BLOCK_SIZE];
         try
@@ -683,7 +715,7 @@
 
     }
 
-    private String getContentCharSet(InputStream is) throws IOException
+    protected String getContentCharSet(InputStream is) throws IOException
     {
         if (!is.markSupported())
         {

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractRewriter.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractRewriter.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractRewriter.java
Wed Dec 16 20:19:02 2009
@@ -123,4 +123,9 @@
     public void enterConvertTagEvent(String tag, MutableAttributes attrs)
     {
     }
+
+    public String enterConvertTextEvent(String tag, String text)
+    {
+        return null;
+    }
 }

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/BasicRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/BasicRewriter.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/BasicRewriter.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/BasicRewriter.java
Wed Dec 16 20:19:02 2009
@@ -38,6 +38,19 @@
         return getBaseRelativeUrl(url);
     }
     
+    /*    
+     * This callback is called by the ParserAdaptor implementation to write
+     * back all rewritten text to point to the proxy server.
+     * Given the original text, rewrites links as a link back to the proxy server.
+     *
+     * @return the rewritten text that points to the proxy server or null to leave unchanged.
+     *
+     */
+    public String rewriteText(String tag, String text)
+    {
+        return null;
+    }
+    
     public boolean shouldRemoveTag(String tag)
     {
         if (tag.equalsIgnoreCase("html"))

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/Rewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/Rewriter.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/Rewriter.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/Rewriter.java
Wed Dec 16 20:19:02 2009
@@ -66,6 +66,16 @@
      */
     String rewriteUrl(String url, String tag, String attribute);
 
+    /** 
+     * This event is the inteface between the Rewriter and ParserAdaptor for rewriting text.
+     * The ParserAdaptor calls back the Rewriter when it finds text that is a candidate to
be
+     * rewritten. The Rewriter rewrites the text and returns it as the result of this function.

+     * 
+     * @param tag The tag being processed
+     * @param text The current text being processsed
+     */
+    String rewriteText(String tag, String text);
+
     /**
      * Returns true if the tag should be removed, otherwise false.
      * Removing a tag only removes the tag but not the contents in 
@@ -207,4 +217,11 @@
      */
     void enterConvertTagEvent(String tag, MutableAttributes attrs);
     
+    /**
+     * Rewriter event called back for text conversion by the ParserAdaptor.
+     * 
+     * @param tag The name of the tag being processed.
+     * @param text the text to be converted.
+     */
+    String enterConvertTextEvent(String tag, String text);
 }

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/RulesetRewriterImpl.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/RulesetRewriterImpl.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/RulesetRewriterImpl.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/RulesetRewriterImpl.java
Wed Dec 16 20:19:02 2009
@@ -157,4 +157,9 @@
     {
         return getBaseRelativeUrl(url);
     }
+
+    public String enterConvertTextEvent(String tagid, String text)
+    {
+        return rewriteText(tagid, text);
+    }
 }

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/SwingParserAdaptor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/SwingParserAdaptor.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/SwingParserAdaptor.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/SwingParserAdaptor.java
Wed Dec 16 20:19:02 2009
@@ -20,6 +20,7 @@
 import java.io.Reader;
 import java.io.Writer;
 import java.util.Enumeration;
+import java.util.Stack;
 
 import javax.swing.text.MutableAttributeSet;
 import javax.swing.text.html.HTML;
@@ -130,6 +131,7 @@
         private boolean simpleTag = false;
         private String stripTag = null;
         private Writer writer = null;
+        private Stack tagStack = new Stack();
 
         private Callback (Writer writer) 
         {
@@ -160,6 +162,16 @@
                 return;
              }                    
 
+             if (!tagStack.isEmpty())
+             {
+                 String tag = (String)tagStack.peek();
+                 String convertedValues = convertText(tag, new String(values));
+                 if (convertedValues != null)
+                 {
+                     values = convertedValues.toCharArray();
+                 }
+             }
+
             addToResult(values);
         }
 
@@ -241,6 +253,7 @@
         public void handleStartTag(HTML.Tag htmlTag,  MutableAttributeSet attrs, int position)

         {
             String tag = htmlTag.toString();
+            tagStack.push(tag);
             
             if (false == rewriter.enterStartTagEvent(tag, new SwingAttributes(attrs)))
             {
@@ -293,6 +306,10 @@
         public void handleEndTag(HTML.Tag htmlTag, int position) 
         {
             String tag = htmlTag.toString();
+            if (!tagStack.isEmpty() && tag.equals(tagStack.peek()))
+            {
+                tagStack.pop();
+            }
             if (false == rewriter.enterEndTagEvent(tag.toString()))
             {
                 return;
@@ -538,7 +555,19 @@
               */
         }
 
+        /*
+         * Determines which HTML Tag/Element is being inspected, and calls the 
+         * appropriate converter for that context.  This method contains all the
+         * logic for determining how text is rewritten. 
+         *
+         * @param tag TAG from the Callback-Interface.
+         * @param text The text for the current HTML element.
+         */
 
+        private String convertText(String tag, String text) 
+        {
+            return rewriter.enterConvertTextEvent(tag.toString(), text);
+        }
     }
     
 }

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/neko/CallbackElementRemover.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/neko/CallbackElementRemover.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/neko/CallbackElementRemover.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/html/neko/CallbackElementRemover.java
Wed Dec 16 20:19:02 2009
@@ -16,6 +16,8 @@
  */
 package org.apache.portals.applications.webcontent.rewriter.html.neko;
 
+import java.util.Stack;
+
 import org.apache.portals.applications.webcontent.rewriter.Rewriter;
 import org.apache.xerces.xni.Augmentations;
 import org.apache.xerces.xni.QName;
@@ -41,6 +43,7 @@
 {
 
     private Rewriter rewriter;
+    private Stack tagStack = new Stack();
 
     /**
      * Construct with reference to the rewriter context to consult for rewriting advice
@@ -48,7 +51,6 @@
     public CallbackElementRemover( Rewriter rewriter )
     {
         super();
-        
         this.rewriter = rewriter;
     }
     
@@ -57,6 +59,26 @@
     
     /**
      * <p>
+     * characters
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#characters(org.apache.xerces.xni.XMLString
text, org.apache.xerces.xni.Augmentations augs)
+     * @param text
+     * @param augs
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void characters(XMLString text,Augmentations augs) throws XNIException
+    {
+        if (!tagStack.isEmpty())
+        {
+            String tag = (String)tagStack.peek();
+            processText(tag, text);
+        }
+        super.characters(text, augs);
+    }
+
+    /**
+     * <p>
      * comment
      * </p>
      * 
@@ -87,7 +109,8 @@
      */
     public void emptyElement( QName element, XMLAttributes attrs, Augmentations arg2 ) throws
XNIException
     {
-        processTag(element,attrs) ;
+        String tag = element.rawname.toLowerCase();
+        processTag(tag,attrs) ;
         super.emptyElement(element, attrs, arg2);
     }
 
@@ -106,10 +129,32 @@
      */
     public void startElement( QName element, XMLAttributes attrs, Augmentations arg2 ) throws
XNIException
     {
-        processTag(element,attrs);
+        String tag = element.rawname.toLowerCase();
+        tagStack.push(tag);
+        processTag(tag,attrs);
         super.startElement(element, attrs, arg2);
     }
     
+    /**
+     * <p>
+     * endElement
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#endElement(org.apache.xerces.xni.QName,
+     *      org.apache.xerces.xni.Augmentations)
+     * @param element
+     * @param arg1
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void endElement( QName element, Augmentations arg1 ) throws XNIException
+    {
+        String tag = element.rawname.toLowerCase();
+        if (!tagStack.isEmpty() && tag.equals(tagStack.peek()))
+        {
+            tagStack.pop();
+        }
+        super.endElement(element, arg1);
+    }
     
     // Support Methods
 
@@ -119,13 +164,13 @@
      * </p>
      * 
      * @param tag
+     * @param attrs
      */
-    protected void processTag(QName element, XMLAttributes attrs)
+    protected void processTag(String tag, XMLAttributes attrs)
     {
-        String tag = element.rawname.toLowerCase();
         if (fRemovedElements.contains(tag))
         {
-            // alread removed
+            // already removed
             return ;
         }
         else if (rewriter.shouldStripTag(tag))
@@ -137,7 +182,7 @@
         }
         else if (rewriter.shouldRemoveTag(tag))
         {
-            // BOZO - block intentially left EMPTY
+            // BOZO - block intentionally left EMPTY
             
             // first time for this tag...
             // remove - no directive necessary, the default behavior of ElementRemover is
to drop tags that it does not know about (but the assocated text will remain)
@@ -160,4 +205,22 @@
         }
         return names ;
     }
+
+    /**
+     * <p>
+     * processText
+     * </p>
+     * 
+     * @param tag
+     * @param text
+     */
+    protected void processText(String tag, XMLString text)
+    {
+        String convertedText = rewriter.enterConvertTextEvent(tag, new String(text.ch, text.offset,
text.length));
+        if (convertedText != null)
+        {
+            char [] convertedTextChars = convertedText.toCharArray();
+            text.setValues(convertedTextChars, 0, convertedTextChars.length);
+        }
+    }
 }

Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/xml/SaxParserAdaptor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/xml/SaxParserAdaptor.java?rev=891414&r1=891413&r2=891414&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/xml/SaxParserAdaptor.java
(original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/xml/SaxParserAdaptor.java
Wed Dec 16 20:19:02 2009
@@ -24,6 +24,7 @@
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Stack;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
@@ -106,6 +107,7 @@
         private int elementCount = 0;
         private boolean emit = true;
         private Writer writer = null;
+        private Stack tagStack = new Stack();
 
         public SaxFormatHandler(Writer writer)
         {
@@ -128,7 +130,17 @@
                 return;                                      
 
             if (false == rewriter.enterText(values, start))
-               return;                    
+               return;
+
+            if (!tagStack.isEmpty())
+            {
+                String tag = (String)tagStack.peek();
+                String convertedValues = convertText(tag, new String(values, start, length));
+                if (convertedValues != null)
+                {
+                    values = convertedValues.toCharArray();
+                }
+            }
 
             if (writer != null)
             {
@@ -149,6 +161,7 @@
 //            System.out.println("localName = " + localName);
 //            System.out.println("uri = " + uri);
             String tag = qName;
+            tagStack.push(tag);
             
             if (false == rewriter.enterStartTagEvent(tag.toString(), attributes))
                 return;
@@ -173,6 +186,10 @@
             throws SAXException
         {
             String tag = qName;
+            if (!tagStack.isEmpty() && tag.equals(tagStack.peek()))
+            {
+                tagStack.pop();
+            }
             elementCount++;
             if (false == rewriter.enterEndTagEvent(tag.toString()))
                 return;
@@ -257,6 +274,20 @@
             rewriter.enterConvertTagEvent(tag.toString(), attrs);
         }
              
+        /*
+         * Determines which HTML Tag/Element is being inspected, and calls the 
+         * appropriate converter for that context.  This method contains all the
+         * logic for determining how text is rewritten. 
+         *
+         * @param tag TAG from the Callback-Interface.
+         * @param text The text for the current HTML element.
+         */
+
+        private String convertText(String tag, String text) 
+        {
+            return rewriter.enterConvertTextEvent(tag.toString(), text);
+        }
+             
         public InputSource resolveEntity (String publicId, String systemId)
         {
             



Mime
View raw message