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/08/18 01:53:10 UTC
svn commit: r1618528 - in /portals/applications/webcontent/trunk:
portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java
war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml
Author: woonsan
Date: Sun Aug 17 23:53:10 2014
New Revision: 1618528
URL: http://svn.apache.org/r1618528
Log:
APA-64: fixing thread-safety issue - Rewriter instance must not be shared between requests because it has request specific member variables such as http method name.
Modified:
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java
portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml
Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java?rev=1618528&r1=1618527&r2=1618528&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java Sun Aug 17 23:53:10 2014
@@ -19,7 +19,6 @@ package org.apache.portals.applications.
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -37,13 +36,10 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
-import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletURL;
@@ -115,19 +111,15 @@ public class WebContentPortlet extends G
public static final String HISTORY = "webcontent.history";
public static final String HTTP_STATE = "webcontent.http.state";
- // Class Data
protected final static Logger log = LoggerFactory.getLogger(WebContentPortlet.class);
- public final static String defaultEncoding = "UTF-8";
-
- // Data Members
- private Lock rewriterLock = new ReentrantLock();
- private RulesetRewriter rewriter = null;
- private RewriterController rewriteController = null;
public static final String FORM_MULTIPART_METHOD = "multipart";
public static final String NO_URL = "<p>URL source not specified. Go to edit mode and specify an URL.</p>";
+ private RewriterController rewriterController;
+ private Ruleset rewriterRuleSet;
+
private String defaultProxyHost;
private int defaultProxyPort = -1;
@@ -262,30 +254,18 @@ public class WebContentPortlet extends G
byte[] content = null;
+ // get content from current page
+ response.setContentType("text/html");
+
try
{
- // initialize the controller if it's not already done
- // and lock stateful rewriter
- initializeRewriter();
-
- // get content from current page
- response.setContentType("text/html");
-
- try
- {
- content = doWebContent(currentPage.getMethod(), currentPage.getUrl(), currentPage.getParams(), request, response);
- }
- catch (Throwable t)
- {
- PrintWriter writer = response.getWriter();
- writer.print("Error retrieveing web content:" + t.getMessage());
- return;
- }
+ content = doWebContent(currentPage.getMethod(), currentPage.getUrl(), currentPage.getParams(), request, response);
}
- finally
+ catch (Throwable t)
{
- // unlock stateful rewriter
- freeRewriter();
+ PrintWriter writer = response.getWriter();
+ writer.print("Error retrieveing web content:" + t.getMessage());
+ return;
}
// write the meta-control navigation header
@@ -317,7 +297,7 @@ public class WebContentPortlet extends G
try
{
bais = new ByteArrayInputStream(content);
- IOUtils.copy(new InputStreamReader(bais, WebContentPortlet.defaultEncoding), writer);
+ IOUtils.copy(new InputStreamReader(bais, "UTF-8"), writer);
}
finally
{
@@ -335,47 +315,40 @@ public class WebContentPortlet extends G
doPreferencesEdit(request, response);
}
- /*
- * Protected helpers for generating WebContent
- */
- protected void initializeRewriter() throws PortletException
- {
- initializeRewriter(WebContentRewriter.class);
- }
-
- protected void initializeRewriter(Class rewriterClass) throws PortletException
+ protected byte[] doWebContent(String method, String sourceAttr, Map sourceParams, RenderRequest request, RenderResponse response)
+ throws PortletException
{
- rewriterLock.lock();
+ CloseableHttpClient httpClient = null;
+ HttpRequestBase httpRequest = null ;
- if (rewriteController == null)
+ try
{
- PortletContext portletApplication = getPortletContext();
- String path = portletApplication.getRealPath("/WEB-INF");
- String contextPath = path + "/";
-
- try
+ if (rewriterController == null)
{
- // Create rewriter adaptor
- rewriteController = getController(contextPath, rewriterClass);
+ String webinfDirPath = getPortletContext().getRealPath("/WEB-INF") + "/";
+ rewriterController = getRewriterController(webinfDirPath, WebContentRewriter.class);
}
- catch (Exception e)
+
+ if (rewriterRuleSet == null)
{
- throw new PortletException("WebContentPortlet failed to create rewriter controller: "+e, e);
+ InputStream is = null;
+
+ try
+ {
+ is = getPortletContext().getResourceAsStream("/WEB-INF/conf/default-rewriter-rules.xml");
+ rewriterRuleSet = rewriterController.loadRuleset(is);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(is);
+ }
}
- }
- }
- protected byte[] doWebContent(String method, String sourceAttr, Map sourceParams, RenderRequest request, RenderResponse response)
- throws PortletException
- {
- CloseableHttpClient httpClient = null;
- HttpRequestBase httpRequest = null ;
+ WebContentRewriter rewriter = (WebContentRewriter) createRewriter(rewriterController, rewriterRuleSet);
- try
- {
// Set the action and base URLs in the rewriter
PortletURL action = response.createActionURL();
- ((WebContentRewriter) rewriter).setActionURL(action);
+ rewriter.setActionURL(action);
URL baseURL = new URL(sourceAttr);
rewriter.setBaseUrl(baseURL.toString());
@@ -384,7 +357,7 @@ public class WebContentPortlet extends G
{
Reader reader = new InputStreamReader((InputStream)baseURL.getContent());
StringWriter writer = new StringWriter();
- rewriter.rewrite(rewriteController.createParserAdaptor("text/html"), reader, writer);
+ rewriter.rewrite(rewriterController.createParserAdaptor("text/html"), reader, writer);
writer.flush();
return writer.toString().getBytes();
}
@@ -394,7 +367,7 @@ public class WebContentPortlet extends G
httpClient = getHttpClient(request, cookieStore) ;
String methodName = StringUtils.defaultIfEmpty(method, HttpGet.METHOD_NAME);
- if (FORM_MULTIPART_METHOD.equals(methodName))
+ if (StringUtils.equalsIgnoreCase(FORM_MULTIPART_METHOD, methodName))
{
httpRequest = createHttpRequest(httpClient, methodName, sourceAttr, null, sourceParams, request);
}
@@ -408,7 +381,7 @@ public class WebContentPortlet extends G
// ...get, cache, and return the content
if (result == null)
{
- return doHttpWebContent(httpClient, cookieStore, httpRequest, 0, request, response);
+ return doHttpWebContent(httpClient, cookieStore, httpRequest, 0, request, response, rewriter);
}
else
{
@@ -446,8 +419,8 @@ public class WebContentPortlet extends G
}
}
- protected byte[] doHttpWebContent(CloseableHttpClient httpClient, CookieStore cookieStore, HttpRequestBase httpRequest, int retryCount, RenderRequest request, RenderResponse response)
- throws PortletException
+ protected byte[] doHttpWebContent(CloseableHttpClient httpClient, CookieStore cookieStore, HttpRequestBase httpRequest, int retryCount,
+ RenderRequest request, RenderResponse response, WebContentRewriter rewriter) throws PortletException
{
CloseableHttpResponse httpResponse = null;
HttpEntity httpEntity = null;
@@ -500,7 +473,7 @@ public class WebContentPortlet extends G
if (retryCount++ < 1 && doRequestedAuthentication( httpClient, httpRequest, request, response))
{
// try again, now that we are authorizied
- return doHttpWebContent(httpClient, cookieStore, httpRequest, retryCount, request, response);
+ return doHttpWebContent(httpClient, cookieStore, httpRequest, retryCount, request, response, rewriter);
}
else
{
@@ -512,7 +485,7 @@ public class WebContentPortlet extends G
{
log.info("WebContentPortlet.doHttpWebContent() - retrying: " + httpRequest.getURI() + ", response code: " + responseCode);
// retry
- return doHttpWebContent(httpClient, cookieStore, httpRequest, retryCount, request, response);
+ return doHttpWebContent(httpClient, cookieStore, httpRequest, retryCount, request, response, rewriter);
}
else
{
@@ -531,17 +504,11 @@ public class WebContentPortlet extends G
String encoding = StringUtils.defaultIfEmpty((charset != null ? charset.name() : null), "UTF-8");
reader = new InputStreamReader(bis, encoding);
- // get the output buffer
- if (encoding == null)
- {
- encoding = WebContentPortlet.defaultEncoding;
- }
-
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
Writer htmlWriter = new OutputStreamWriter(byteOutputStream, encoding);
// rewrite and flush output
- rewriter.rewrite(rewriteController.createParserAdaptor("text/html"), reader, htmlWriter);
+ rewriter.rewrite(rewriterController.createParserAdaptor("text/html"), reader, htmlWriter);
htmlWriter.flush();
// Page has been rewritten
@@ -551,15 +518,15 @@ public class WebContentPortlet extends G
}
catch (UnsupportedEncodingException ueex)
{
- throw new PortletException("Encoding " + defaultEncoding + " not supported. Error: " + ueex.getMessage());
+ throw new PortletException("Encoding not supported. Error: " + ueex);
}
catch (RewriterException rwe)
{
- throw new PortletException("Failed to rewrite HTML page. Error: " + rwe.getMessage());
+ throw new PortletException("Failed to rewrite HTML page. Error: " + rwe);
}
catch (Exception e)
{
- throw new PortletException("Exception while rewritting HTML page. Error: " + e.getMessage());
+ throw new PortletException("Exception while rewritting HTML page. Error: " + e);
}
finally
{
@@ -606,31 +573,23 @@ public class WebContentPortlet extends G
/*
* Generate a rewrite controller using the basic rules file
*/
- protected RewriterController getController(String contextPath, Class rewriterClass) throws Exception
+ protected RewriterController getRewriterController(String contextPath, Class rewriterClass) throws Exception
{
- Class[] rewriterClasses = new Class[] { rewriterClass, rewriterClass};
- Class[] adaptorClasses = new Class[] { NekoParserAdaptor.class, SaxParserAdaptor.class};
- RewriterController rwc =
+ Class[] rewriterClasses = new Class[] { rewriterClass, rewriterClass };
+ Class[] adaptorClasses = new Class[] { NekoParserAdaptor.class, SaxParserAdaptor.class };
+ RewriterController rewriterController =
new MappingRewriterController(contextPath + "conf/rewriter-rules-mapping.xml",
Arrays.asList(rewriterClasses),
Arrays.asList(adaptorClasses));
- FileReader reader = new FileReader(contextPath + "conf/default-rewriter-rules.xml");
- Ruleset ruleset = rwc.loadRuleset(reader);
- reader.close();
- rewriter = rwc.createRewriter(ruleset);
- return rwc;
+ return rewriterController;
}
- protected RulesetRewriter getRewriter()
+ protected RulesetRewriter createRewriter(RewriterController rewriterController, Ruleset ruleset) throws RewriterException
{
+ RulesetRewriter rewriter = rewriterController.createRewriter(ruleset);
return rewriter;
}
- protected void freeRewriter()
- {
- rewriterLock.unlock();
- }
-
protected CloseableHttpClient getHttpClient(RenderRequest request, CookieStore cookieStore) throws IOException
{
// derived class hook (e.g. to set up Basic Authentication)
@@ -700,7 +659,7 @@ public class WebContentPortlet extends G
}
}
- if (HttpPost.METHOD_NAME.equals(method))
+ if (StringUtils.equalsIgnoreCase(HttpPost.METHOD_NAME, method))
{
httpRequest = new HttpPost(uriBuilder.build());
@@ -732,7 +691,7 @@ public class WebContentPortlet extends G
}
}
}
- else if (HttpGet.METHOD_NAME.equals(method))
+ else if (StringUtils.equalsIgnoreCase(HttpGet.METHOD_NAME, method) || StringUtils.isBlank(method))
{
httpRequest = new HttpGet(uriBuilder.build());
}
Modified: portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml?rev=1618528&r1=1618527&r2=1618528&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml (original)
+++ portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/conf/rewriter-rules-mapping.xml Sun Aug 17 23:53:10 2014
@@ -16,7 +16,7 @@ See the License for the specific languag
limitations under the License.
-->
<mapping>
- <class name="org.apache.portals.applications.webcontent2.rewriter.rules.impl.RulesetImpl">
+ <class name="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.RulesetImpl">
<map-to xml="ruleset"/>
<field name="id" type="java.lang.String">
@@ -28,20 +28,20 @@ limitations under the License.
</field>
<field name="tags"
- type="org.apache.portals.applications.webcontent2.rewriter.rules.impl.TagImpl"
+ type="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.TagImpl"
collection="collection">
<bind-xml name="tag"/>
</field>
<field name="rules"
- type="org.apache.portals.applications.webcontent2.rewriter.rules.impl.RuleImpl"
+ type="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.RuleImpl"
collection="collection">
<bind-xml name="rule"/>
</field>
</class>
- <class name="org.apache.portals.applications.webcontent2.rewriter.rules.impl.TagImpl">
+ <class name="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.TagImpl">
<map-to xml="tag"/>
<field name="id" type="java.lang.String">
@@ -57,14 +57,14 @@ limitations under the License.
</field>
<field name="attributes"
- type="org.apache.portals.applications.webcontent2.rewriter.rules.impl.AttributeImpl"
+ type="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.AttributeImpl"
collection="collection">
<bind-xml name="attribute"/>
</field>
</class>
- <class name="org.apache.portals.applications.webcontent2.rewriter.rules.impl.RuleImpl">
+ <class name="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.RuleImpl">
<map-to xml="rule"/>
<field name="id" type="java.lang.String">
@@ -89,7 +89,7 @@ limitations under the License.
</class>
- <class name="org.apache.portals.applications.webcontent2.rewriter.rules.impl.AttributeImpl">
+ <class name="org.apache.portals.applications.webcontent2.portlet.rewriter.rules.impl.AttributeImpl">
<map-to xml="attribute"/>
<field name="id" type="java.lang.String">