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/29 05:16:09 UTC
svn commit: r1621242 - in /portals/applications/webcontent/trunk:
content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/
content-rewriter/src/test/java/org/apache/portals/applications/webcontent2/rewriter/
port...
Author: woonsan
Date: Fri Aug 29 03:16:08 2014
New Revision: 1621242
URL: http://svn.apache.org/r1621242
Log:
APA-66: Adding simpleReverseProxyPortlet with html cleaner based content rewriting
Added:
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/ContentSelectorUtils.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPage.java
- copied, changed from r1621008, portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryPage.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPageHistory.java
- copied, changed from r1621008, portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryList.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletAnyProxyMapping.java
Removed:
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryList.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryPage.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentResource.java
Modified:
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/test/java/org/apache/portals/applications/webcontent2/rewriter/HtmlCleanerContentRewriterTest.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentPortlet.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/GenericReverseProxyPortlet.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletRequestContext.java
portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java
portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyContext.java
portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java
portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/portlet.xml
portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/psml/test-webcontent2.psml
Added: 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=1621242&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java (added)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AbstractProxyTagNodeVisitor.java Fri Aug 29 03:16:08 2014
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent2.rewriter.htmlcleaner;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.htmlcleaner.CommentNode;
+import org.htmlcleaner.HtmlNode;
+import org.htmlcleaner.TagNode;
+import org.htmlcleaner.TagNodeVisitor;
+
+public abstract class AbstractProxyTagNodeVisitor implements TagNodeVisitor
+{
+
+ private Map<String, String> tagNameAndLinkAttrs;
+
+ public AbstractProxyTagNodeVisitor(Map<String, String> tagNameAndLinkAttrs)
+ {
+ this.tagNameAndLinkAttrs = new HashMap<String, String>();
+
+ if (tagNameAndLinkAttrs != null)
+ {
+ this.tagNameAndLinkAttrs.putAll(tagNameAndLinkAttrs);
+ }
+ }
+
+ public boolean visit(TagNode parentNode, HtmlNode htmlNode)
+ {
+ if (htmlNode instanceof TagNode)
+ {
+ return visitTagNode(parentNode, (TagNode) htmlNode);
+ }
+ else if (htmlNode instanceof CommentNode)
+ {
+ return visitCommentNode(parentNode, (CommentNode) htmlNode);
+ }
+
+ return true;
+ }
+
+ protected boolean visitTagNode(TagNode parentNode, TagNode tag)
+ {
+ String tagName = tag.getName();
+ String linkAttrName = tagNameAndLinkAttrs.get(tagName);
+
+ if (StringUtils.isEmpty(linkAttrName))
+ {
+ return true;
+ }
+
+ String link = tag.getAttributeByName(linkAttrName);
+
+ if (StringUtils.isNotEmpty(link))
+ {
+ String rewritten = rewriteURI(tagName, linkAttrName, link);
+
+ if (!StringUtils.equals(link, rewritten))
+ {
+ tag.addAttribute(linkAttrName, rewritten);
+ }
+ }
+
+ return true;
+ }
+
+ protected boolean visitCommentNode(TagNode parentNode, CommentNode comment)
+ {
+ return true;
+ }
+
+ protected abstract String rewriteURI(String tagName, String attrName, String uri);
+
+}
Added: 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=1621242&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java (added)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/AndTagNodeCondition.java Fri Aug 29 03:16:08 2014
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent2.rewriter.htmlcleaner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.htmlcleaner.TagNode;
+import org.htmlcleaner.conditional.ITagNodeCondition;
+
+public class AndTagNodeCondition implements ITagNodeCondition
+{
+
+ private List<ITagNodeCondition> conditionsList;
+
+ public AndTagNodeCondition()
+ {
+ }
+
+ public void addTagNodeCondition(ITagNodeCondition condition)
+ {
+ if (conditionsList == null)
+ {
+ conditionsList = new ArrayList<ITagNodeCondition>();
+ }
+
+ conditionsList.add(condition);
+ }
+
+ public boolean satisfy(TagNode tagNode)
+ {
+ if (conditionsList == null || conditionsList.isEmpty())
+ {
+ return false;
+ }
+
+ for (ITagNodeCondition condition : conditionsList)
+ {
+ if (!condition.satisfy(tagNode))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
Added: portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/ContentSelectorUtils.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/ContentSelectorUtils.java?rev=1621242&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/ContentSelectorUtils.java (added)
+++ portals/applications/webcontent/trunk/content-rewriter/src/main/java/org/apache/portals/applications/webcontent2/rewriter/htmlcleaner/ContentSelectorUtils.java Fri Aug 29 03:16:08 2014
@@ -0,0 +1,79 @@
+package org.apache.portals.applications.webcontent2.rewriter.htmlcleaner;
+
+import org.apache.commons.lang.StringUtils;
+import org.htmlcleaner.conditional.ITagNodeCondition;
+import org.htmlcleaner.conditional.TagNodeAttExistsCondition;
+import org.htmlcleaner.conditional.TagNodeAttValueCondition;
+import org.htmlcleaner.conditional.TagNodeNameCondition;
+
+class ContentSelectorUtils
+{
+
+ private ContentSelectorUtils()
+ {
+ }
+
+ /**
+ * Support transforming very simple selector string to <code>ITagNodeCondition</code>.
+ * <P>
+ * <EM>Note: This supports only 'elem[attr=value]' pattern only.
+ * </P>
+ * @param selector
+ * @return
+ */
+ public static ITagNodeCondition createTagNodeConditionBySelector(String selector)
+ {
+ AndTagNodeCondition condition = new AndTagNodeCondition();
+
+ if (StringUtils.isBlank(selector))
+ {
+ return condition;
+ }
+
+ String elementName = null;
+ String attributeName = null;
+ String attributeValue = null;
+
+ int offset = StringUtils.indexOf(selector, "[");
+
+ if (offset == -1)
+ {
+ elementName = StringUtils.trim(selector);
+ }
+ else
+ {
+ elementName = StringUtils.trim(StringUtils.substring(selector, 0, offset));
+ selector = StringUtils.trim(StringUtils.substringBefore(StringUtils.substring(selector, offset + 1), "]"));
+ offset = StringUtils.indexOf(selector, "=");
+
+ if (offset == -1)
+ {
+ attributeName = selector;
+ }
+ else
+ {
+ attributeName = StringUtils.trim(StringUtils.substring(selector, 0, offset));
+ attributeValue = StringUtils.trim(StringUtils.substring(selector, offset + 1));
+ }
+ }
+
+ if (StringUtils.isNotEmpty(elementName))
+ {
+ condition.addTagNodeCondition(new TagNodeNameCondition(elementName));
+ }
+
+ if (StringUtils.isNotEmpty(attributeName))
+ {
+ if (attributeValue == null)
+ {
+ condition.addTagNodeCondition(new TagNodeAttExistsCondition(attributeName));
+ }
+ else
+ {
+ condition.addTagNodeCondition(new TagNodeAttValueCondition(attributeName, attributeValue, true));
+ }
+ }
+
+ return condition;
+ }
+}
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=1621242&r1=1621241&r2=1621242&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 Fri Aug 29 03:16:08 2014
@@ -39,19 +39,16 @@ import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.Serializer;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.TagNodeVisitor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.htmlcleaner.conditional.ITagNodeCondition;
public class HtmlCleanerContentRewriter implements ContentRewriter
{
- private static Logger log = LoggerFactory.getLogger(HtmlCleanerContentRewriter.class);
-
private HtmlCleaner cleaner;
private SerializerFactory serializerFactory;
private String sinkEncoding = "UTF-8";
- private String rootTagName;
- private boolean innerRootTagOnly;
+ private String contentSelector;
+ private boolean innerHtmlOnly;
private String [] transformationInfos;
private List<TagNodeVisitor> tagNodeVisitors;
@@ -79,24 +76,24 @@ public class HtmlCleanerContentRewriter
this.sinkEncoding = sinkEncoding;
}
- public String getRootTagName()
+ public String getContentSelector()
{
- return rootTagName;
+ return contentSelector;
}
- public void setRootTagName(String rootTagName)
+ public void setContentSelector(String contentSelector)
{
- this.rootTagName = rootTagName;
+ this.contentSelector = contentSelector;
}
- public boolean isInnerRootTagOnly()
+ public boolean isInnerHtmlOnly()
{
- return innerRootTagOnly;
+ return innerHtmlOnly;
}
- public void setInnerRootTagOnly(boolean innerRootTagOnly)
+ public void setInnerHtmlOnly(boolean innerHtmlOnly)
{
- this.innerRootTagOnly = innerRootTagOnly;
+ this.innerHtmlOnly = innerHtmlOnly;
}
public CleanerTransformations getCleanerTransformations()
@@ -218,27 +215,53 @@ public class HtmlCleanerContentRewriter
bw = new BufferedWriter(writer);
TagNode rootTagNode = getHtmlCleaner().clean(br);
+ List<? extends TagNode> contentTagNodes = null;
- if (getRootTagName() != null)
+ if (getContentSelector() != null)
{
- TagNode [] tagNodes = rootTagNode.getElementsByName(getRootTagName(), true);
-
- if (tagNodes.length > 0 ) {
- rootTagNode = tagNodes[0];
- }
+ ITagNodeCondition selectCondition = ContentSelectorUtils.createTagNodeConditionBySelector(getContentSelector());
+ contentTagNodes = rootTagNode.getElementList(selectCondition, true);
}
- for (TagNodeVisitor tagNodeVisitor : getTagNodeVisitors())
+ if (contentTagNodes != null && !contentTagNodes.isEmpty())
{
- rootTagNode.traverse(tagNodeVisitor);
- }
+ for (TagNode contentTagNode : contentTagNodes)
+ {
+ for (TagNodeVisitor tagNodeVisitor : getTagNodeVisitors())
+ {
+ contentTagNode.traverse(tagNodeVisitor);
+ }
+ }
- if (isInnerRootTagOnly())
- {
- writer.write(getHtmlCleaner().getInnerHtml(rootTagNode));
+ if (isInnerHtmlOnly())
+ {
+ String innerHtml = null;
+
+ for (TagNode contentTagNode : contentTagNodes)
+ {
+ innerHtml = getHtmlCleaner().getInnerHtml(contentTagNode);
+
+ if (innerHtml != null)
+ {
+ writer.write(innerHtml);
+ }
+ }
+ }
+ else
+ {
+ for (TagNode contentTagNode : contentTagNodes)
+ {
+ serializer.write(contentTagNode, writer, getSinkEncoding());
+ }
+ }
}
else
{
+ for (TagNodeVisitor tagNodeVisitor : getTagNodeVisitors())
+ {
+ rootTagNode.traverse(tagNodeVisitor);
+ }
+
serializer.write(rootTagNode, writer, getSinkEncoding());
}
}
Modified: portals/applications/webcontent/trunk/content-rewriter/src/test/java/org/apache/portals/applications/webcontent2/rewriter/HtmlCleanerContentRewriterTest.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/content-rewriter/src/test/java/org/apache/portals/applications/webcontent2/rewriter/HtmlCleanerContentRewriterTest.java?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/content-rewriter/src/test/java/org/apache/portals/applications/webcontent2/rewriter/HtmlCleanerContentRewriterTest.java (original)
+++ portals/applications/webcontent/trunk/content-rewriter/src/test/java/org/apache/portals/applications/webcontent2/rewriter/HtmlCleanerContentRewriterTest.java Fri Aug 29 03:16:08 2014
@@ -95,8 +95,8 @@ public class HtmlCleanerContentRewriterT
contentRewriter = new HtmlCleanerContentRewriter();
contentRewriter.setSerializerFactory(serializerFactory);
- contentRewriter.setRootTagName("body");
- contentRewriter.setInnerRootTagOnly(true);
+ contentRewriter.setContentSelector("body");
+ contentRewriter.setInnerHtmlOnly(true);
contentRewriter.setCleanerTransformationStringArray(HTMLCLEANER_TRNSFORM_INFO);
final String siteUrl = "http://www.example.com/";
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=1621242&r1=1621241&r2=1621242&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 Fri Aug 29 03:16:08 2014
@@ -70,6 +70,8 @@ import org.apache.http.impl.client.HttpC
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
+import org.apache.portals.applications.webcontent2.portlet.history.WebContentPageHistory;
+import org.apache.portals.applications.webcontent2.portlet.history.WebContentPage;
import org.apache.portals.applications.webcontent2.portlet.rewriter.MappingRewriterController;
import org.apache.portals.applications.webcontent2.portlet.rewriter.RewriterController;
import org.apache.portals.applications.webcontent2.portlet.rewriter.RewriterException;
@@ -159,7 +161,7 @@ public class WebContentPortlet extends G
if (!browserAction.equalsIgnoreCase(BROWSER_ACTION_REFRESH_PAGE))
{
// for Refresh, there is nothing special to do - current history page will be re-displayed
- WebContentHistoryList history = (WebContentHistoryList)PortletMessaging.receive(actionRequest, HISTORY);
+ WebContentPageHistory history = (WebContentPageHistory)PortletMessaging.receive(actionRequest, HISTORY);
if (browserAction.equalsIgnoreCase(BROWSER_ACTION_PREVIOUS_PAGE))
{
@@ -203,14 +205,14 @@ public class WebContentPortlet extends G
if (webContentURL != null && webContentURL.length() > 0)
{
// new page visit - make it the current page in the history
- WebContentHistoryList history = (WebContentHistoryList)PortletMessaging.receive(actionRequest, HISTORY);
+ WebContentPageHistory history = (WebContentPageHistory)PortletMessaging.receive(actionRequest, HISTORY);
if (history == null)
{
- history = new WebContentHistoryList();
+ history = new WebContentPageHistory();
}
- history.visitPage(new WebContentHistoryPage(webContentURL,webContentParams,webContentMethod));
+ history.visitPage(new WebContentPage(webContentURL, webContentMethod, webContentParams));
PortletMessaging.publish(actionRequest, HISTORY, history);
}
}
@@ -230,14 +232,14 @@ public class WebContentPortlet extends G
}
// view the current page in the history
- WebContentHistoryList history = (WebContentHistoryList)PortletMessaging.receive(request, HISTORY);
+ WebContentPageHistory history = (WebContentPageHistory)PortletMessaging.receive(request, HISTORY);
if (history == null)
{
- history = new WebContentHistoryList();
+ history = new WebContentPageHistory();
}
- WebContentHistoryPage currentPage = history.getCurrentPage();
+ WebContentPage currentPage = history.getCurrentPage();
if (currentPage == null)
{
@@ -249,7 +251,7 @@ public class WebContentPortlet extends G
return;
}
- currentPage = new WebContentHistoryPage(sourceURL);
+ currentPage = new WebContentPage(sourceURL);
}
byte[] content = null;
Copied: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPage.java (from r1621008, portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryPage.java)
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPage.java?p2=portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPage.java&p1=portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryPage.java&r1=1621008&r2=1621242&rev=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryPage.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPage.java Fri Aug 29 03:16:08 2014
@@ -14,47 +14,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.portals.applications.webcontent2.portlet;
+package org.apache.portals.applications.webcontent2.portlet.history;
import java.io.Serializable;
-import java.util.HashMap;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
-
/**
- * Information required to re-visit a page in the WebContentPortlet
- *
- * @author <a href="mailto:dyoung@phase2systems.com">David L Young</a>
- * @version $Id$
+ * Web content page
*/
-
-public class WebContentHistoryPage implements Serializable
+public class WebContentPage implements Serializable
{
-
private static final long serialVersionUID = 1L;
private String method;
private String url;
private Map<String, String[]> params;
- public WebContentHistoryPage(String url)
+ public WebContentPage(String url)
+ {
+ this(url, null);
+ }
+
+ public WebContentPage(String url, String method)
{
- this(url, null, null);
+ this(url, method, null);
}
- public WebContentHistoryPage(String url, Map<String, String[]> params, String method)
+ public WebContentPage(String url, String method, Map<String, String[]> params)
{
- // guarantee non-null, so that equals() is well-behaved
if (url == null)
{
- throw new IllegalArgumentException("WebContentHistoryPage() - url required");
+ throw new IllegalArgumentException("url must not be null.");
}
this.url = url;
- this.params = (params != null ? params : new HashMap<String, String[]>());
this.method = method;
+ this.params = new LinkedHashMap<String, String[]>();
+
+ if (params != null)
+ {
+ this.params.putAll(params);
+ }
}
public String getMethod()
@@ -62,50 +66,33 @@ public class WebContentHistoryPage imple
return method;
}
- public void setMethod(String method)
- {
- this.method = method;
- }
-
public String getUrl()
{
return url;
}
- public void setUrl(String url)
- {
- this.url = url;
- }
-
public Map<String, String[]> getParams()
{
- return params;
- }
-
- public void setParams(Map<String, String[]> params)
- {
- this.params = params;
+ return Collections.unmodifiableMap(params);
}
@Override
public boolean equals(Object o)
{
- if (o == null || !(o instanceof WebContentHistoryPage))
+ if (o == null || !(o instanceof WebContentPage))
{
return false;
}
- WebContentHistoryPage page = (WebContentHistoryPage) o;
-
- return (StringUtils.equals(page.url, this.url) && page.params.equals(this.params) && StringUtils.equals(page.method, this.method));
+ WebContentPage other = (WebContentPage) o;
+ return (StringUtils.equals(other.url, this.url) && StringUtils.equals(other.method, this.method) && other.params.equals(this.params));
}
@Override
public String toString()
{
- StringBuilder sb = new StringBuilder();
- sb.append( "[" ).append(method).append(": ").append(url).append(", params: ").append(params).append("]");
+ StringBuilder sb = new StringBuilder(super.toString()).append(' ');
+ sb.append("[").append(method).append(": ").append(url).append(", params: ").append(params).append("]");
return sb.toString();
}
-
}
Copied: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPageHistory.java (from r1621008, portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryList.java)
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPageHistory.java?p2=portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPageHistory.java&p1=portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryList.java&r1=1621008&r2=1621242&rev=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/WebContentHistoryList.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/history/WebContentPageHistory.java Fri Aug 29 03:16:08 2014
@@ -14,110 +14,111 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.portals.applications.webcontent2.portlet;
+package org.apache.portals.applications.webcontent2.portlet.history;
import java.io.Serializable;
-import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
-
/**
- * A history of content navigations in the WebContentPortlet
- *
- * @author <a href="mailto:dyoung@phase2systems.com">David L Young</a>
- * @version $Id$
+ * History of web content page navigations
*/
-
-public class WebContentHistoryList extends Object
- implements Serializable
+public class WebContentPageHistory implements Serializable
{
- int maxLength;
- List history;
- int currentIndex;
-
- // Constructors
-
- public WebContentHistoryList()
- {
- this( -1 );
- }
- public WebContentHistoryList( int maxLength )
- {
- super();
-
- this.maxLength = maxLength;
- this.history = new ArrayList();
- this.currentIndex = -1;
- }
-
- // Methods
-
+ private static final long serialVersionUID = 1L;
+
+ private List<WebContentPage> pageList;
+ private int curIndex = -1;
+
+ public WebContentPageHistory()
+ {
+ pageList = new LinkedList<WebContentPage>();
+ }
+
public boolean isEmpty()
{
- return this.history.isEmpty();
+ return (pageList == null || pageList.isEmpty());
}
+
public boolean hasCurrentPage()
{
- return this.currentIndex >= 0;
+ return curIndex >= 0;
}
+
public boolean hasPreviousPage()
{
- return !isEmpty() && this.currentIndex-1 >= 0;
+ return !isEmpty() && (curIndex > 0);
}
+
public boolean hasNextPage()
{
- return !isEmpty() && this.currentIndex+1 < this.history.size();
+ return !isEmpty() && (curIndex < pageList.size() - 1);
}
-
- public WebContentHistoryPage getCurrentPage()
+
+ public WebContentPage getCurrentPage()
{
if (!hasCurrentPage())
- return null ;
- return (WebContentHistoryPage)this.history.get(this.currentIndex);
+ {
+ return null;
+ }
+
+ return (WebContentPage) pageList.get(curIndex);
}
- public WebContentHistoryPage getPreviousPage()
+
+ public WebContentPage getPreviousPage()
{
if (!hasPreviousPage())
+ {
return null;
- this.currentIndex = this.currentIndex-1;
+ }
+
+ curIndex -= 1;
+
return getCurrentPage();
}
- public WebContentHistoryPage getNextPage()
+
+ public WebContentPage getNextPage()
{
if (!hasNextPage())
+ {
return null;
- this.currentIndex = this.currentIndex+1;
+ }
+
+ curIndex += 1;
+
return getCurrentPage();
}
-
- public void visitPage(WebContentHistoryPage page)
+
+ public void visitPage(WebContentPage page)
{
- if (page==null)
- throw new IllegalArgumentException("WebContentHistoryList.addPage() - non-null page required.");
-
- int i = this.history.indexOf(page);
- if (i >= 0 && i == this.currentIndex)
+ if (page == null)
+ {
+ throw new IllegalArgumentException("page must be not null.");
+ }
+
+ int index = pageList.indexOf(page);
+
+ if (index != -1 && index == curIndex)
{
- // just visiting the current page
+ // just you're visiting the current page
return;
}
-
- // otherwise - new page...
+
+ // otherwise new page...
while (hasNextPage())
{
// ...visiting a page discards any pages we have visited by going "back"
- this.history.remove(this.currentIndex+1);
+ pageList.remove(curIndex + 1);
}
- if (i >= 0 && i < history.size())
+
+ if (index != -1 && index < pageList.size())
{
// ...actually, new visit to an old page, only keep one reference to it
- this.history.remove(i);
+ pageList.remove(index);
}
-
+
// add in the new page, at the end
- this.history.add(page);
- this.currentIndex = this.history.size()-1;
-
- // System.out.println("WebContentHistoryList.visitPage() - current index is: "+this.currentIndex+"\nhistory list..."+ArrayUtils.toString(this.history));
+ pageList.add(page);
+ curIndex = pageList.size() - 1;
}
}
Added: 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=1621242&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/DefaultPortletProxyTagNodeVisitor.java Fri Aug 29 03:16:08 2014
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent2.portlet.proxy;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.MimeResponse;
+import javax.portlet.PortletResponse;
+import javax.portlet.PortletURL;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.client.utils.URIUtils;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.apache.portals.applications.webcontent2.rewriter.htmlcleaner.AbstractProxyTagNodeVisitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultPortletProxyTagNodeVisitor extends AbstractProxyTagNodeVisitor
+{
+
+ private static Logger log = LoggerFactory.getLogger(DefaultPortletProxyTagNodeVisitor.class);
+
+ 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");
+ }
+
+ public DefaultPortletProxyTagNodeVisitor()
+ {
+ this(DEFAULT_TAG_NAME_AND_LINK_ATTRS);
+ }
+
+ public DefaultPortletProxyTagNodeVisitor(Map<String, String> tagNameAndLinkAttrs)
+ {
+ super(tagNameAndLinkAttrs);
+ }
+
+ @Override
+ protected String rewriteURI(String tagName, String attrName, String uri)
+ {
+ if (!isRewritableURI(uri))
+ {
+ return uri;
+ }
+
+ ProxyContext proxyContext = ProxyContext.getCurrentProxyContext();
+ PortletRequestContext prc = (PortletRequestContext) proxyContext.getRequestContext();
+ PortletResponse response = prc.getPortletResponse();
+
+ if (!(response instanceof MimeResponse))
+ {
+ log.error("Cannot rewrite url because response is not a MimeResponse.");
+ return uri;
+ }
+
+ URI remoteURI = proxyContext.getRemoteURI();
+
+ URI uriObj = null;
+
+ try
+ {
+ uriObj = URI.create(uri);
+ }
+ catch (Exception e)
+ {
+ log.warn("Invalid uri: '{}'.", uri);
+ return uri;
+ }
+
+ URI rewrittenURI = URIUtils.resolve(remoteURI, uriObj);
+
+ if ("src".equals(attrName))
+ {
+ return rewrittenURI.toString();
+ }
+ else
+ {
+ PortletURL actionUrl = ((MimeResponse) response).createActionURL();
+ actionUrl.setParameter(GenericReverseProxyPortlet.REMOTE_URI_PARAM_NAME, rewrittenURI.toString());
+ return actionUrl.toString();
+ }
+ }
+
+ protected boolean isRewritableURI(String uri)
+ {
+ // mailto: URIs often contain invalid characters in web pages to avoid spams
+ // and #, javascript: and data: URIs do not need to be parsed at all.
+ // These should be avoided in URI rewriting.
+ if (StringUtils.startsWith(uri, "#")
+ || StringUtils.startsWith(uri, "javascript:")
+ || StringUtils.startsWith(uri, "mailto:")
+ || StringUtils.startsWith(uri, "data:"))
+ {
+ return false;
+ }
+
+ return true;
+ }
+}
Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/GenericReverseProxyPortlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/GenericReverseProxyPortlet.java?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/GenericReverseProxyPortlet.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/GenericReverseProxyPortlet.java Fri Aug 29 03:16:08 2014
@@ -18,18 +18,30 @@ package org.apache.portals.applications.
import java.io.IOException;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import org.apache.commons.lang.StringUtils;
import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
import org.apache.portals.applications.webcontent2.proxy.ReverseProxyService;
import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
import org.apache.portals.bridges.velocity.GenericVelocityPortlet;
+/**
+ * Generic reverse proxy portlet invoking {@link ReverseProxyService} injected.
+ */
public class GenericReverseProxyPortlet extends GenericVelocityPortlet
{
+ public static final String REMOTE_URI_PARAM_NAME = "remote.uri";
+
private ReverseProxyService proxyService;
public GenericReverseProxyPortlet()
@@ -51,11 +63,33 @@ public class GenericReverseProxyPortlet
public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException
{
response.setContentType("text/html");
+ invokeProxyService(request, response);
+ }
+
+ @Override
+ public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException
+ {
+ invokeProxyService(request, response);
+ }
+
+ @Override
+ public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException
+ {
+ String param = StringUtils.trim(request.getParameter(REMOTE_URI_PARAM_NAME));
+
+ if (StringUtils.isNotEmpty(param))
+ {
+ response.setRenderParameter(REMOTE_URI_PARAM_NAME, param);
+ }
+ }
+ protected void invokeProxyService(PortletRequest request, PortletResponse response) throws PortletException, IOException
+ {
try
{
PortletRequestContext requestContext = new PortletRequestContext(request, response);
ProxyContext proxyContext = new ProxyContext(requestContext);
+ ProxyContext.setCurrentProxyContext(proxyContext);
getProxyService().invoke(proxyContext);
}
catch (ReverseProxyException e)
@@ -77,5 +111,9 @@ public class GenericReverseProxyPortlet
{
throw new PortletException(e);
}
+ finally
+ {
+ ProxyContext.removeCurrentProxyContext();
+ }
}
}
Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletAnyProxyMapping.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletAnyProxyMapping.java?rev=1621242&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletAnyProxyMapping.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/PortletAnyProxyMapping.java Fri Aug 29 03:16:08 2014
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent2.portlet.proxy;
+
+import java.net.URI;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyMapping;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+
+public class PortletAnyProxyMapping extends AbstractProxyMapping
+{
+
+ private PortletConfig portletConfig;
+
+ public PortletAnyProxyMapping(PortletConfig portletConfig)
+ {
+ this.portletConfig = portletConfig;
+ }
+
+ public boolean matchesLocal(String localPath)
+ {
+ return true;
+ }
+
+ public String resolveRemoteFromLocal(String localPath)
+ {
+ return getCurrentRemoteURI();
+ }
+
+ public boolean matchesRemote(URI remoteURI)
+ {
+ return true;
+ }
+
+ public String resolveLocalFromRemote(URI remoteURI)
+ {
+ return "/";
+ }
+
+ protected PortletConfig getPortletConfig()
+ {
+ return portletConfig;
+ }
+
+ protected String getCurrentRemoteURI()
+ {
+ ProxyContext proxyContext = ProxyContext.getCurrentProxyContext();
+ PortletRequestContext prc = (PortletRequestContext) proxyContext.getRequestContext();
+ PortletRequest request = prc.getPortletRequest();
+ String remoteURI = request.getParameter(GenericReverseProxyPortlet.REMOTE_URI_PARAM_NAME);
+
+ if (StringUtils.isBlank(remoteURI))
+ {
+ remoteURI = request.getPreferences().getValue(GenericReverseProxyPortlet.REMOTE_URI_PARAM_NAME, null);
+ }
+
+ if (StringUtils.isBlank(remoteURI))
+ {
+ remoteURI = getPortletConfig().getInitParameter(GenericReverseProxyPortlet.REMOTE_URI_PARAM_NAME);
+ }
+
+ return remoteURI;
+ }
+}
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=1621242&r1=1621241&r2=1621242&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 Fri Aug 29 03:16:08 2014
@@ -48,6 +48,16 @@ public class PortletRequestContext imple
this.response = response;
}
+ public PortletRequest getPortletRequest()
+ {
+ return request;
+ }
+
+ public PortletResponse getPortletResponse()
+ {
+ return response;
+ }
+
public boolean isSecure()
{
return request.isSecure();
@@ -75,12 +85,12 @@ public class PortletRequestContext imple
public String getRequestBasePath()
{
- return null;
+ return "";
}
public String getPathInfo()
{
- return null;
+ return "/";
}
public Object getAttribute(String name)
@@ -170,7 +180,7 @@ public class PortletRequestContext imple
{
if (sink == null)
{
- if (!(response instanceof MimeResponseSink))
+ if (!(response instanceof MimeResponse))
{
throw new IllegalStateException("MimeResponse is required to create a sink.");
}
Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java Fri Aug 29 03:16:08 2014
@@ -16,23 +16,36 @@
*/
package org.apache.portals.applications.webcontent2.portlet.proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
+import org.apache.portals.applications.webcontent2.proxy.ProxyMapping;
import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
import org.apache.portals.applications.webcontent2.proxy.builder.ProxyServices;
import org.apache.portals.applications.webcontent2.proxy.impl.DefaultProxyMappingRegistry;
import org.apache.portals.applications.webcontent2.proxy.impl.DefaultReverseProxyService;
import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
import org.apache.portals.applications.webcontent2.proxy.util.ProxyCommandUtils;
-import org.apache.portals.applications.webcontent2.proxy.util.YamlConfigUtils;
+import org.apache.portals.applications.webcontent2.rewriter.ContentRewriter;
+import org.apache.portals.applications.webcontent2.rewriter.htmlcleaner.DefaultSerializerFactory;
+import org.apache.portals.applications.webcontent2.rewriter.htmlcleaner.HtmlCleanerContentRewriter;
+import org.htmlcleaner.SimpleHtmlSerializer;
+import org.htmlcleaner.TagNodeVisitor;
public class SimpleReverseProxyPortlet extends GenericReverseProxyPortlet
{
- public static final String MAPPINGS_PARAM_NAME = "mappings";
+ private static final String CONTENT_SELECTOR_PARAM_NAME = "content.selector";
+ private static final String HTML_CLEANER_TRANSFORMATION_PARAM_NAME = "html.cleaner.transformation";
private ProxyMappingRegistry proxyMappingRegistry;
private HttpClientBuilder httpClientBuilder;
@@ -60,8 +73,7 @@ public class SimpleReverseProxyPortlet e
if (proxyMappingRegistry == null)
{
proxyMappingRegistry = new DefaultProxyMappingRegistry();
- final String param = getPortletConfig().getInitParameter(MAPPINGS_PARAM_NAME);
- proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getPortletContext()));
+ proxyMappingRegistry.addProxyMapping(getProxyMapping());
}
return proxyMappingRegistry;
@@ -93,4 +105,83 @@ public class SimpleReverseProxyPortlet e
ProxyCommandUtils.destroyAllCommands(proxyServiceCommand);
super.destroy();
}
+
+ protected ProxyMapping getProxyMapping()
+ {
+ PortletAnyProxyMapping portletAnyProxyMapping = new PortletAnyProxyMapping(getPortletConfig());
+ portletAnyProxyMapping.setContentRewriters(getContentRewriters());
+ return portletAnyProxyMapping;
+ }
+
+ protected Map<String, ContentRewriter> getContentRewriters()
+ {
+ Map<String, ContentRewriter> contentRewriters = new HashMap<String, ContentRewriter>();
+
+ DefaultSerializerFactory serializerFactory = new DefaultSerializerFactory();
+ serializerFactory.setSerializerClass(SimpleHtmlSerializer.class);
+
+ HtmlCleanerContentRewriter contentRewriter = new HtmlCleanerContentRewriter();
+ contentRewriter.setSerializerFactory(serializerFactory);
+ contentRewriter.setContentSelector(getContentSelector());
+ contentRewriter.setInnerHtmlOnly(true);
+
+ String [] cleanerTransformations = getCleanerTransformationStringArray();
+
+ if (!ArrayUtils.isEmpty(cleanerTransformations))
+ {
+ contentRewriter.setCleanerTransformationStringArray(cleanerTransformations);
+ }
+
+ List<TagNodeVisitor> tagNodeVisitors = getTagNodeVisitors();
+
+ if (!tagNodeVisitors.isEmpty())
+ {
+ for (TagNodeVisitor visitor : tagNodeVisitors)
+ {
+ contentRewriter.addTagNodeVisitor(visitor);
+ }
+ }
+
+ contentRewriters.put("text/html",contentRewriter);
+
+ return contentRewriters;
+ }
+
+ protected String getContentSelector()
+ {
+ String selector = getPortletConfig().getInitParameter(CONTENT_SELECTOR_PARAM_NAME);
+
+ if (selector == null || StringUtils.isBlank(selector))
+ {
+ return "body";
+ }
+
+ return selector;
+ }
+
+ protected String [] getCleanerTransformationStringArray()
+ {
+ String param = getPortletConfig().getInitParameter(HTML_CLEANER_TRANSFORMATION_PARAM_NAME);
+
+ if (param == null || StringUtils.isBlank(param))
+ {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+
+ String [] tokens = StringUtils.split(param, "|");
+
+ for (int i = 0; i < tokens.length; i++)
+ {
+ tokens[i] = StringUtils.trim(tokens[i]);
+ }
+
+ return tokens;
+ }
+
+ protected List<TagNodeVisitor> getTagNodeVisitors()
+ {
+ List<TagNodeVisitor> visitors = new ArrayList<TagNodeVisitor>();
+ visitors.add(new DefaultPortletProxyTagNodeVisitor());
+ return visitors;
+ }
}
Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyContext.java?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyContext.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ProxyContext.java Fri Aug 29 03:16:08 2014
@@ -36,6 +36,23 @@ public class ProxyContext extends Contex
private static final long serialVersionUID = 1L;
+ private static ThreadLocal<ProxyContext> tlProxyContext = new ThreadLocal<ProxyContext>();
+
+ public static ProxyContext getCurrentProxyContext()
+ {
+ return tlProxyContext.get();
+ }
+
+ public static void setCurrentProxyContext(ProxyContext proxyContext)
+ {
+ tlProxyContext.set(proxyContext);
+ }
+
+ public static void removeCurrentProxyContext()
+ {
+ tlProxyContext.remove();
+ }
+
private final RequestContext requestContext;
private ProxyMappingRegistry proxyMappingRegistry;
private ProxyMapping resolvedMapping;
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=1621242&r1=1621241&r2=1621242&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 Fri Aug 29 03:16:08 2014
@@ -42,6 +42,16 @@ public class ServletRequestContext imple
this.response = response;
}
+ public HttpServletRequest getServletRequest()
+ {
+ return request;
+ }
+
+ public HttpServletResponse getServletResponse()
+ {
+ return response;
+ }
+
public boolean isSecure()
{
return request.isSecure();
Modified: portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/portlet.xml
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/portlet.xml?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/portlet.xml (original)
+++ portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/portlet.xml Fri Aug 29 03:16:08 2014
@@ -18,11 +18,13 @@
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
-
+
<portlet>
- <description>Places an HTML IFrame inside a portlet for easily
+ <description>
+ Places an HTML IFrame inside a portlet for easily
hosting other web application within a portlet. Sizes of both
- normal and maximized modes are configurable in edit mode.</description>
+ normal and maximized modes are configurable in edit mode.
+ </description>
<portlet-name>IFramePortlet2</portlet-name>
<display-name>IFrame Portlet 2</display-name>
<portlet-class>
@@ -102,11 +104,13 @@
</preference>
</portlet-preferences>
</portlet>
-
+
<portlet>
- <description>Places an HTML IFrame with reverse proxied url inside a portlet for easily
+ <description>
+ Places an HTML IFrame with reverse proxied url inside a portlet for easily
hosting other web application within a portlet. Sizes of both
- normal and maximized modes are configurable in edit mode.</description>
+ normal and maximized modes are configurable in edit mode.
+ </description>
<portlet-name>ReverseProxyIFramePortlet2</portlet-name>
<display-name>ReverseProxy IFrame Portlet2</display-name>
<portlet-class>
@@ -195,12 +199,15 @@
</preference>
</portlet-preferences>
</portlet>
-
+
<portlet>
- <description>Includes the content of another website inside the portal without using frames. All links are rewritten back to the portal to attempt to proxy all content through the portal.</description>
+ <description>
+ Includes the content of another website inside the portal without using frames.
+ All links are rewritten back to the portal to attempt to proxy all content through the portal.
+ </description>
<portlet-name>WebContentPortlet2</portlet-name>
<display-name>WebContent Portlet2</display-name>
- <portlet-class>org.apache.portals.applications.webcontent2.portlet.WebContentPortlet</portlet-class>
+ <portlet-class>org.apache.portals.applications.webcontent2.portlet.WebContentPortlet</portlet-class>
<init-param>
<name>EditPage</name>
<value>/WEB-INF/view/edit-wcprefs.vm</value>
@@ -215,7 +222,7 @@
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>VIEW</portlet-mode>
</supports>
- <supported-locale>en</supported-locale>
+ <supported-locale>en</supported-locale>
<portlet-info>
<title>WebContent Prototype 2</title>
<short-title>WebContent2</short-title>
@@ -234,9 +241,45 @@
<name>PROXYPORT</name>
<value></value>
</preference>
- </portlet-preferences>
+ </portlet-preferences>
</portlet>
-
+
+ <portlet>
+ <description>
+ Includes the content of another website inside the portal without using frames.
+ All links are rewritten back to the portal to attempt to proxy all content through the portal.
+ </description>
+ <portlet-name>SimpleReverseProxyPortlet</portlet-name>
+ <display-name>Simple Reverse Proxy Portlet</display-name>
+ <portlet-class>org.apache.portals.applications.webcontent2.portlet.proxy.SimpleReverseProxyPortlet</portlet-class>
+ <init-param>
+ <name>portlet-icon</name>
+ <value>preferences-system-network-proxy.png</value>
+ </init-param>
+ <init-param>
+ <name>content.selector</name>
+ <value>div[id=bodyColumn]</value>
+ </init-param>
+ <expiration-cache>0</expiration-cache>
+ <supports>
+ <mime-type>text/html</mime-type>
+ <portlet-mode>EDIT</portlet-mode>
+ <portlet-mode>VIEW</portlet-mode>
+ </supports>
+ <supported-locale>en</supported-locale>
+ <portlet-info>
+ <title>Simple Reverse Proxy Portlet</title>
+ <short-title>Simple Reverse Proxy Portlet</short-title>
+ <keywords>web,content,webnav,bridge,proxy,rewrite</keywords>
+ </portlet-info>
+ <portlet-preferences>
+ <preference>
+ <name>remote.uri</name>
+ <value>http://portals.apache.org/news.html</value>
+ </preference>
+ </portlet-preferences>
+ </portlet>
+
<custom-portlet-mode>
<description>Custom About Mode</description>
<portlet-mode>about</portlet-mode>
@@ -257,6 +300,6 @@
<description>Custom Print Mode</description>
<portlet-mode>print</portlet-mode>
</custom-portlet-mode>
-
+
</portlet-app>
Modified: portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/psml/test-webcontent2.psml
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/psml/test-webcontent2.psml?rev=1621242&r1=1621241&r2=1621242&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/psml/test-webcontent2.psml (original)
+++ portals/applications/webcontent/trunk/war/src/main/webapp/WEB-INF/psml/test-webcontent2.psml Fri Aug 29 03:16:08 2014
@@ -29,13 +29,17 @@
<property name="row" value="1"></property>
<property name="column" value="0"></property>
</fragment>
- <fragment id="tw2-22" type="portlet" name="webcontent2::IFramePortlet2">
+ <fragment id="tw2-31" type="portlet" name="webcontent2::IFramePortlet2">
<property name="row" value="2"></property>
<property name="column" value="0"></property>
<preference name="SRC" readOnly="false">
<value>http://www.apache.org/</value>
</preference>
</fragment>
+ <fragment id="tw2-41" type="portlet" name="webcontent2::SimpleReverseProxyPortlet">
+ <property name="row" value="3"></property>
+ <property name="column" value="0"></property>
+ </fragment>
</fragment>
<defaults></defaults>
</page>