Author: woonsan
Date: Fri Sep 16 16:07:53 2011
New Revision: 1171639

URL: http://svn.apache.org/viewvc?rev=1171639&view=rev
Log:
APA-38: Enabling to rewrite stylesheet imports (@import url(...))

Modified:
    
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
    
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java

Modified: 
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
URL: 
http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java?rev=1171639&r1=1171638&r2=1171639&view=diff
==============================================================================
--- 
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
 (original)
+++ 
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
 Fri Sep 16 16:07:53 2011
@@ -47,6 +47,15 @@ public class DefaultReverseProxyLinkRewr
     protected static final Pattern HTTP_DOMAIN_ADDRESS_ONLY_PATTERN = 
         Pattern.compile("^https?:\\/\\/[^\\/]+$", Pattern.CASE_INSENSITIVE);
     
+    protected static final Pattern IMPORT_URL_PATTERN =
+        Pattern.compile("(\\s|^)(url)\\s*\\(", Pattern.CASE_INSENSITIVE);
+    
+    protected static final Pattern IMPORT_URL_PATH_PATTERN = 
+        
Pattern.compile("(\\s|^)(url)\\s*\\(\\s*(['\"])((\\/)[^'\"]*)['\"]\\)", 
Pattern.CASE_INSENSITIVE);
+    
+    protected static final Pattern IMPORT_URL_ABS_URL_PATTERN = 
+        
Pattern.compile("(\\s|^)(url)\\s*\\(\\s*(['\"])(https?:\\/\\/[^'\"]+)['\"]\\)", 
Pattern.CASE_INSENSITIVE);
+    
     protected boolean lookUpAllMappings;
     
     protected String localPathMatchingReplaces;
@@ -57,10 +66,11 @@ public class DefaultReverseProxyLinkRewr
     private Pattern defaultRemoteURLPattern;
     private String defaultRemoteURLReplaces;
     
-    private Set<String> blacklist;
+    private Set<String> blacklist = new HashSet<String>();
     
-    private Map<HttpReverseProxyPathMapper, Pattern> 
remoteURLMatchingPatternMap;
-    private Map<HttpReverseProxyPathMapper, String> 
localPathMatchingReplacesMap;
+    private Map<HttpReverseProxyPathMapper, Pattern> 
remoteURLMatchingPatternMap = new HashMap<HttpReverseProxyPathMapper, 
Pattern>();
+    private Map<HttpReverseProxyPathMapper, Pattern> 
remoteImportURLMatchingPatternMap = new HashMap<HttpReverseProxyPathMapper, 
Pattern>();
+    private Map<HttpReverseProxyPathMapper, String> 
localPathMatchingReplacesMap = new HashMap<HttpReverseProxyPathMapper, 
String>();
     
     private Pattern [] customPatterns;
     private String [] customReplaces;
@@ -115,6 +125,101 @@ public class DefaultReverseProxyLinkRewr
             defaultRemoteURLReplaces = 
createLocalPathMatchingReplaces(getHttpReverseProxyPathMapper());
         }
         
+        if (IMPORT_URL_PATTERN.matcher(line).find()) {
+            line = rewriteImportURLs(line);
+        }
+        
+        return rewriteLinks(line);
+    }
+    
+    protected String rewriteImportURLs(String line) throws Exception
+    {
+        // first, replace slash leading relative paths by slash leading 
reverse proxying relative paths.
+        Matcher linkBasePathMatcher = IMPORT_URL_PATH_PATTERN.matcher(line);
+        line = linkBasePathMatcher.replaceAll("$1$2($3" + 
defaultRemoteURLReplaces + "$4$3)");
+        
+        // if there's any https? absolute url link, try to find the proxy path 
mapper again...
+        if (lookUpAllMappings)
+        {
+            CharSequence segment = new CharArraySegment(line);
+            
+            for (Matcher absURLMatcher = 
IMPORT_URL_ABS_URL_PATTERN.matcher(segment); absURLMatcher.find(); )
+            {
+                HttpReverseProxyPathMapper proxyMapper = null;
+                String absURL = absURLMatcher.group(4);
+                int maxMatchingPathPartCount = getMaxMatchingPathPartCount();
+                String [] pathParts = StringUtils.split(absURL, "/", 
maxMatchingPathPartCount + 2);
+                int pathPartCount = (pathParts != null ? pathParts.length : 0);
+                
+                if (pathPartCount < 2)
+                {
+                    continue;
+                }
+                
+                String scheme = pathParts[0];
+                
+                for (int i = Math.min(pathPartCount, maxMatchingPathPartCount 
+ 1); i > 1; i--)
+                {
+                    String remoteBaseURLKey = scheme + "//" + 
StringUtils.join(pathParts, "/", 1, i);
+                    
+                    if (blacklist != null && 
blacklist.contains(remoteBaseURLKey))
+                    {
+                        continue;
+                    }
+
+                    proxyMapper = 
getHttpReverseProxyPathMapperProvider().findMapperByRemoteURL(remoteBaseURLKey 
+ "/");
+                    
+                    if (proxyMapper == null)
+                    {
+                        blacklist.add(remoteBaseURLKey);
+                    }
+                    else
+                    {
+                        Pattern pattern = 
remoteImportURLMatchingPatternMap.get(proxyMapper);
+                        if (pattern == null)
+                        {
+                            pattern = 
createRemoteImportURLMatchingPattern(proxyMapper);
+                            remoteImportURLMatchingPatternMap.put(proxyMapper, 
pattern);
+                        }
+                        
+                        String replaces = 
localPathMatchingReplacesMap.get(proxyMapper);
+                        if (replaces == null)
+                        {
+                            replaces = 
createLocalPathMatchingReplaces(proxyMapper);
+                            localPathMatchingReplacesMap.put(proxyMapper, 
replaces);
+                        }
+                        
+                        Matcher matcher = pattern.matcher(line);
+                        line = replaceRemoteImportLinkValues(matcher, 
"$1$2($3" + replaces + "$6$3)", line);
+                        
+                        break;
+                    }
+                }
+                
+                segment = segment.subSequence(absURLMatcher.end(), 
segment.length());
+                absURLMatcher.reset(segment);
+            }
+        }
+        else
+        {
+            Matcher matcher = defaultRemoteURLPattern.matcher(line);
+            line = matcher.replaceAll("$1$2($3" + defaultRemoteURLReplaces + 
"$6$3)");
+        }
+        
+        if (customPatterns != null)
+        {
+            for (int i = 0; i < customPatterns.length; i++)
+            {
+                Matcher matcher = customPatterns[i].matcher(line);
+                line = matcher.replaceAll(customReplaces[i]);
+            }
+        }
+        
+        return line;
+    }
+    
+    protected String rewriteLinks(String line) throws Exception
+    {
         // first, replace slash leading relative paths by slash leading 
reverse proxying relative paths.
         Matcher linkBasePathMatcher = LINK_ABS_PATH_PATTERN.matcher(line);
         line = linkBasePathMatcher.replaceAll("$1$2=$3" + 
defaultRemoteURLReplaces + "$4$3");
@@ -152,21 +257,10 @@ public class DefaultReverseProxyLinkRewr
                     
                     if (proxyMapper == null)
                     {
-                        if (blacklist == null)
-                        {
-                            blacklist = new HashSet<String>();
-                        }
-                        
                         blacklist.add(remoteBaseURLKey);
                     }
                     else
                     {
-                        if (remoteURLMatchingPatternMap == null)
-                        {
-                            remoteURLMatchingPatternMap = new 
HashMap<HttpReverseProxyPathMapper, Pattern>();
-                            localPathMatchingReplacesMap = new 
HashMap<HttpReverseProxyPathMapper, String>();
-                        }
-                        
                         Pattern pattern = 
remoteURLMatchingPatternMap.get(proxyMapper);
                         if (pattern == null)
                         {
@@ -174,15 +268,15 @@ public class DefaultReverseProxyLinkRewr
                             remoteURLMatchingPatternMap.put(proxyMapper, 
pattern);
                         }
                         
-                        String localPathMatchingReplaces = 
localPathMatchingReplacesMap.get(proxyMapper);
-                        if (localPathMatchingReplaces == null)
+                        String replaces = 
localPathMatchingReplacesMap.get(proxyMapper);
+                        if (replaces == null)
                         {
-                            localPathMatchingReplaces = 
createLocalPathMatchingReplaces(proxyMapper);
-                            localPathMatchingReplacesMap.put(proxyMapper, 
localPathMatchingReplaces);
+                            replaces = 
createLocalPathMatchingReplaces(proxyMapper);
+                            localPathMatchingReplacesMap.put(proxyMapper, 
replaces);
                         }
                         
                         Matcher matcher = pattern.matcher(line);
-                        line = replaceRemoteLinkValues(matcher, "$1$2=$3" + 
localPathMatchingReplaces + "$6$3", line);
+                        line = replaceRemoteLinkValues(matcher, "$1$2=$3" + 
replaces + "$6$3", line);
                         
                         break;
                     }
@@ -216,6 +310,12 @@ public class DefaultReverseProxyLinkRewr
         return Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*(['\"])((" + 
remoteBaseURLPattern + ")([^'\"]*))['\"]", Pattern.CASE_INSENSITIVE);
     }
     
+    protected Pattern 
createRemoteImportURLMatchingPattern(HttpReverseProxyPathMapper proxyMapper)
+    {
+        String remoteBaseURLPattern = 
StringUtils.replaceEach(StringUtils.removeEnd(proxyMapper.getRemoteBaseURL(), 
"/"), linkRemoteBaseURLSearches, linkRemoteBaseURLReplaces);
+        return Pattern.compile("(\\s|^)(url)\\s*\\(\\s*(['\"])((" + 
remoteBaseURLPattern + ")([^'\"]*))['\"]\\)", Pattern.CASE_INSENSITIVE);
+    }
+    
     protected String 
createLocalPathMatchingReplaces(HttpReverseProxyPathMapper proxyMapper)
     {
         return getRewritingContextPath() + 
StringUtils.removeEnd(proxyMapper.getLocalBasePath(), "/");
@@ -257,4 +357,38 @@ public class DefaultReverseProxyLinkRewr
         return text;
     }
     
+    protected String replaceRemoteImportLinkValues(Matcher matcher, String 
replacement, String text)
+    {
+        matcher.reset();
+        boolean result = matcher.find();
+        
+        if (result) 
+        {
+            StringBuffer sb = new StringBuffer();
+            
+            do 
+            {
+                // if the url is comopsed of scheme and domain name such as 
"http://projects.apache.org";,
+                // then the local path info should be appended by '/' like 
"/webcontent/rproxy/project_apache/".
+                if 
(HTTP_DOMAIN_ADDRESS_ONLY_PATTERN.matcher(matcher.group(4)).matches())
+                {
+                    int offset = replacement.lastIndexOf("$3");
+                    matcher.appendReplacement(sb, replacement.substring(0, 
offset) + "/" + replacement.substring(offset));
+                }
+                else
+                {
+                    matcher.appendReplacement(sb, replacement);
+                }
+                
+                result = matcher.find();
+            }
+            while (result);
+            
+            matcher.appendTail(sb);
+            
+            return sb.toString();
+        }
+        
+        return text;
+    }
 }

Modified: 
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java
URL: 
http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java?rev=1171639&r1=1171638&r2=1171639&view=diff
==============================================================================
--- 
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java
 (original)
+++ 
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java
 Fri Sep 16 16:07:53 2011
@@ -49,6 +49,15 @@ public class TestReverseProxyLinkRewriti
     
     private String html =
         "<html>\n" +
+        "<head>\n" +
+        "<link type=\"text/css\" rel=\"stylesheet\" 
href=\"/skin/css/screen1.css\" media=\"all\">\n" +
+        "<link type=\"text/css\" rel=\"stylesheet\" 
href=\"http://portals.apache.org/skin/css/screen2.css\"; media=\"all\">\n" +
+        "<style>\n" +
+        "@import url(\"/skin/css/import1.css\");\n" +
+        "@import url(\"http://portals.apache.org/skin/css/import2.css\";);\n" +
+        "</style>\n" +
+        "</head>\n" +
+        "<body>\n" +
         "<p><a href=\"mission.html\">Mission</a> and <a 
href='about.html'>About</a></p>\n" +
         "<p><a href=\"/docs/\">Docs</a> and <a 
href='/documents/'>Documents</a></p>\n" +
         "<p><a href=\"http://projects.apache.org\"; title=\"Apache 
Projects\">Projects</a> <a 
href=\"http://portals.apache.org/apa.html\";>Applications</a></p>\n" +
@@ -61,6 +70,7 @@ public class TestReverseProxyLinkRewriti
         "<p><a href=\"https://blogs.apache.org/index.html\";>Apache 
Blogs</a></p>\n" +
         "<p><a href=\"http://apache.org/index.html\";>Apache Software 
Foundation</a></p>\n" +
         "<script>new AjaxUpdate('/lazyLoader');</script>\n" +
+        "</body>\n" +
         "</html>";
     
     private HttpReverseProxyPathMapperProvider proxyPathMapperProvider;
@@ -113,21 +123,43 @@ public class TestReverseProxyLinkRewriti
         
         List<String> lines = (List<String>) IOUtils.readLines(new 
StringReader(writer.toString()));
         
-        assertTrue("Wrong rewriting: " + lines.get(1), 
StringUtils.contains(lines.get(1), "href=\"mission.html\""));
-        assertTrue("Wrong rewriting: " + lines.get(1), 
StringUtils.contains(lines.get(1), "href='about.html'"));
-        assertTrue("Wrong rewriting: " + lines.get(2), 
StringUtils.contains(lines.get(2), 
"href=\"/webcontent/rproxy/www_apache/docs/\""));
-        assertTrue("Wrong rewriting: " + lines.get(2), 
StringUtils.contains(lines.get(2), 
"href='/webcontent/rproxy/www_apache/documents/'"));
-        assertTrue("Wrong rewriting: " + lines.get(3), 
StringUtils.contains(lines.get(3), 
"href=\"/webcontent/rproxy/projects_apache/\""));
-        assertTrue("Wrong rewriting: " + lines.get(3), 
StringUtils.contains(lines.get(3), 
"href=\"/webcontent/rproxy/portals_apache/apa.html\""));
-        assertTrue("Wrong rewriting: " + lines.get(4), 
StringUtils.contains(lines.get(4), 
"href=\"/webcontent/rproxy/www_apache/events.html\""));
-        assertTrue("Wrong rewriting: " + lines.get(4), 
StringUtils.contains(lines.get(4), 
"href='/webcontent/rproxy/www_apache/apachecon.html'"));
-        assertTrue("Wrong rewriting: " + lines.get(5), 
StringUtils.contains(lines.get(5), 
"href=\"/webcontent/rproxy/localhost/manager/list\""));
-        assertTrue("Wrong rewriting: " + lines.get(5), 
StringUtils.contains(lines.get(5), 
"href='/webcontent/rproxy/localhost/manager/start'"));
-        assertTrue("Wrong rewriting: " + lines.get(7), 
StringUtils.contains(lines.get(7), 
"href=\"/webcontent/rproxy/www_apache/docs/\""));
-        assertTrue("Wrong rewriting: " + lines.get(9), 
StringUtils.contains(lines.get(9), 
"href=\"/webcontent/rproxy/localhost/manager/list\""));
-        assertTrue("Wrong rewriting: " + lines.get(10), 
StringUtils.contains(lines.get(10), 
"href=\"/webcontent/rproxy/secure/blogs_apache/index.html\""));
-        assertTrue("Wrong rewriting: " + lines.get(11), 
StringUtils.contains(lines.get(11), 
"href=\"/webcontent/rproxy/apache/index.html\""));
-        assertTrue("Wrong rewriting: " + lines.get(12), 
StringUtils.contains(lines.get(12), "new AjaxUpdate('/busyLoader');"));
+        int lineNum = 0;
+        
+        lineNum += 2;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/www_apache/skin/css/screen1.css\""));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/portals_apache/skin/css/screen2.css\""));
+        
+        lineNum += 2;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"url(\"/webcontent/rproxy/www_apache/skin/css/import1.css\")"));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"url(\"/webcontent/rproxy/portals_apache/skin/css/import2.css\")"));
+        
+        lineNum += 4;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), "href=\"mission.html\""));
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), "href='about.html'"));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/www_apache/docs/\""));
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href='/webcontent/rproxy/www_apache/documents/'"));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/projects_apache/\""));
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/portals_apache/apa.html\""));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/www_apache/events.html\""));
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href='/webcontent/rproxy/www_apache/apachecon.html'"));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/localhost/manager/list\""));
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href='/webcontent/rproxy/localhost/manager/start'"));
+        lineNum += 2;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/www_apache/docs/\""));
+        lineNum += 2;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/localhost/manager/list\""));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/secure/blogs_apache/index.html\""));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), 
"href=\"/webcontent/rproxy/apache/index.html\""));
+        lineNum += 1;
+        assertTrue("Wrong rewriting: " + lines.get(lineNum), 
StringUtils.contains(lines.get(lineNum), "new AjaxUpdate('/busyLoader');"));
     }
     
 }


Reply via email to