You are viewing a plain text version of this content. The canonical link for it is here.
Posted to portalapps-dev@portals.apache.org by wo...@apache.org on 2014/12/17 15:00:09 UTC

svn commit: r1646246 - 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/impl/ portlets/sr...

Author: woonsan
Date: Wed Dec 17 14:00:09 2014
New Revision: 1646246

URL: http://svn.apache.org/r1646246
Log:
APA-67: javadocs in reverse-proxy impl package

Modified:
    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/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/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/ProxyMapping.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/RequestContext.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyCommand.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyMapping.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultProxyMappingRegistry.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultReverseProxyService.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultURICleaner.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/GzippedSource.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpEntitySource.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpServletResponseSink.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyProcessingChain.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/RegexProxyMapping.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/SimpleProxyMapping.java
    portals/applications/webcontent/trunk/reverse-proxy/src/test/java/org/apache/portals/applications/webcontent2/proxy/ProxyCommandChainTest.java

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=1646246&r1=1646245&r2=1646246&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 Wed Dec 17 14:00:09 2014
@@ -34,7 +34,7 @@ public interface Source
     public InputStream getInputStream() throws IOException;
 
     /**
-     * Retrieves the content as character data using a <code>Reader</code>. 
+     * Retrieves the content as character data using a {@link Reader}. 
      * 
      * @return
      * @throws IOException

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=1646246&r1=1646245&r2=1646246&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 Wed Dec 17 14:00:09 2014
@@ -26,13 +26,25 @@ 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.
+ * Acts as an holder for a content rewriting {@link Sink} in the form of byte or character stream.
  */
 public class StreamSink implements Sink
 {
 
+    /**
+     * Underlying {@link java.io.OutputStream} of this sink.
+     */
     private OutputStream output;
+
+    /**
+     * Character encoding to be used to create a {@link java.io.Writer}
+     * from the underlying byte output stream.
+     */
     private String encoding;
+
+    /**
+     * Underlying {@link java.io.Writer} of this sink.
+     */
     private Writer writer;
 
     /**

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=1646246&r1=1646245&r2=1646246&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 Wed Dec 17 14:00:09 2014
@@ -35,8 +35,20 @@ import org.apache.portals.applications.w
 public class StreamSource implements Source
 {
 
+    /**
+     * The underlying {@link InputStream} which can be created once by calling {@link #getInputStream()}.
+     */
     private InputStream input;
-    private String encoding;
+
+    /**
+     * Character encoding to be used when {@link #getReader()} is invoked to create a
+     * reader from the underlying gzipped byte stream.
+     */
+    private String characterEncoding;
+
+    /**
+     * The underlying {@link Reader} which can be created once by calling {@link #getReader()}.
+     */
     private Reader reader;
 
     /**
@@ -55,7 +67,7 @@ public class StreamSource implements Sou
      * @param input
      * @param encoding
      */
-    public StreamSource(InputStream input, String encoding)
+    public StreamSource(InputStream input, String characterEncoding)
     {
         if (input == null)
         {
@@ -63,7 +75,7 @@ public class StreamSource implements Sou
         }
 
         this.input = input;
-        this.encoding = encoding;
+        this.characterEncoding = characterEncoding;
     }
 
     /**
@@ -111,13 +123,13 @@ public class StreamSource implements Sou
 
         if (reader == null)
         {
-            if (encoding == null)
+            if (characterEncoding == null)
             {
                 reader = new InputStreamReader(input);
             }
             else
             {
-                reader = new InputStreamReader(input, encoding);
+                reader = new InputStreamReader(input, characterEncoding);
             }
         }
 

Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java Wed Dec 17 14:00:09 2014
@@ -33,6 +33,10 @@ import javax.servlet.http.Cookie;
 import org.apache.portals.applications.webcontent2.proxy.RequestContext;
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
 
+/**
+ * {@link javax.portlet.PortletRequest} / {@link javax.portlet.PortletResponse}
+ * abstraction needed for reverse proxy processing.
+ */
 public class PortletRequestContext implements RequestContext
 {
 
@@ -58,21 +62,33 @@ public class PortletRequestContext imple
         return response;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean isSecure()
     {
         return request.isSecure();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getServerName()
     {
         return request.getServerName();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public int getServerPort()
     {
         return request.getServerPort();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getMethod()
     {
         if (request instanceof ClientDataRequest)
@@ -83,41 +99,65 @@ public class PortletRequestContext imple
         return "GET";
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getRequestBasePath()
     {
         return "";
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getPathInfo()
     {
         return "/";
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Object getAttribute(String name)
     {
         return request.getAttribute(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getQueryString()
     {
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Enumeration getHeaderNames()
     {
         return request.getPropertyNames();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Enumeration getHeaders(String name)
     {
         return request.getProperties(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getHeader(String name)
     {
         return request.getProperty(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public InputStream getInputStream() throws IOException
     {
         if (request instanceof ClientDataRequest)
@@ -128,6 +168,9 @@ public class PortletRequestContext imple
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setStatus(int sc)
     {
         this.responseStatus = sc;
@@ -138,6 +181,9 @@ public class PortletRequestContext imple
         return this.responseStatus;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void sendRedirect(String location) throws IOException
     {
         if (response instanceof ActionResponse)
@@ -146,16 +192,25 @@ public class PortletRequestContext imple
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setHeader(String name, String value)
     {
         response.setProperty(name, value);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setIntHeader(String name, int value)
     {
         response.setProperty(name, Integer.toString(value));
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void addCookie(Cookie cookie)
     {
         if (responseCookies == null)
@@ -166,6 +221,9 @@ public class PortletRequestContext imple
         responseCookies.add(cookie);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public List<Cookie> getCookies()
     {
         if (responseCookies == null)
@@ -176,6 +234,9 @@ public class PortletRequestContext imple
         return Collections.unmodifiableList(responseCookies);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Sink getSink()
     {
         if (sink == null)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/ProxyMapping.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/ProxyMapping.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/ProxyMapping.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/ProxyMapping.java Wed Dec 17 14:00:09 2014
@@ -32,6 +32,12 @@ import org.apache.portals.applications.w
  * <li>storing/retrieving/setting ad hoc attributes.</li>
  * </ul>
  * <p>
+ * <em>Note:</em> {@link #resolveRemoteFromLocal(String)} is usually invoked to resolve
+ * a remote target URI from a local request path info, whereas {@link #resolveLocalFromRemote(URI)}
+ * is usually invoked to resolve a local request path info from a remote target URI location
+ * (e.g, URI redirection response from the remote server).
+ * </p>
+ * <p>
  * <em>Note:</em> It is recommended to invoke {@link #resolveRemoteFromLocal(String)}
  * only when {@link #matchesLocal(String)} returns true.
  * In the same way, it is recommended to invoke {@link #resolveLocalFromRemote(URI)}
@@ -87,17 +93,17 @@ public interface ProxyMapping
     public Object getAttribute(String name);
 
     /**
-     * Stores an attribute in this context.
+     * Stores an attribute in this mapping.
      * @param name
      * @param value
      */
     public void setAttribute(String name, Object value);
 
     /**
-     * Removes an attribute from this context.
+     * Removes an attribute from this mapping.
      * @param name
      */
-    public void remoteAttribute(String name);
+    public void removeAttribute(String name);
 
     /**
      * Returns a <code>Map</code> containing the attributes available. 

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/RequestContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/RequestContext.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/RequestContext.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/RequestContext.java Wed Dec 17 14:00:09 2014
@@ -76,9 +76,22 @@ public interface RequestContext
 
     /**
      * Returns the base relative path of the request before the request path info.
+     * <p>
+     * Typically, in servlet runtime, it is either the concatenation of
+     * the request context path and the servlet path, or the concatenation of
+     * the request context path and the servlet filter mapping path prefix.
+     * </p>
+     * <p>
      * For example, in servlet runtime, if the context path is '/webcontent2',
      * the servlet path is '/rproxy' and the path info is '/a/b/c.html', then
-     * this method should return the concatenation of the context path and servlet path,
+     * this method may return the concatenation of the context path and servlet path,
+     * '/webcontent2/rproxy'.
+     * <p>
+     * <p>
+     * Or, if a servlet filter used for reverse proxy in servlet runtime, and
+     * if the context path is '/webcontent2', the servlet filter mapping path is '/rproxy/*'
+     * and the remaining path info is '/a/b/c.html', then
+     * this method may return the concatenation of the context path and filter mapping path prefix,
      * '/webcontent2/rproxy'.
      * <p>
      * <em>Note:</em> Portlet runtime doesn't give a request path info unlike servlet runtime.

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyCommand.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyCommand.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyCommand.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyCommand.java Wed Dec 17 14:00:09 2014
@@ -23,20 +23,61 @@ import org.apache.commons.chain.Context;
 import org.apache.portals.applications.webcontent2.proxy.ProxyContext;
 import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
 
+/**
+ * <p>Abstract {@link Command} base class encapsulating a unit of
+ * reverse proxy processing work to be performed, whose purpose is
+ * to support life cycle management with {@link #initialize()} and
+ * {@link #destroy()} methods, and to examine and/or modify the state of a
+ * reverse proxy transaction that is represented by a {@link ProxyContext}.
+ * Individual {@link AbstractProxyCommand}s can be assembled into a {@link ProxyProcessingChain},
+ * which allows them to either complete the required processing or delegate further
+ * processing to the next {@link AbstractProxyCommand} in the {@link AbstractProxyCommand}.</p>
+ * <p><em>Note: </em>{@link AbstractProxyCommand} implementations should be designed in a thread-safe
+ * manner, suitable for inclusion in multiple {@link ProxyProcessingChain}s that might be
+ * processed by different threads simultaneously.</p>
+ * 
+ * @see {@link Command}
+ */
 public abstract class AbstractProxyCommand implements Command
 {
 
+    /**
+     * Initializes the proxy command before using in a proxy processing chain.
+     */
     public void initialize()
     {
     }
 
-    public boolean execute(Context context) throws ReverseProxyException, IOException
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <em>Note:</em> This method simply casts the {@link Context} argument
+     * to {@link ProxyContext} and delegates the call to {@link #executeInternal(ProxyContext)}
+     * which must be implemented by a concrete command class.
+     * </p>
+     */
+    public final boolean execute(Context context) throws ReverseProxyException, IOException
     {
         return executeInternal((ProxyContext) context);
     }
 
+    /**
+     * <p>Execute a unit of processing work to be performed.  This
+     * {@link AbstractProxyCommand} may either complete the required processing
+     * and return <code>true</code>, or delegate remaining processing
+     * to the next {@link AbstractProxyCommand} in a {@link ProxyProcessingChain} containing this
+     * {@link AbstractProxyCommand} by returning <code>false</code>.
+     * @param context
+     * @return
+     * @throws ReverseProxyException
+     * @throws IOException
+     */
     protected abstract boolean executeInternal(final ProxyContext context) throws ReverseProxyException, IOException;
 
+    /**
+     * Invokes this method to give this proxy command a chance to dispose any resource
+     * used in reverse proxy processing.
+     */
     public void destroy()
     {
     }

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyMapping.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyMapping.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyMapping.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/AbstractProxyMapping.java Wed Dec 17 14:00:09 2014
@@ -23,12 +23,26 @@ import java.util.Map;
 import org.apache.portals.applications.webcontent2.proxy.ProxyMapping;
 import org.apache.portals.applications.webcontent2.rewriter.ContentRewriter;
 
+/**
+ * Abstract base implementation of {@link ProxyMapping}
+ * to provide the basic management features for attributes and content rewriters.
+ */
 public abstract class AbstractProxyMapping implements ProxyMapping
 {
 
+    /**
+     * Attribute key-value map.
+     */
     private Map<String, Object> attributes;
+
+    /**
+     * {@link ContentRewriter} map per content mime type.
+     */
     private Map<String, ContentRewriter> contentRewriters;
 
+    /**
+     * {@inheritDoc}
+     */
     public Object getAttribute(String name)
     {
         if (attributes != null)
@@ -39,6 +53,9 @@ public abstract class AbstractProxyMappi
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setAttribute(String name, Object value)
     {
         if (attributes == null)
@@ -49,7 +66,10 @@ public abstract class AbstractProxyMappi
         attributes.put(name, value);
     }
 
-    public void remoteAttribute(String name)
+    /**
+     * {@inheritDoc}
+     */
+    public void removeAttribute(String name)
     {
         if (attributes != null)
         {
@@ -57,6 +77,9 @@ public abstract class AbstractProxyMappi
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Map<String, Object> getAttributesMap()
     {
         if (attributes == null)
@@ -69,6 +92,9 @@ public abstract class AbstractProxyMappi
         }
     }
 
+    /**
+     * Stores all the given <code>attributes</code> map in mapping.
+     */
     public void setAttributesMap(String name, Map<String, Object> attributes)
     {
         this.attributes = new HashMap<String, Object>();
@@ -79,6 +105,11 @@ public abstract class AbstractProxyMappi
         }
     }
 
+    /**
+     * Returns an unmodifiable map of the internal content rewriters.
+     * If nothing exists, then it returns an empty map.
+     * @return
+     */
     public Map<String, ContentRewriter> getContentRewriters()
     {
         if (contentRewriters == null)
@@ -89,6 +120,10 @@ public abstract class AbstractProxyMappi
         return Collections.unmodifiableMap(contentRewriters);
     }
 
+    /**
+     * Sets the internal content rewriters map by copying <code>contentRewriters</code>.
+     * @param contentRewriters
+     */
     public void setContentRewriters(Map<String, ContentRewriter> contentRewriters)
     {
         this.contentRewriters = new HashMap<String, ContentRewriter>();
@@ -99,6 +134,9 @@ public abstract class AbstractProxyMappi
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public ContentRewriter getContentRewriter(String mimeType)
     {
         if (mimeType != null)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultProxyMappingRegistry.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultProxyMappingRegistry.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultProxyMappingRegistry.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultProxyMappingRegistry.java Wed Dec 17 14:00:09 2014
@@ -26,17 +26,28 @@ import org.apache.portals.applications.w
 import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
 
 
-
+/**
+ * Default simple implementation of {@link ProxyMappingRegistry}.
+ */
 public class DefaultProxyMappingRegistry implements ProxyMappingRegistry
 {
 
+    /**
+     * Internal proxy mapping list.
+     */
     private List<ProxyMapping> proxyMappings = new ArrayList<ProxyMapping>();
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean addProxyMapping(ProxyMapping proxyMapping)
     {
         return proxyMappings.add(proxyMapping);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean addAllProxyMappings(Collection<ProxyMapping> proxyMappingsCollection)
     {
         if (proxyMappingsCollection != null)
@@ -47,16 +58,25 @@ public class DefaultProxyMappingRegistry
         return false;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean removeProxyMapping(ProxyMapping proxyMapping)
     {
         return proxyMappings.remove(proxyMapping);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Collection<ProxyMapping> getProxyMappings()
     {
         return Collections.unmodifiableCollection(proxyMappings);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public ProxyMapping findProxyMappingByLocalPath(String localPath)
     {
         if (localPath == null)
@@ -75,6 +95,9 @@ public class DefaultProxyMappingRegistry
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public ProxyMapping findProxyMappingByRemoteURI(URI remoteURI)
     {
         if (remoteURI == null)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultReverseProxyService.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultReverseProxyService.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultReverseProxyService.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultReverseProxyService.java Wed Dec 17 14:00:09 2014
@@ -3,24 +3,38 @@ package org.apache.portals.applications.
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.commons.chain.Command;
 import org.apache.portals.applications.webcontent2.proxy.ProxyContext;
 import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
 import org.apache.portals.applications.webcontent2.proxy.ReverseProxyService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * Default reverse proxy service implementation.
+ */
 public class DefaultReverseProxyService implements ReverseProxyService
 {
 
     private static Logger log = LoggerFactory.getLogger(DefaultReverseProxyService.class);
 
+    /**
+     * The underlying {@link ProxyProcessingChain} containing {@link Command}s.
+     */
     private final ProxyProcessingChain proxyProcessingChain;
 
+    /**
+     * Constructs a <code>DefaultReverseProxyService</code> with the given <code>proxyProcessingChain</code>.
+     * @param proxyProcessingChain
+     */
     public DefaultReverseProxyService(final ProxyProcessingChain proxyProcessingChain)
     {
         this.proxyProcessingChain = proxyProcessingChain;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void invoke(ProxyContext proxyContext) throws ReverseProxyException, IOException
     {
         proxyProcessingChain.execute(proxyContext);
@@ -46,9 +60,14 @@ public class DefaultReverseProxyService
         }
     }
 
-    // TODO: use location-aware logger
+    /**
+     * Logs all the exceptions caught while calling on {@link #invoke(ProxyContext)}.
+     * @param exceptions
+     */
     protected void logExceptions(List<Exception> exceptions)
     {
+        // Note: maybe it can be more useful to use a location-aware logger here.
+
         if (log.isDebugEnabled())
         {
             for (Exception ex : exceptions)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultURICleaner.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultURICleaner.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultURICleaner.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/DefaultURICleaner.java Wed Dec 17 14:00:09 2014
@@ -19,15 +19,33 @@ package org.apache.portals.applications.
 import org.apache.commons.lang.StringUtils;
 import org.apache.portals.applications.webcontent2.proxy.URICleaner;
 
+/**
+ * Default simple {@link URICleaner} implementation.
+ * <p>
+ * This simply finds any strings given by {@link #setSearchList(String[])}
+ * from a URI string and replace each string in the URI string
+ * by the corresponding strings given by {@link #setReplacementList(String[])}.
+ * </p>
+ * <p>
+ * By default, it replaces a space (" ") by "%20".
+ * </p>
+ */
 public class DefaultURICleaner implements URICleaner
 {
     private String[] searchList = { " " };
     private String[] replacementList = { "%20" };
 
+    /**
+     * Zero-argument default constructor.
+     */
     public DefaultURICleaner()
     {
     }
 
+    /**
+     * Sets the search string array to find from URI strings.
+     * @param searchList
+     */
     public void setSearchList(String[] searchList)
     {
         this.searchList = null;
@@ -38,6 +56,10 @@ public class DefaultURICleaner implement
         }
     }
 
+    /**
+     * Sets the replace string array to replace URI strings with.
+     * @param replacementList
+     */
     public void setReplacementList(String[] replacementList)
     {
         this.replacementList = null;
@@ -48,6 +70,9 @@ public class DefaultURICleaner implement
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String clean(String uri)
     {
         return StringUtils.replaceEach(uri, searchList, replacementList);

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/GzippedSource.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/GzippedSource.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/GzippedSource.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/GzippedSource.java Wed Dec 17 14:00:09 2014
@@ -24,28 +24,66 @@ import java.util.zip.GZIPInputStream;
 
 import org.apache.portals.applications.webcontent2.rewriter.Source;
 
+/**
+ * Acts as an holder for a content rewriting Source in the form of a gzipped {@link Source}.
+ * <p>
+ * <em>Note:</em> Due to their internal use of either a Reader or InputStream instance,
+ * <code>GzippedSource</code> instances may only be used once.
+ * </p>
+ */
 public class GzippedSource implements Source
 {
 
+    /**
+     * Underlying gzipped {@link Source}.
+     */
     private final Source source;
+
+    /**
+     * Character encoding to be used when {@link #getReader()} is invoked to create a
+     * reader from the underlying gzipped byte stream.
+     */
     private final String characterEncoding;
 
+    /**
+     * Constructs a <code>GzippedSource</code> for the underlying gzipped <code>source</code>.
+     * @param source
+     */
     public GzippedSource(final Source source)
     {
         this(source, null);
     }
 
+    /**
+     * Constructs a <code>GzippedSource</code> for the underlying gzipped <code>source</code>
+     * with the specific <code>characterEncoding</code> which can be used when {@link #getReader()}
+     * is invoked from the underlying gzipped byte stream.
+     * @param source
+     * @param characterEncoding
+     */
     public GzippedSource(final Source source, final String characterEncoding)
     {
         this.source = source;
         this.characterEncoding = characterEncoding;
     }
 
+    /**
+     * Retrieves the gunzipped content as binary data using a {@link InputStream}.
+     * <P>
+     * Either this method or {@link #getReader} may be called to read the body, not both.
+     * </P>
+     */
     public InputStream getInputStream() throws IOException
     {
         return new GZIPInputStream(source.getInputStream());
     }
 
+    /**
+     * Retrieves the gunzipped content as character data using a {@link Reader}.
+     * <P>
+     * Either this method or {@link #getInputStream} may be called to read the body, not both.
+     * </P>
+     */
     public Reader getReader() throws IOException
     {
         if (characterEncoding != null)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpEntitySource.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpEntitySource.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpEntitySource.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpEntitySource.java Wed Dec 17 14:00:09 2014
@@ -26,28 +26,56 @@ import org.apache.http.HttpEntity;
 import org.apache.http.entity.ContentType;
 import org.apache.portals.applications.webcontent2.rewriter.Source;
 
+/**
+ * Acts as an holder for a content rewriting Source in the form of an {@link HttpEntity}.
+ */
 public class HttpEntitySource implements Source
 {
 
+    /**
+     * Underlying {@link HttpEntity} for this content source.
+     */
     private final HttpEntity entity;
+
+    /**
+     * Character encoding to be used when {@link #getReader()} is invoked to create a
+     * reader from the underlying gzipped byte stream.
+     */
     private final String characterEncoding;
 
+    /**
+     * Constructs an <code>HttpEntitySource</code> for the underlying {@link HttpEntity}.
+     * @param entity
+     */
     public HttpEntitySource(final HttpEntity entity)
     {
         this(entity, null);
     }
 
+    /**
+     * Constructs a <code>HttpEntitySource</code> for the underlying {@link HttpEntity}
+     * with the specific <code>characterEncoding</code> which can be used when {@link #getReader()}
+     * is invoked from the underlying {@link HttpEntity} content stream.
+     * @param entity
+     * @param characterEncoding
+     */
     public HttpEntitySource(final HttpEntity entity, final String characterEncoding)
     {
         this.entity = entity;
         this.characterEncoding = characterEncoding;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public InputStream getInputStream() throws IOException
     {
         return entity.getContent();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Reader getReader() throws IOException
     {
         String charsetName = characterEncoding;

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpServletResponseSink.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpServletResponseSink.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpServletResponseSink.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/HttpServletResponseSink.java Wed Dec 17 14:00:09 2014
@@ -24,21 +24,39 @@ import javax.servlet.http.HttpServletRes
 
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
 
+/**
+ * Acts as an holder for a content rewriting {@link Sink}
+ * in the form of byte or character stream of {@link HttpServletResponse}.
+ */
 public class HttpServletResponseSink implements Sink
 {
 
+    /**
+     * Underlying {@link HttpServletResponse} of this sink.
+     */
     private final HttpServletResponse response;
 
+    /**
+     * Constructs a <code>HttpServletResponseSink</code> for the given
+     * <code>response</code>.
+     * @param response
+     */
     public HttpServletResponseSink(final HttpServletResponse response)
     {
         this.response = response;
     }
 
+    /**
+     * Returns the {@link java.io.OutputStream} of the underlying {@link HttpServletResponse}.
+     */
     public OutputStream getOutputStream() throws IOException
     {
         return response.getOutputStream();
     }
 
+    /**
+     * Returns the {@link java.io.Writer} of the underlying {@link HttpServletResponse}.
+     */
     public Writer getWriter() throws IOException
     {
         return response.getWriter();

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyProcessingChain.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyProcessingChain.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyProcessingChain.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyProcessingChain.java Wed Dec 17 14:00:09 2014
@@ -35,28 +35,46 @@ import org.apache.portals.applications.w
 public class ProxyProcessingChain extends ChainBase
 {
 
+    /**
+     * Constructs a <code>ProxyProcessingChain</code> with no configured {@link Command}s.</p>
+     */
     public ProxyProcessingChain() 
     {
         super();
     }
 
+    /**
+     * Constructs a <code>ProxyProcessingChain</code> configured with the specified
+     * {@link Command}.</p>
+     * @param command
+     */
     public ProxyProcessingChain(Command command) 
     {
         super(command);
     }
 
+    /**
+     * Constructs a <code>ProxyProcessingChain</code> configured with the specified
+     * {@link Command}s.</p>
+     * @param commands
+     */
     public ProxyProcessingChain(Command[] commands) 
     {
         super(commands);
     }
 
+    /**
+     * Constructs a <code>ProxyProcessingChain</code> configured with the specified
+     * {@link Command}s.</p>
+     * @param commands
+     */
     public ProxyProcessingChain(@SuppressWarnings("rawtypes") Collection commands) 
     {
         super(commands);
     }
 
     /**
-     * Return the size of command list.
+     * Return the size of the internal {@link Command} list.
      * @return
      */
     public int getCommandCount() {
@@ -64,8 +82,8 @@ public class ProxyProcessingChain extend
     }
 
     /**
-     * Return the index of the given <code>command</code> in the command list.
-     * If not found, return -1.
+     * Return the index of the given {@link Command} in the command list.
+     * If not found, it should return -1.
      * @param command
      * @return
      */
@@ -73,6 +91,12 @@ public class ProxyProcessingChain extend
         return ArrayUtils.indexOf(commands, command);
     }
 
+    /**
+     * Return the index of the given class type of {@link Command} in the command list.
+     * If not found, it should return -1.
+     * @param commandType
+     * @return
+     */
     public int getCommandIndex(Class<? extends Command> commandType) {
         if (commands == null) {
             return -1;
@@ -92,7 +116,7 @@ public class ProxyProcessingChain extend
     }
 
     /**
-     * Find and return the command at the given <code>index</code> of the command list.
+     * Finds and returns the {@link Command} at the given <code>index</code> of the {@link Command} list.
      * @param index
      * @return
      */
@@ -199,6 +223,18 @@ public class ProxyProcessingChain extend
         return false;
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <em>Note:</em> The method implementation takes the strategy to catch all the exceptions
+     * thrown while executing commands in the chain in order to proceed to the next commands
+     * even when a command throws an exception in an earlier step.
+     * This guarantees each of the internal commands are always
+     * to execute. So, for example, a command, which is responsible for cleaning up all the
+     * resources used during the reverse proxy processing, will always have a chance to do
+     * its job in this reverse proxy processing chain.
+     * </p>
+     */
     @Override
     public boolean execute(Context context) throws ReverseProxyException, IOException
     {
@@ -215,7 +251,8 @@ public class ProxyProcessingChain extend
     }
 
     /**
-     * Return a list including all the descendant commands, type of which is <code>AbstractProxyCommand</code>
+     * Return a list including all the descendant {@link Command}s,
+     * type of which is <code>AbstractProxyCommand</code>
      * in this proxy processing chain.
      * @return
      */

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/RegexProxyMapping.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/RegexProxyMapping.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/RegexProxyMapping.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/RegexProxyMapping.java Wed Dec 17 14:00:09 2014
@@ -20,70 +20,167 @@ import java.net.URI;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.portals.applications.webcontent2.proxy.ProxyMapping;
+
+/**
+ * Java Regular Expression based {@link ProxyMapping} implementation.
+ * <p>
+ * For example, suppose this should cover the following mapping cases:
+ * <ul>
+ * <li>/portals/applications/a/b/c.html &lt;-&gt; http://portals.apache.org/applications/a/b/c.html</li>
+ * <li>/portals/pluto/a/b/c.html &lt;-&gt; http://portals.apache.org/pluto/a/b/c.html</li>
+ * <li>/portals/jetspeed-2/a/b/c.html &lt;-&gt; http://portals.apache.org/jetspeed-2/a/b/c.html</li>
+ * </ul>
+ * Then you might configure the properties of this like the following example to achieve
+ * the mappings shown above:
+ * <ul>
+ * <li><code>localPattern</code>: "^/portals/([A-Za-z]+)/(.*)$"</li>
+ * <li><code>remoteReplace</code>: "http://portals.apache.org/$1/$2"</li>
+ * <li><code>remotePattern</code>: "^http://portals\\.apache\\.org/([A-Za-z]+)/(.*)$"</li>
+ * <li><code>localReplace</code>: "/portals/$1/$2"</li>
+ * </ul>
+ * </p>
+ * <p>
+ * <em>Note: </em>
+ * The <code>localPattern</code> and <code>remoteReplace</code> properties are used
+ * in order to translate the local request path info to a remote target URI, whereas
+ * the <code>remotePattern</code> and <code>localReplace</code> properties are used
+ * in order to translate the remote location URI (e.g, redirection location) to a local
+ * request path info.
+ * </p>
+ */
 public class RegexProxyMapping extends AbstractProxyMapping
 {
 
+    /**
+     * Regular expression to evaluate a local request path info.
+     */
     private String localPattern;
+
+    /**
+     * Replace string to translate to a remote URI based on the regular expression
+     * result from {@link #localPattern}.
+     */
     private String remoteReplace;
 
+    /**
+     * Regular expression to evaluate a remote URL.
+     */
     private String remotePattern;
+
+    /**
+     * Replace string to translate to a local request path info based on the regular expression
+     * result from {@link #remotePattern}.
+     */
     private String localReplace;
 
+    /**
+     * Internal pattern instance created from {@link #localPattern}.
+     */
     private Pattern localPatternObject;
+
+    /**
+     * Internal pattern instance created from {@link #remotePattern}.
+     */
     private Pattern remotePatternObject;
 
+    /**
+     * Zero-argument default constructor.
+     */
     public RegexProxyMapping()
     {
     }
 
+    /**
+     * Returns the regular expression to evaluate a local request path info.
+     * @return
+     */
     public String getLocalPattern()
     {
         return localPattern;
     }
 
+    /**
+     * Sets the regular expression to evaluate a local request path info.
+     * @param localPattern
+     */
     public void setLocalPattern(String localPattern)
     {
         this.localPattern = localPattern;
         this.localPatternObject = Pattern.compile(localPattern);
     }
 
+    /**
+     * Returns the replace string to translate to a remote URI based on the regular expression
+     * result from {@link #getLocalPattern()}.
+     * @return
+     */
     public String getRemoteReplace()
     {
         return remoteReplace;
     }
 
+    /**
+     * Sets the replace string to translate to a remote URI based on the regular expression
+     * result from {@link #getLocalPattern()}.
+     * @param remoteReplace
+     */
     public void setRemoteReplace(String remoteReplace)
     {
         this.remoteReplace = remoteReplace;
     }
 
+    /**
+     * Returns the regular expression to evaluate a remote URL.
+     * @return
+     */
     public String getRemotePattern()
     {
         return remotePattern;
     }
 
+    /**
+     * Sets the regular expression to evaluate a remote URL.
+     * @param remotePattern
+     */
     public void setRemotePattern(String remotePattern)
     {
         this.remotePattern = remotePattern;
         this.remotePatternObject = Pattern.compile(remotePattern);
     }
 
+    /**
+     * Returns the replace string to translate to a local request path info based on the regular expression
+     * result from {@link #getRemotePattern}.
+     * @return
+     */
     public String getLocalReplace()
     {
         return localReplace;
     }
 
+    /**
+     * Sets the replace string to translate to a local request path info based on the regular expression
+     * result from {@link #getRemotePattern}.
+     * @param localReplace
+     */
     public void setLocalReplace(String localReplace)
     {
         this.localReplace = localReplace;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean matchesLocal(String localPath)
     {
         Matcher m = localPatternObject.matcher(localPath);
         return m.matches();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String resolveRemoteFromLocal(String localPath)
     {
         Matcher m = localPatternObject.matcher(localPath);
@@ -96,12 +193,18 @@ public class RegexProxyMapping extends A
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean matchesRemote(URI remoteURI)
     {
         Matcher m = remotePatternObject.matcher(remoteURI.toString());
         return m.matches();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String resolveLocalFromRemote(URI remoteURI)
     {
         Matcher m = remotePatternObject.matcher(remoteURI.toString());

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java Wed Dec 17 14:00:09 2014
@@ -28,50 +28,102 @@ import org.apache.portals.applications.w
 import org.apache.portals.applications.webcontent2.proxy.util.RequestUtils;
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
 
+/**
+ * {@link javax.servlet.http.HttpServletRequest} / {@link javax.servlet.http.HttpServletResponse}
+ * abstraction needed for reverse proxy processing.
+ */
 public class ServletRequestContext implements RequestContext
 {
 
+    /**
+     * Base relative path of the request before the request path info.
+     * Typically, it is either the concatenation of the request context path and
+     * the servlet path, or the concatenation of the request context path and
+     * the filter mapping path prefix.
+     */
     private String requestBasePath;
+
+    /**
+     * Underlying {@link javax.servlet.http.HttpServletRequest}
+     */
     private final HttpServletRequest request;
+
+    /**
+     * Underlying {@link javax.servlet.http.HttpServletResponse}
+     */
     private final HttpServletResponse response;
+
+    /**
+     * Underlying {@link Sink} used during reverse proxy processing.
+     */
     private Sink sink;
 
+    /**
+     * Constructs a <code>ServletRequestContext</code>
+     * with the given {@link javax.servlet.http.HttpServletRequest}
+     * and {@link javax.servlet.http.HttpServletResponse}.
+     * @param request
+     * @param response
+     */
     public ServletRequestContext(final HttpServletRequest request, final HttpServletResponse response)
     {
         this.request = request;
         this.response = response;
     }
 
+    /**
+     * Returns the underlying {@link javax.servlet.http.HttpServletRequest}.
+     * @return
+     */
     public HttpServletRequest getServletRequest()
     {
         return request;
     }
 
+    /**
+     * Returns the underlying {@link javax.servlet.http.HttpServletResponse}.
+     * @return
+     */
     public HttpServletResponse getServletResponse()
     {
         return response;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean isSecure()
     {
         return request.isSecure();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getServerName()
     {
         return request.getServerName();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public int getServerPort()
     {
         return request.getServerPort();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getMethod()
     {
         return request.getMethod();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getRequestBasePath()
     {
         if (requestBasePath != null)
@@ -97,6 +149,9 @@ public class ServletRequestContext imple
         this.requestBasePath = requestBasePath;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getPathInfo()
     {
         if (requestBasePath != null)
@@ -112,63 +167,99 @@ public class ServletRequestContext imple
         return RequestUtils.getPathInfo(request);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Object getAttribute(final String name)
     {
         return request.getAttribute(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getQueryString()
     {
         return request.getQueryString();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String getHeader(String name)
     {
         return request.getHeader(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public InputStream getInputStream() throws IOException
     {
         return request.getInputStream();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @SuppressWarnings("rawtypes")
     public Enumeration getHeaderNames()
     {
         return request.getHeaderNames();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @SuppressWarnings("rawtypes")
     public Enumeration getHeaders(String name)
     {
         return request.getHeaders(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void sendRedirect(String location) throws IOException
     {
         response.sendRedirect(location);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setHeader(String name, String value)
     {
         response.setHeader(name, value);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setIntHeader(String name, int value)
     {
         response.setIntHeader(name, value);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void addCookie(Cookie cookie)
     {
         response.addCookie(cookie);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public void setStatus(int sc)
     {
         response.setStatus(sc);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public Sink getSink()
     {
         if (sink == null)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/SimpleProxyMapping.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/SimpleProxyMapping.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/SimpleProxyMapping.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/SimpleProxyMapping.java Wed Dec 17 14:00:09 2014
@@ -19,42 +19,84 @@ package org.apache.portals.applications.
 import java.net.URI;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.portals.applications.webcontent2.proxy.ProxyMapping;
 
+/**
+ * Simple {@link ProxyMapping} implementation based on path prefix matching.
+ * <p>
+ * For example, if this represents a mapping between a local path prefix and
+ * a remote URI prefix like '/portals/' vs. 'http://portals.apache.org/',
+ * then a local request path info, '/portals/a/b/c.html', will be resolved to
+ * 'http://portals.apache.org/a/b/c.html' and vice versa.
+ * </p>
+ */
 public class SimpleProxyMapping extends AbstractProxyMapping
 {
 
+    /**
+     * Local request path info prefix to match/resolve.
+     */
     private String localBasePath;
+
+    /**
+     * Remote base URI prefix to match/resolve.
+     */
     private URI remoteBaseURI;
 
+    /**
+     * Zero-argument default constructor.
+     */
     public SimpleProxyMapping()
     {
     }
 
+    /**
+     * Returns the local request path info prefix.
+     * @return
+     */
     public String getLocal()
     {
         return localBasePath;
     }
 
+    /**
+     * Sets the local request path info prefix.
+     * @param localBasePath
+     */
     public void setLocal(String localBasePath)
     {
         this.localBasePath = localBasePath;
     }
 
+    /**
+     * Returns the remote target URI prefix.
+     * @return
+     */
     public URI getRemote()
     {
         return remoteBaseURI;
     }
 
+    /**
+     * Sets the remote target URI prefix.
+     * @param remoteBaseURI
+     */
     public void setRemote(URI remoteBaseURI)
     {
         this.remoteBaseURI = remoteBaseURI;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean matchesLocal(String localPath)
     {
         return StringUtils.startsWith(localPath, localBasePath);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String resolveRemoteFromLocal(String localPath)
     {
         if (matchesLocal(localPath))
@@ -65,11 +107,17 @@ public class SimpleProxyMapping extends
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public boolean matchesRemote(URI remoteURI)
     {
         return StringUtils.startsWith(remoteURI.toString(), remoteBaseURI.toString());
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public String resolveLocalFromRemote(URI remoteURI)
     {
         if (matchesRemote(remoteURI))

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/test/java/org/apache/portals/applications/webcontent2/proxy/ProxyCommandChainTest.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/test/java/org/apache/portals/applications/webcontent2/proxy/ProxyCommandChainTest.java?rev=1646246&r1=1646245&r2=1646246&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/test/java/org/apache/portals/applications/webcontent2/proxy/ProxyCommandChainTest.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/test/java/org/apache/portals/applications/webcontent2/proxy/ProxyCommandChainTest.java Wed Dec 17 14:00:09 2014
@@ -37,9 +37,7 @@ import java.util.Set;
 import org.apache.commons.chain.Catalog;
 import org.apache.commons.chain.Chain;
 import org.apache.commons.chain.Command;
-import org.apache.commons.chain.Context;
 import org.apache.commons.chain.impl.CatalogBase;
-import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
 import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
 import org.junit.Before;
@@ -198,9 +196,17 @@ public class ProxyCommandChainTest
     private abstract class AbstractLoggableCommand extends AbstractProxyCommand
     {
         @SuppressWarnings("unchecked")
-        @Override
-        public final boolean execute(Context context) throws ReverseProxyException, IOException
+        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
         {
+            try {
+                addLog(context, " is about to execute.");
+                return executeInternal2(context);
+            } finally {
+                addLog(context, " has executed.");
+            }
+        }
+
+        protected void addLog(final ProxyContext context, final String message) {
             List<String> logs = (List<String>) context.get("logs");
 
             if (logs == null) {
@@ -208,19 +214,16 @@ public class ProxyCommandChainTest
                 context.put("logs", logs);
             }
 
-            try {
-                logs.add(getClass().getSimpleName() + " is about to execute.");
-                return super.execute(context);
-            } finally {
-                logs.add(getClass().getSimpleName() + " has executed.");
-            }
+            logs.add(getClass().getSimpleName() + message);
         }
+
+        protected abstract boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException;
     }
 
     private class InitCommand extends AbstractLoggableCommand
     {
         @Override
-        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
+        protected boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException
         {
             return false;
         }
@@ -230,7 +233,7 @@ public class ProxyCommandChainTest
     {
         @SuppressWarnings("unchecked")
         @Override
-        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
+        protected boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException
         {
             final String roleAllowed = (String) context.get("role.allowed");
 
@@ -257,7 +260,7 @@ public class ProxyCommandChainTest
     private class RenderingCommand extends AbstractLoggableCommand
     {
         @Override
-        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
+        protected boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException
         {
             PrintWriter out = (PrintWriter) context.get("out");
             out.print("Hello, " + context.get("user.name") + "!");
@@ -270,7 +273,7 @@ public class ProxyCommandChainTest
     private class NotInvokedCommand extends AbstractLoggableCommand
     {
         @Override
-        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
+        protected boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException
         {
             return false;
         }
@@ -280,7 +283,7 @@ public class ProxyCommandChainTest
     {
         @SuppressWarnings("unchecked")
         @Override
-        protected boolean executeInternal(ProxyContext context) throws ReverseProxyException, IOException
+        protected boolean executeInternal2(ProxyContext context) throws ReverseProxyException, IOException
         {
             Collection<Closeable> closeables = (Collection<Closeable>) context.get("closeables");