portals-portalapps-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From woon...@apache.org
Subject svn commit: r1643554 - in /portals/applications/webcontent/trunk: ./ content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/ c...
Date Sat, 06 Dec 2014 16:42:12 GMT
Author: woonsan
Date: Sat Dec  6 16:42:12 2014
New Revision: 1643554

URL: http://svn.apache.org/r1643554
Log:
APA-67: javadocs in content-rewriter module

Modified:
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ContentRewritingContext.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Sink.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Source.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/DefaultSerializerFactory.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/HtmlCleanerContentRewriter.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/SerializerFactory.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/AbstractTextLineContentRewriter.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/SimpleContentRewritingContext.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSink.java
    portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSource.java
    portals/applications/webcontent/trunk/pom.xml
    portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ContentRewritingContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ContentRewritingContext.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ContentRewritingContext.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/ContentRewritingContext.java Sat Dec  6 16:42:12 2014
@@ -19,7 +19,8 @@ package org.apache.portals.applications.
 import java.util.Map;
 
 /**
- * Content Rewriting Context which can be used to shared context variables.
+ * Content Rewriting Context which can be used to share context variables
+ * during the content rewriting process.
  */
 public interface ContentRewritingContext
 {

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Sink.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Sink.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Sink.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Sink.java Sat Dec  6 16:42:12 2014
@@ -26,8 +26,7 @@ import java.io.Writer;
 public interface Sink
 {
     /**
-     * Returns an {@link OutputStream} suitable for writing binary data. 
-     * Either this method or {@link #getWriter} may be called to write the body, not both.
+     * Returns an {@link OutputStream} suitable for writing binary data.
      * 
      * @return
      * @throws IOException

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Source.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Source.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Source.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/Source.java Sat Dec  6 16:42:12 2014
@@ -26,8 +26,7 @@ import java.io.Reader;
 public interface Source
 {
     /**
-     * Retrieves the content as binary data using a {@link InputStream}. 
-     * Either this method or {@link #getReader} may be called to read the body, not both.
+     * Retrieves the content as binary data using a {@link InputStream}.
      * 
      * @return
      * @throws IOException
@@ -36,7 +35,6 @@ public interface Source
 
     /**
      * Retrieves the content as character data using a <code>Reader</code>. 
-     * Either this method or {@link #getReader} may be called to read the body, not both.
      * 
      * @return
      * @throws IOException

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java Sat Dec  6 16:42:12 2014
@@ -19,20 +19,47 @@ package org.apache.portals.applications.
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.htmlcleaner.CommentNode;
 import org.htmlcleaner.HtmlNode;
 import org.htmlcleaner.TagNode;
 import org.htmlcleaner.TagNodeVisitor;
 
+/**
+ * A generic abstract {@link TagNodeVisitor} class
+ * which can be extended simply by implementing the link rewriting method only
+ * ({@link #rewriteURI(String, String, String)}).
+ * <p>
+ * This abstract class is provided to help developers implement {@link TagNodeVisitor}s
+ * more easily with a simple link rewriting capability which is very common in
+ * reverse proxy modules.
+ * </p>
+ * <p>
+ * This class is constructed with a map constructor argument, <code>Map&lt;String,String[]&gt; tagNameAndLinkAttrs</code>,
+ * which should contain entries of tag name and link attribute names array of the tag.
+ * For example, an HTML &lt;a /&gt; tag typically may contain an <code>href</code> attribute for
+ * the link information. e.g, &lt;a href="http://portals.apache.org">Apache Portals&lt;/a&gt;.
+ * If you want to rewrite the link string contained in the <code>href</code> attribute of the
+ * &lt;a /&gt; tag, then the map constructor argument should contain a key-value pair entry (the tag name
+ * : link attribute names array):  { "a" :  [ "href" ] }.
+ * Then this class will invoke {@link #rewriteURI(String, String, String)} for each link attribute
+ * whenever it visits a &lt;a /&gt; tag.
+ * </p>
+ */
 public abstract class AbstractProxyTagNodeVisitor implements TagNodeVisitor
 {
 
-    private Map<String, String> tagNameAndLinkAttrs;
+    private Map<String, String[]> tagNameAndLinkAttrs;
 
-    public AbstractProxyTagNodeVisitor(Map<String, String> tagNameAndLinkAttrs)
+    /**
+     * Construct a AbstractProxyTagNodeVisitor from the map of
+     * the link element tag name (e.g, "a" or "img") and its link attributes (e.g, [ "href" ] or [ "src" ]).
+     * @param tagNameAndLinkAttrs
+     */
+    public AbstractProxyTagNodeVisitor(Map<String, String[]> tagNameAndLinkAttrs)
     {
-        this.tagNameAndLinkAttrs = new HashMap<String, String>();
+        this.tagNameAndLinkAttrs = new HashMap<String, String[]>();
 
         if (tagNameAndLinkAttrs != null)
         {
@@ -40,6 +67,15 @@ public abstract class AbstractProxyTagNo
         }
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This method checks the type of the current <code>htmlNode</code>
+     * and it invokes {@link #visitTagNode(TagNode, TagNode)} if the current <code>htmlNode</code>
+     * is instance of {@link TagNode}, or invokes {@link #visitCommentNode(TagNode, CommentNode)}
+     * if the current <code>htmlNode</code> is instance of {@link CommentNode}.
+     * </p>
+     */
     public boolean visit(TagNode parentNode, HtmlNode htmlNode)
     {
         if (htmlNode instanceof TagNode)
@@ -54,36 +90,75 @@ public abstract class AbstractProxyTagNo
         return true;
     }
 
+    /**
+     * Default implementation of handling visited <code>TagNode</code>s.
+     * <p>
+     * This method checks if the tag name was registered to be handled to rewrite the link attributes.
+     * If it is registered through the constructor, then it retrieves the attribute names array by the
+     * tag name. For each attribute, it invokes {@link #rewriteURI(String, String, String)} method
+     * to translate the link URI.
+     * If {@link #rewriteURI(String, String, String)} returns a different string than the original
+     * link URI string, then it updates the link attributes by the newly rewritten link URI string.
+     * </p>
+     * @param parentNode
+     * @param tag
+     * @return
+     */
     protected boolean visitTagNode(TagNode parentNode, TagNode tag)
     {
         String tagName = tag.getName();
-        String linkAttrName = tagNameAndLinkAttrs.get(tagName);
+        String[] linkAttrNames = tagNameAndLinkAttrs.get(tagName);
 
-        if (StringUtils.isEmpty(linkAttrName))
+        if (ArrayUtils.isEmpty(linkAttrNames))
         {
             return true;
         }
 
-        String link = tag.getAttributeByName(linkAttrName);
+        String link;
+        String rewrittenLink;
 
-        if (StringUtils.isNotEmpty(link))
+        for (String linkAttrName : linkAttrNames)
         {
-            String rewritten = rewriteURI(tagName, linkAttrName, link);
-
-            if (!StringUtils.equals(link, rewritten))
+            if (StringUtils.isNotEmpty(linkAttrName))
             {
-                tag.addAttribute(linkAttrName, rewritten);
+                link = tag.getAttributeByName(linkAttrName);
+
+                if (StringUtils.isNotEmpty(link))
+                {
+                    rewrittenLink = rewriteURI(tagName, linkAttrName, link);
+
+                    if (!StringUtils.equals(link, rewrittenLink))
+                    {
+                        tag.addAttribute(linkAttrName, rewrittenLink);
+                    }
+                }
             }
         }
 
         return true;
     }
 
+    /**
+     * Default implementation of handling visited <code>CommentNode</code>s.
+     * <p>
+     * This does nothing but simply returns true by default.
+     * </p>
+     * @param parentNode
+     * @param comment
+     * @return
+     */
     protected boolean visitCommentNode(TagNode parentNode, CommentNode comment)
     {
         return true;
     }
 
+    /**
+     * The method which should rewrite the original link URI string to a new link URI to return if necessary.
+     * @param tagName the tag name holding the link
+     * @param attrName the attribute name of the tag node holding the link
+     * @param uri the original link URI string
+     * @return newly rewritten link URI string if necessary, or the original link URI string if rewriting is unnecessary.
+     */
     protected abstract String rewriteURI(String tagName, String attrName, String uri);
 
 }

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java Sat Dec  6 16:42:12 2014
@@ -22,15 +22,35 @@ import java.util.List;
 import org.htmlcleaner.TagNode;
 import org.htmlcleaner.conditional.ITagNodeCondition;
 
+/**
+ * Simple AND node condition checker implementation for HtmlCleaner based content rewriting process.
+ * This class is for combining existing {@link ITagNodeCondition} checkers and for checking if
+ * all the {@link ITagNodeCondition} checker instances return true.
+ * <p>
+ * This class can basically be given multiple {@link ITagNodeCondition} checker instances.
+ * This class iterates the multiple {@link ITagNodeCondition} checker instances
+ * and invokes {@link ITagNodeCondition#satisfy(TagNode)} on each.
+ * If and only if every call on {@link ITagNodeCondition#satisfy(TagNode)} returns true,
+ * then the {@link #satisfy(TagNode)} method of this class returns true.
+ * Otherwise, it will return false.
+ * </p>
+ */
 public class AndTagNodeCondition implements ITagNodeCondition
 {
 
     private List<ITagNodeCondition> conditionsList;
 
+    /**
+     * Zero-argument default constructor.
+     */
     public AndTagNodeCondition()
     {
     }
 
+    /**
+     * Adds a {@link ITagNodeCondition} checker instance.
+     * @param condition
+     */
     public void addTagNodeCondition(ITagNodeCondition condition)
     {
         if (conditionsList == null)
@@ -41,6 +61,19 @@ public class AndTagNodeCondition impleme
         conditionsList.add(condition);
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This method iterates the multiple {@link ITagNodeCondition} checker instances
+     * and invokes {@link ITagNodeCondition#satisfy(TagNode)} on each.
+     * If and only if every call on {@link ITagNodeCondition#satisfy(TagNode)} returns true,
+     * then the {@link #satisfy(TagNode)} method of this class returns true.
+     * Otherwise, it will return false.
+     * </p>
+     * <p>
+     * Also, if there is no {@link ITagNodeCondition} checker instances, then it returns false.
+     * </p>
+     */
     public boolean satisfy(TagNode tagNode)
     {
         if (conditionsList == null || conditionsList.isEmpty())

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/DefaultSerializerFactory.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/DefaultSerializerFactory.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/DefaultSerializerFactory.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/DefaultSerializerFactory.java Sat Dec  6 16:42:12 2014
@@ -20,35 +20,72 @@ import org.apache.commons.beanutils.Cons
 import org.htmlcleaner.HtmlCleaner;
 import org.htmlcleaner.Serializer;
 
+/**
+ * Default generic implementation of {@link SerializerFactory}.
+ * <p>
+ * A bean of this class should be injected with the physical HtmlCleaner
+ * {@link Serializer} class and object argument array.
+ * Then this will find and invoke the constructor of the specified class
+ * with the specified object argument array to create a {@link Serializer} instance.
+ * </p>
+ */
 public class DefaultSerializerFactory implements SerializerFactory
 {
     private Class<? extends Serializer> serializerClass;
     private Object[] arguments;
 
+    /**
+     * Zero-argument default constructor.
+     */
     public DefaultSerializerFactory()
     {
     }
 
+    /**
+     * Returns the class of the physical HtmlCleaner {@link Serializer}
+     * such as {@link org.htmlcleaner.SimpleHtmlSerializer}.
+     * @return
+     */
     public Class<? extends Serializer> getSerializerClass()
     {
         return serializerClass;
     }
 
+    /**
+     * Sets the class of the physical HtmlCleaner {@link Serializer}
+     * such as {@link org.htmlcleaner.SimpleHtmlSerializer}.
+     * @param serializerClass
+     */
     public void setSerializerClass(Class<? extends Serializer> serializerClass)
     {
         this.serializerClass = serializerClass;
     }
 
+    /**
+     * Returns the object argument array to be used when invoking the constructor
+     * of the physical {@link Serializer} class.
+     * @return
+     */
     public Object[] getArguments()
     {
         return arguments;
     }
 
+    /**
+     * Sets the object argument array to be used when invoking the constructor
+     * of the physical {@link Serializer} class.
+     * @param arguments
+     */
     public void setArguments(Object[] arguments)
     {
         this.arguments = arguments;
     }
 
+    /**
+     * Creates a {@link Serializer} instance by finding and invoking the constructor
+     * of the injected HtmlCleaner {@link Serializer} class with the given
+     * object argument array.
+     */
     public Serializer createSerializer(HtmlCleaner cleaner) throws Exception
     {
         if (arguments == null)

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/HtmlCleanerContentRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/HtmlCleanerContentRewriter.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/HtmlCleanerContentRewriter.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/HtmlCleanerContentRewriter.java Sat Dec  6 16:42:12 2014
@@ -38,11 +38,15 @@ import org.apache.portals.applications.w
 import org.htmlcleaner.CleanerTransformations;
 import org.htmlcleaner.HtmlCleaner;
 import org.htmlcleaner.Serializer;
+import org.htmlcleaner.SimpleHtmlSerializer;
 import org.htmlcleaner.TagNode;
 import org.htmlcleaner.TagNodeVisitor;
 import org.htmlcleaner.XPather;
 import org.htmlcleaner.XPatherException;
 
+/**
+ * HtmlCleaner based content rewriter implementation.
+ */
 public class HtmlCleanerContentRewriter implements ContentRewriter
 {
 
@@ -54,60 +58,243 @@ public class HtmlCleanerContentRewriter
     private String [] transformationInfos;
     private List<TagNodeVisitor> tagNodeVisitors;
 
+    /**
+     * Zero-argument default constructor.
+     */
     public HtmlCleanerContentRewriter()
     {
     }
 
+    /**
+     * Returns {@link SerializerFactory} instance.
+     * <p>
+     * If no {@link SerializerFactory} was set in prior,
+     * then it creates and returns a new instance of {@link DefaultSerializerFactory}
+     * with using {@link SimpleHtmlSerializer} by default.
+     * </p>
+     * @return
+     */
     public SerializerFactory getSerializerFactory()
     {
-        return serializerFactory;
+        if (serializerFactory != null) {
+            return serializerFactory;
+        }
+
+        DefaultSerializerFactory defaultSerializerFactory = new DefaultSerializerFactory();
+        defaultSerializerFactory.setSerializerClass(SimpleHtmlSerializer.class);
+        return defaultSerializerFactory;
     }
 
+    /**
+     * Sets {@link SerializerFactory} property.
+     * @param serializerFactory
+     */
     public void setSerializerFactory(SerializerFactory serializerFactory)
     {
         this.serializerFactory = serializerFactory;
     }
 
+    /**
+     * Returns the character encoding to be used to write to <code>sink</code>.
+     * The default return value is 'UTF-8' if not set.
+     * @return
+     */
     public String getSinkEncoding()
     {
         return sinkEncoding;
     }
 
+    /**
+     * Sets the character encoding to be used to write to <code>sink</code>.
+     * @param sinkEncoding
+     */
     public void setSinkEncoding(String sinkEncoding)
     {
         this.sinkEncoding = sinkEncoding;
     }
 
+    /**
+     * Returns the XPath expression to be used to select some filtered tag node(s) only.
+     * @return
+     */
     public String getXpathExpression()
     {
         return xpathExpression;
     }
 
+    /**
+     * Sets the XPath expression to be used to select some filtered tag node(s) only.
+     * @param xpathExpression
+     */
     public void setXpathExpression(String xpathExpression)
     {
         this.xpathExpression = xpathExpression;
     }
 
+    /**
+     * Returns the flag whether or not the output should include the inner HTML(s) only.
+     * The default value is false, meaning the outer HTML(s) will be written to <code>sink</code>.
+     * @return
+     */
     public boolean isInnerHtmlOnly()
     {
         return innerHtmlOnly;
     }
 
+    /**
+     * Sets the flag whether or not the output should include the inner HTML(s) only.
+     * If the value is false, it means the outer HTML(s) will be written to <code>sink</code>.
+     * @param innerHtmlOnly
+     */
     public void setInnerHtmlOnly(boolean innerHtmlOnly)
     {
         this.innerHtmlOnly = innerHtmlOnly;
     }
 
+    /**
+     * Returns {@link CleanerTransformations} of the underlying <code>HtmlCleaner</code> properties.
+     * @return
+     */
     public CleanerTransformations getCleanerTransformations()
     {
         return getHtmlCleaner().getProperties().getCleanerTransformations();
     }
 
+    /**
+     * Sets {@link CleanerTransformations} of the underlying <code>HtmlCleaner</code> properties.
+     * @param cleanerTransformations
+     */
     public void setCleanerTransformations(CleanerTransformations cleanerTransformations)
     {
         getHtmlCleaner().getProperties().setCleanerTransformations(cleanerTransformations);
     }
 
+    /**
+     * Returns an array of parsing transformation string.
+     * <p>
+     * Since HtmlCleaner 2.1, it introduces a way to quickly skip specified tags and/or attributes or to transform
+     * them to some other tags/attributes during parsing process, avoiding expansive document object model manipulation
+     * after cleaning.
+     * </p>
+     * <p>
+     * Here are example transformation rules applied in the cleaning process:
+     * </p>
+     * <table border="1">
+     *   <tr>
+     *     <th>Example rule</th>
+     *     <th>Explanation</th>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       cfouput
+     *     </td>
+     *     <td>
+     *       <code>cfouput</code> tag will be ignored by parser (but not content inside)
+     *     </td>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       c:block->div,false
+     *     </td>
+     *     <td>
+     *       <code>c:block</code> tag will be transformed to <code>div</code> tag and
+     *       all original attributes will be ignored (false in tranformation description).
+     *     </td>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       font->span,true
+     *     </td>
+     *     <td>
+     *       <code>font</code> tag will be transformed to <code>span</code> and
+     *       original attributes will be preserved.
+     *     </td>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       font.size
+     *     </td>
+     *     <td>
+     *       <code>font</code> tag will still be transformed to <code>span</code> and
+     *       original attributes will be preserved thanks to the preceding rule added above,
+     *       except of the specified <code>size</code> attribute.
+     *       The <code>size</code> attribute will be removed.
+     *     </td>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       font.face
+     *     </td>
+     *     <td>
+     *       <code>font</code> tag will still be transformed to <code>span</code> and
+     *       original attributes will be preserved thanks to the preceding rule added above,
+     *       except of the specified <code>face</code> attribute.
+     *       The <code>face</code> attribute will be removed.
+     *     </td>
+     *   </tr>
+     *   <tr>
+     *     <td>
+     *       font.style=${style};font-family=${face};font-size=${size};
+     *     </td>
+     *     <td>
+     *       <code>font</code> tag will still be transformed to <code>span</code> and
+     *       original attributes will be preserved thanks to the preceding rule added above.
+     *       <br>
+     *       And attribute <code>style</code> has more complex transformation rule:
+     *       it will be translated to value given by the template <code>${style};font-family=${face};font-size=${size};</code>.
+     *       <br>
+     *       So, the <code>style</code> attribute of the original <code>font</code> tag will be prepended to
+     *       the <code>style</code> attribute of the new <code>span</code> tag.
+     *       <br>
+     *       The <code>face</code> attribute of the original <code>font</code> tag will be appended to
+     *       <code>style</code> attribute of the new <code>span</code> tag as <code>font-family</code> property.
+     *       <br>
+     *       The <code>size</code> attribute of the original <code>font</code> tag will be appended to
+     *       <code>style</code> attribute of the new <code>span</code> tag as <code>font-size</code> property.
+     *       <br>
+     *       Template is evaluated against source tag attributes (names between ${ and }).
+     *     </td>
+     *   </tr>
+     * </table>
+     * <p>
+     * Suppose you have example HTML markups like the following:
+     * </p>
+     * <pre>
+     * ...My content 1...
+     * &lt;cfoutput&gt;
+     *   Yin and yang describe the polar effects of phenomena.
+     * &lt;/cfoutput&gt;
+     * ...My content 2...
+     * &lt;c:block parent=b1 count=331&gt;
+     *   Yin-yang are Mutually Rooted
+     * &lt;/c:block&gt;
+     * ...My content 3...
+     * &lt;font id=f21 size=12 face=Arial style="color:red"&gt;
+     *   The Yin and yang aspects are in dynamic equilibrium
+     * &lt;/font&gt;
+     * ...My content 4...
+     * </pre>
+     * <p>
+     * Based on the example transformation rules shown above,
+     * it will be transformed like this:
+     * </p>
+     * <pre>
+     * ...My content 1...
+     * Yin and yang describe the polar effects of phenomena.
+     * ...My content 2...
+     * &lt;div&gt;
+     *   Yin-yang are Mutually Rooted
+     * &lt;/div&gt;
+     * ...My content 3...
+     * &lt;span id="f21" style="color:red;font-family=Arial;font-size=12;"&gt;
+     *   The Yin and yang aspects are in dynamic equilibrium
+     * &lt;/span&gt;
+     * ...My content 4...
+     * </pre>
+     * 
+     * @return
+     * @see <a href="http://htmlcleaner.sourceforge.net/parameters.php">HtmlCleaner Setting Behavior</a>
+     */
     public String [] getCleanerTransformationStringArray()
     {
         if (transformationInfos == null)
@@ -120,6 +307,11 @@ public class HtmlCleanerContentRewriter
         return transInfos;
     }
 
+    /**
+     * Sets an array of parsing transformation string.
+     * See {@link #getCleanerTransformationStringArray()} for details.
+     * @param transInfos
+     */
     public void setCleanerTransformationStringArray(final String [] transInfos)
     {
         if (transInfos == null)
@@ -145,6 +337,11 @@ public class HtmlCleanerContentRewriter
         setCleanerTransformations(new CleanerTransformations(transInfosMap));
     }
 
+    /**
+     * Returns custom {@link TagNodeVisitor}s which can get the chance to do custom processing on
+     * the selected tag nodes.
+     * @return
+     */
     public List<TagNodeVisitor> getTagNodeVisitors()
     {
         if (tagNodeVisitors == null)
@@ -155,6 +352,10 @@ public class HtmlCleanerContentRewriter
         return Collections.unmodifiableList(tagNodeVisitors);
     }
 
+    /**
+     * Sets custom {@link TagNodeVisitor}s which can get the chance to do custom processing on
+     * the selected tag nodes.
+     */
     public void setTagNodeVisitors(List<TagNodeVisitor> tagNodeVisitors)
     {
         this.tagNodeVisitors = new ArrayList<TagNodeVisitor>();
@@ -165,6 +366,10 @@ public class HtmlCleanerContentRewriter
         }
     }
 
+    /**
+     * Adds a custom {@link TagNodeVisitor} which can get the chance to do custom processing on
+     * the selected tag nodes.
+     */
     public void addTagNodeVisitor(TagNodeVisitor tagNodeVisitor)
     {
         if (tagNodeVisitors == null)
@@ -175,6 +380,9 @@ public class HtmlCleanerContentRewriter
         tagNodeVisitors.add(tagNodeVisitor);
     }
 
+    /**
+     * Removes the specified custom {@link TagNodeVisitor}.
+     */
     public void removeTagNodeVisitor(TagNodeVisitor tagNodeVisitor)
     {
         if (tagNodeVisitors != null)
@@ -183,6 +391,9 @@ public class HtmlCleanerContentRewriter
         }
     }
 
+    /**
+     * Removes all the custom {@link TagNodeVisitor}s.
+     */
     public void removeAllTagNodeVisitors()
     {
         if (tagNodeVisitors != null)
@@ -191,13 +402,35 @@ public class HtmlCleanerContentRewriter
         }
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This method basically gets a {@link java.io.Reader} from the <code>source</code>
+     * and cleans it with an <code>HtmlCleaner</code> retrieved from a {@link #getHtmlCleaner()} call.
+     * </p>
+     * <p>
+     * And, it checks if there's an XPath expression configuration by calling on {@link #getXpathExpression()}.
+     * If there's an XPath expression configuration, then it selects only the element(s) filtered by the XPath expression property.
+     * Otherwise, it selects the root tag node by default.
+     * </p>
+     * <p>
+     * Afterward, it checks if there's any <code>TagNodeVisitor</code> set by calling on {@link #getTagNodeVisitors()}.
+     * If there's any <code>TagNodeVisitor</code>s, then it invokes {@link TagNodeVisitor#visit(TagNode, org.htmlcleaner.HtmlNode)}
+     * to give custom <code>TagNodeVisitor</code>s chances to do some custom tag node handling
+     * on either filtered tag node(s) or the root tag node if no XPath expression configured.
+     * </p>
+     * <p>
+     * Finally, it serializes the selected tag node(s) to the <code>sink</code>
+     * by internally creating a {@link org.htmlcleaner.Serializer} based on other properties configuration.
+     * </p>
+     */
     public void rewrite(Source source, Sink sink, ContentRewritingContext context) throws ContentRewritingException, IOException
     {
         Serializer serializer = null;
 
         try
         {
-            serializer = serializerFactory.createSerializer(getHtmlCleaner());
+            serializer = getSerializerFactory().createSerializer(getHtmlCleaner());
         } 
         catch (Exception e) 
         {
@@ -295,6 +528,11 @@ public class HtmlCleanerContentRewriter
         }
     }
 
+    /**
+     * Returns the underlying <code>HtmlCleaner</code> instance.
+     * If it was not initiated yet, it creates one by invoking {@link #createHtmlCleaner()}.
+     * @return
+     */
     protected HtmlCleaner getHtmlCleaner()
     {
         if (cleaner == null)
@@ -305,6 +543,15 @@ public class HtmlCleanerContentRewriter
         return cleaner;
     }
 
+    /**
+     * Creates a <code>HtmlCleaner</code> instance.
+     * By default, it sets the following properties to the <code>HtmlCleaner</code>:
+     * <ul>
+     *   <li>omitXmlDeclaration : true</li>
+     *   <li>omitDoctypeDeclaration : true</li>
+     * </ul>
+     * @return
+     */
     protected HtmlCleaner createHtmlCleaner()
     {
         HtmlCleaner htmlCleaner = new HtmlCleaner();

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/SerializerFactory.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/SerializerFactory.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/SerializerFactory.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/SerializerFactory.java Sat Dec  6 16:42:12 2014
@@ -19,7 +19,26 @@ package org.apache.portals.applications.
 import org.htmlcleaner.HtmlCleaner;
 import org.htmlcleaner.Serializer;
 
+/**
+ * Factory interface responsible for creating HtmlCleaner {@link Serializer}.
+ * <p>
+ * {@link HtmlCleanerContentRewriter} requires an instance of this factory type
+ * to create a physical HtmlCleaner {@link Serializer} instance.
+ * </p>
+ */
 public interface SerializerFactory
 {
+    /**
+     * Creates a {@link Serializer} instance for the given HtmlCleaner instance.
+     * <p>
+     * <em>Note: </em>
+     * Implementations can read properties of the given HtmlCleaner instance
+     * to set configurations of the newly created {@link Serializer} instance
+     * like {@link org.apache.portals.applications.webcontent2.rewriter.htmlcleaner.DefaultSerializerFactory} does.
+     * </p>
+     * @param cleaner
+     * @return
+     * @throws Exception
+     */
     public Serializer createSerializer(HtmlCleaner cleaner) throws Exception;
 }

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/AbstractTextLineContentRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/AbstractTextLineContentRewriter.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/AbstractTextLineContentRewriter.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/AbstractTextLineContentRewriter.java Sat Dec  6 16:42:12 2014
@@ -31,11 +31,23 @@ import org.apache.portals.applications.w
 import org.apache.portals.applications.webcontent2.rewriter.Source;
 
 /**
- * AbstractTextLineContentRewriter
+ * Abstract text line based content rewriter base implementation.
  */
 public abstract class AbstractTextLineContentRewriter implements ContentRewriter
 {
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This method basically gets a {@link java.io.Reader} from the <code>source</code>
+     * and reads each text line from the reader. And it invokes {@link #rewriteLine(String, ContentRewritingContext)} method
+     * to translate the line and write the translated line to the writer retrieved from the <code>sink</code>.
+     * </p>
+     * <p>
+     * If both <code>source</code> and <code>sink<code> are all text-based, and if it is possible to translate line by line,
+     * then you can simply create a derived class from this class with implementing {@link #rewriteLine(String, ContentRewritingContext)} method.
+     * </p>
+     */
     public void rewrite(Source source, Sink sink, ContentRewritingContext context) throws ContentRewritingException, IOException
     {
         Reader reader = null;
@@ -68,6 +80,35 @@ public abstract class AbstractTextLineCo
         }
     }
 
+    /**
+     * Translates the given <code>line</code> and returns the translated string.
+     * <p>
+     * For example, suppose the <code>source</code> contains the following lines:
+     * <pre>
+     * ${message.greeting}
+     * Copyright ${copyright.holder} ${copyright.years}
+     * </pre>
+     * </p>
+     * <p>
+     * Then, one implementation of this method might want to return "Hello, World!" for the first text line,
+     * and "Copyright Apache Software Foundation 2014" for instance to let the <code>sink</code> have the following:
+     * <pre>
+     * Hello, World!
+     * Copyright Apache Software Foundation 2014
+     * </pre>
+     * </p>
+     * <p>
+     * Even better, for example, if the given <code>context</code> contains all those variables (i.e, ${copyright.holder} and ${copyright.years}),
+     * then the implementation of this method can resolve those variables dynamically and translates them based on the variables given
+     * by the runtime.
+     * </p>
+     * 
+     * @param line a text line from the <code>source</code>
+     * @param context the content rewriting context given by the runtime
+     * @return a translated line
+     * @throws ContentRewritingException
+     * @throws IOException
+     */
     protected abstract String rewriteLine(String line, ContentRewritingContext context) throws ContentRewritingException, IOException;
 
 }

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/SimpleContentRewritingContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/SimpleContentRewritingContext.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/SimpleContentRewritingContext.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/SimpleContentRewritingContext.java Sat Dec  6 16:42:12 2014
@@ -22,11 +22,17 @@ import java.util.concurrent.ConcurrentHa
 
 import org.apache.portals.applications.webcontent2.rewriter.ContentRewritingContext;
 
+/**
+ * Trivial <code>ContentRewritingContext</code> implementation.
+ */
 public class SimpleContentRewritingContext implements ContentRewritingContext
 {
 
     private Map<String, Object> attributes;
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean hasAttribute(String name)
     {
         if (attributes == null) 
@@ -37,6 +43,9 @@ public class SimpleContentRewritingConte
         return attributes.containsKey(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Object getAttribute(String name)
     {
         if (attributes == null) 
@@ -47,6 +56,9 @@ public class SimpleContentRewritingConte
         return attributes.get(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Map<String, Object> getAttributesMap()
     {
         if (attributes == null) 
@@ -57,6 +69,9 @@ public class SimpleContentRewritingConte
         return Collections.unmodifiableMap(attributes);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setAttribute(String name, Object value)
     {
         if (attributes == null) 
@@ -67,6 +82,9 @@ public class SimpleContentRewritingConte
         attributes.put(name, value);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void removeAttribute(String name)
     {
         if (attributes != null) 

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSink.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSink.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSink.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSink.java Sat Dec  6 16:42:12 2014
@@ -25,6 +25,9 @@ import java.io.Writer;
 
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
 
+/**
+ * Acts as an holder for a content rewriting Sink in the form of byte or character stream.
+ */
 public class StreamSink implements Sink
 {
 
@@ -32,11 +35,22 @@ public class StreamSink implements Sink
     private String encoding;
     private Writer writer;
 
+    /**
+     * Construct a StreamSink for a byte stream.
+     * @param output
+     */
     public StreamSink(OutputStream output)
     {
         this(output, null);
     }
 
+    /**
+     * Construct a StreamSink for a byte stream with the specified <code>encoding</code>.
+     * The <code>encoding</code> is used when {@link #getWriter()} is invoked to create a
+     * writer from the underlying byte stream.
+     * @param output
+     * @param encoding
+     */
     public StreamSink(OutputStream output, String encoding)
     {
         if (output == null)
@@ -48,6 +62,10 @@ public class StreamSink implements Sink
         this.encoding = encoding;
     }
 
+    /**
+     * Construct a StreamSink for a character stream.
+     * @param writer
+     */
     public StreamSink(Writer writer)
     {
         if (writer == null)
@@ -58,6 +76,12 @@ public class StreamSink implements Sink
         this.writer = writer;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Either this method or {@link #getWriter} may be called to write the body, not both.
+     * </p>
+     */
     public OutputStream getOutputStream() throws IOException
     {
         if (writer != null)
@@ -68,6 +92,12 @@ public class StreamSink implements Sink
         return output;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Either this method or {@link #getOutputStream} may be called to write the body, not both.
+     * </p>
+     */
     public Writer getWriter() throws IOException
     {
         if (output != null)

Modified: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSource.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSource.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSource.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/impl/StreamSource.java Sat Dec  6 16:42:12 2014
@@ -25,6 +25,13 @@ import java.io.Reader;
 
 import org.apache.portals.applications.webcontent2.rewriter.Source;
 
+/**
+ * Acts as an holder for a content rewriting Source in the form of a byte or character stream.
+ * <p>
+ * <em>Note:</em> Due to their internal use of either a Reader or InputStream instance,
+ * <code>StreamSource</code> instances may only be used once.
+ * </p>
+ */
 public class StreamSource implements Source
 {
 
@@ -32,11 +39,22 @@ public class StreamSource implements Sou
     private String encoding;
     private Reader reader;
 
+    /**
+     * Construct a StreamSource from a byte stream.
+     * @param input
+     */
     public StreamSource(InputStream input)
     {
         this(input, null);
     }
 
+    /**
+     * Construct a StreamSource from a byte stream with the specified <code>encoding</code>.
+     * The <code>encoding</code> is used when {@link #getReader()} is invoked to create a
+     * reader from the underlying byte stream.
+     * @param input
+     * @param encoding
+     */
     public StreamSource(InputStream input, String encoding)
     {
         if (input == null)
@@ -48,6 +66,10 @@ public class StreamSource implements Sou
         this.encoding = encoding;
     }
 
+    /**
+     * Construct a StreamSource from a character reader.
+     * @param reader
+     */
     public StreamSource(Reader reader)
     {
         if (reader == null)
@@ -58,6 +80,12 @@ public class StreamSource implements Sou
         this.reader = reader;
     }
 
+    /**
+     * {@inheritDoc}
+     * <P>
+     * Either this method or {@link #getReader} may be called to read the body, not both.
+     * </P>
+     */
     public InputStream getInputStream() throws IOException
     {
         if (reader != null)
@@ -68,6 +96,12 @@ public class StreamSource implements Sou
         return input;
     }
 
+    /**
+     * {@inheritDoc}
+     * <P>
+     * Either this method or {@link #getInputStream} may be called to read the body, not both.
+     * </P>
+     */
     public Reader getReader() throws IOException
     {
         if (input != null)

Modified: portals/applications/webcontent/trunk/pom.xml
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/pom.xml?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/pom.xml (original)
+++ portals/applications/webcontent/trunk/pom.xml Sat Dec  6 16:42:12 2014
@@ -312,6 +312,23 @@
         <version>2.10.1</version>
         <configuration>
           <aggregate>true</aggregate>
+          <groups>
+            <group>
+              <title>Apache Portals Application Web Content 2 - Content Rewriter Module</title>
+              <packages>org.apache.portals.applications.webcontent2.rewriter*</packages>
+            </group>
+            <group>
+              <title>Apache Portals Application Web Content 2 - Reverse Proxy Module</title>
+              <packages>org.apache.portals.applications.webcontent2.proxy*</packages>
+            </group>
+            <group>
+              <title>Apache Portals Application Web Content 2 - Portlets Module</title>
+              <packages>org.apache.portals.applications.webcontent2.portlet*</packages>
+            </group>
+          </groups>
+          <links>
+            <link>http://htmlcleaner.sourceforge.net/doc/</link>
+          </links>
         </configuration>
         <executions>
           <execution>

Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java?rev=1643554&r1=1643553&r2=1643554&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java Sat Dec  6 16:42:12 2014
@@ -36,13 +36,13 @@ public class DefaultPortletProxyTagNodeV
 
     private static Logger log = LoggerFactory.getLogger(DefaultPortletProxyTagNodeVisitor.class);
 
-    private static final Map<String, String> DEFAULT_TAG_NAME_AND_LINK_ATTRS = new HashMap<String, String>();
+    private static final Map<String, String[]> DEFAULT_TAG_NAME_AND_LINK_ATTRS = new HashMap<String, String[]>();
 
     static
     {
-        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("a", "href");
-        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("img", "src");
-        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("form", "action");
+        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("a", new String[] { "href" });
+        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("img", new String[] { "src" });
+        DEFAULT_TAG_NAME_AND_LINK_ATTRS.put("form", new String[] { "action" });
     }
 
     public DefaultPortletProxyTagNodeVisitor()
@@ -50,7 +50,7 @@ public class DefaultPortletProxyTagNodeV
         this(DEFAULT_TAG_NAME_AND_LINK_ATTRS);
     }
 
-    public DefaultPortletProxyTagNodeVisitor(Map<String, String> tagNameAndLinkAttrs)
+    public DefaultPortletProxyTagNodeVisitor(Map<String, String[]> tagNameAndLinkAttrs)
     {
         super(tagNameAndLinkAttrs);
     }



Mime
View raw message