WICKET-5827 Allow to apply multiple Javascript / CSS compressors

Re-implement CssUrlReplacer


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/08f8a556
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/08f8a556
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/08f8a556

Branch: refs/heads/master
Commit: 08f8a556722b8b803430194ab8e80d00199a5401
Parents: b87b459
Author: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Authored: Fri Feb 6 00:20:57 2015 +0200
Committer: Martin Tzvetanov Grigorov <mgrigo...@apache.org>
Committed: Fri Feb 6 00:20:57 2015 +0200

----------------------------------------------------------------------
 .../request/resource/CssPackageResource.java    | 17 +++-
 .../wicket/resource/CompositeCssCompressor.java | 22 ++++-
 .../apache/wicket/resource/CssUrlReplacer.java  | 94 +++++---------------
 .../IScopeAwareTextResourceProcessor.java       | 17 ++++
 .../wicket/resource/CssUrlReplacerTest.java     | 75 ++++++++++++++++
 5 files changed, 148 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/08f8a556/wicket-core/src/main/java/org/apache/wicket/request/resource/CssPackageResource.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/CssPackageResource.java
 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/CssPackageResource.java
index f6cf010..72e2dc1 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/request/resource/CssPackageResource.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/request/resource/CssPackageResource.java
@@ -20,6 +20,7 @@ import java.util.Locale;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.css.ICssCompressor;
+import org.apache.wicket.resource.IScopeAwareTextResourceProcessor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,6 +33,8 @@ public class CssPackageResource extends PackageResource
 
        private static final Logger log = 
LoggerFactory.getLogger(CssPackageResource.class);
 
+       private final String name;
+
        /**
         * Construct.
         * 
@@ -46,6 +49,8 @@ public class CssPackageResource extends PackageResource
        {
                super(scope, name, locale, style, variation);
 
+               this.name = name;
+
                // CSS resources can be compressed if there is configured 
ICssCompressor
                setCompress(true);
        }
@@ -62,7 +67,17 @@ public class CssPackageResource extends PackageResource
                        try
                        {
                                String nonCompressed = new 
String(processedResponse, "UTF-8");
-                               return 
compressor.compress(nonCompressed).getBytes();
+                               String output;
+                               if (compressor instanceof 
IScopeAwareTextResourceProcessor)
+                               {
+                                       IScopeAwareTextResourceProcessor 
scopeAwareProcessor = (IScopeAwareTextResourceProcessor) compressor;
+                                       output = 
scopeAwareProcessor.process(nonCompressed, getScope(), name);
+                               }
+                               else
+                               {
+                                       output = 
compressor.compress(nonCompressed);
+                               }
+                               return output.getBytes();
                        }
                        catch (Exception e)
                        {

http://git-wip-us.apache.org/repos/asf/wicket/blob/08f8a556/wicket-core/src/main/java/org/apache/wicket/resource/CompositeCssCompressor.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/CompositeCssCompressor.java
 
b/wicket-core/src/main/java/org/apache/wicket/resource/CompositeCssCompressor.java
index 6756491..f23c937 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/resource/CompositeCssCompressor.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/resource/CompositeCssCompressor.java
@@ -41,7 +41,7 @@ import org.apache.wicket.css.ICssCompressor;
  * @author Tobias Soloschenko
  * 
  */
-public class CompositeCssCompressor implements ICssCompressor
+public class CompositeCssCompressor implements IScopeAwareTextResourceProcessor
 {
        /* Compressors to compress the CSS content */
        private final List<ICssCompressor> compressors = new ArrayList<>();
@@ -62,16 +62,30 @@ public class CompositeCssCompressor implements 
ICssCompressor
         * given the original content is going to be returned.
         */
        @Override
-       public String compress(String original)
+       public String process(String input, Class<?> scope, String name)
        {
-               String compressed = original;
+               String compressed = input;
                for (ICssCompressor compressor : compressors)
                {
-                       compressed = compressor.compress(compressed);
+                       if (compressor instanceof 
IScopeAwareTextResourceProcessor)
+                       {
+                               IScopeAwareTextResourceProcessor processor = 
(IScopeAwareTextResourceProcessor) compressor;
+                               processor.process(compressed, scope, name);
+                       }
+                       else
+                       {
+                               compressed = compressor.compress(compressed);
+                       }
                }
                return compressed;
        }
 
+       @Override
+       public String compress(String original)
+       {
+               throw new 
UnsupportedOperationException(CompositeCssCompressor.class.getSimpleName() + 
".process() should be used instead!");
+       }
+
        /**
         * Adds a ICssCompressor to the list of delegates.
         *

http://git-wip-us.apache.org/repos/asf/wicket/blob/08f8a556/wicket-core/src/main/java/org/apache/wicket/resource/CssUrlReplacer.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/CssUrlReplacer.java 
b/wicket-core/src/main/java/org/apache/wicket/resource/CssUrlReplacer.java
index 7c7864e..985c275 100644
--- a/wicket-core/src/main/java/org/apache/wicket/resource/CssUrlReplacer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/resource/CssUrlReplacer.java
@@ -16,20 +16,10 @@
  */
 package org.apache.wicket.resource;
 
-import java.net.URL;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.wicket.Application;
-import org.apache.wicket.Component;
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.application.IComponentInitializationListener;
-import org.apache.wicket.core.util.lang.WicketObjects;
-import org.apache.wicket.css.ICssCompressor;
+import org.apache.wicket.request.Url;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.resource.PackageResourceReference;
 
@@ -46,78 +36,38 @@ import 
org.apache.wicket.request.resource.PackageResourceReference;
  * 
  * @since 6.20.0
  * @author Tobias Soloschenko
- * 
  */
-public class CssUrlReplacer implements ICssCompressor
+public class CssUrlReplacer implements IScopeAwareTextResourceProcessor
 {
-
-       // Holds the names of components
-       private final Map<String, String> componentNames = 
Collections.synchronizedMap(new LinkedHashMap<String, String>());
-
        // The pattern to find URLs in CSS resources
-       private static final Pattern urlPattern = 
Pattern.compile("url\\(['|\"]*(.*)['|\"]*\\)");
-
-       public CssUrlReplacer(Application application)
-       {
-
-               // Create an instantiation listener to detect components
-               application.getComponentInitializationListeners().add(
-                       new IComponentInitializationListener()
-                       {
-
-                               @Override
-                               public void onInitialize(Component component)
-                               {
-                                       
CssUrlReplacer.this.componentNames.put(component.getClass().getName(),
-                                               
component.getClass().getSimpleName());
-                               }
-                       });
-       }
+       private static final Pattern URL_PATTERN = 
Pattern.compile("url\\(['|\"]*(.*?)['|\"]*\\)");
 
        /**
         * Replaces the URLs of CSS resources with Wicket representatives.
         */
        @Override
-       public String compress(String original)
+       public String process(String input, Class<?> scope, String name)
        {
-               Matcher matcher = CssUrlReplacer.urlPattern.matcher(original);
-               // Search for urls
+               PackageResourceReference cssReference = new 
PackageResourceReference(scope, name);
+               CharSequence urlToCss = RequestCycle.get().urlFor(cssReference, 
null);
+               Url cssUrl = Url.parse(urlToCss);
+               Matcher matcher = URL_PATTERN.matcher(input);
+               StringBuffer output = new StringBuffer();
+
                while (matcher.find())
                {
-                       Collection<String> componentNames = 
this.componentNames.keySet();
-                       for (String componentName : componentNames)
-                       {
-                               try
-                               {
-                                       Class<?> componentClass = 
WicketObjects.resolveClass(componentName);
-                                       String url = matcher.group(1);
-                                       if (!url.contains("/"))
-                                       {
-                                               URL urlResource = 
componentClass.getResource(url);
-                                               // If the resource is not found 
skip it
-                                               if (urlResource != null)
-                                               {
-                                                       
PackageResourceReference packageResourceReference = new 
PackageResourceReference(
-                                                               componentClass, 
url);
-                                                       String replacedUrl = 
RequestCycle.get()
-                                                               
.urlFor(packageResourceReference, null)
-                                                               .toString();
-                                                       StringBuilder 
urlBuilder = new StringBuilder();
-                                                       
urlBuilder.append("url('");
-                                                       
urlBuilder.append(replacedUrl);
-                                                       urlBuilder.append("')");
-                                                       original = 
matcher.replaceFirst(urlBuilder.toString());
-                                               }
-                                       }
-                               }
-                               catch (Exception e)
-                               {
-                                       throw new WicketRuntimeException(
-                                               "A problem occurred during CSS 
url replacement.", e);
-                               }
-                       }
-
+                       Url imageRelativeUrl = Url.parse(matcher.group(1));
+                       Url cssUrlCopy = new Url(cssUrl);
+                       cssUrlCopy.resolveRelative(imageRelativeUrl);
+                       matcher.appendReplacement(output, "url('" + 
cssUrlCopy.toString() + "')");
                }
-               return original;
+               matcher.appendTail(output);
+               return output.toString();
+       }
+
+       @Override
+       public String compress(String original)
+       {
+               throw new 
UnsupportedOperationException(CssUrlReplacer.class.getSimpleName() + 
".process() should be used instead!");
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/08f8a556/wicket-core/src/main/java/org/apache/wicket/resource/IScopeAwareTextResourceProcessor.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/resource/IScopeAwareTextResourceProcessor.java
 
b/wicket-core/src/main/java/org/apache/wicket/resource/IScopeAwareTextResourceProcessor.java
new file mode 100644
index 0000000..2b37c27
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/resource/IScopeAwareTextResourceProcessor.java
@@ -0,0 +1,17 @@
+package org.apache.wicket.resource;
+
+/**
+ *
+ */
+public interface IScopeAwareTextResourceProcessor extends 
ITextResourceCompressor
+{
+       /**
+        * Processes/manipulates a text resource.
+        *
+        *
+        * @param input
+        * @param scope
+        * @return The processed input
+        */
+       public String process(String input, Class<?> scope, String name);
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/08f8a556/wicket-core/src/test/java/org/apache/wicket/resource/CssUrlReplacerTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/resource/CssUrlReplacerTest.java 
b/wicket-core/src/test/java/org/apache/wicket/resource/CssUrlReplacerTest.java
new file mode 100644
index 0000000..157bd60
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/resource/CssUrlReplacerTest.java
@@ -0,0 +1,75 @@
+package org.apache.wicket.resource;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+
+import org.apache.wicket.WicketTestCase;
+import org.junit.Test;
+
+public class CssUrlReplacerTest extends WicketTestCase
+{
+       @Test
+       public void sameFolderSingleQuotes()
+       {
+               String input = ".class {background-image: url('some.img');}";
+               Class<?> scope = CssUrlReplacerTest.class;
+               String cssRelativePath = "res/css/some.css";
+               CssUrlReplacer replacer = new CssUrlReplacer();
+
+               String processed = replacer.process(input, scope, 
cssRelativePath);
+               assertThat(processed, is(".class {background-image: 
url('./wicket/resource/org.apache.wicket.resource.CssUrlReplacerTest/res/css/some.img');}"));
+       }
+
+       @Test
+       public void sameFolderDoubleQuotes()
+       {
+               String input = ".class {background-image: url(\"some.img\");}";
+               Class<?> scope = CssUrlReplacerTest.class;
+               String cssRelativePath = "res/css/some.css";
+               CssUrlReplacer replacer = new CssUrlReplacer();
+
+               String processed = replacer.process(input, scope, 
cssRelativePath);
+               assertThat(processed, is(".class {background-image: 
url('./wicket/resource/org.apache.wicket.resource.CssUrlReplacerTest/res/css/some.img');}"));
+       }
+
+       @Test
+       public void parentFolderAppendFolder()
+       {
+               String input = ".class {background-image: 
url('../images/some.img');}";
+               Class<?> scope = CssUrlReplacerTest.class;
+               String cssRelativePath = "res/css/some.css";
+               CssUrlReplacer replacer = new CssUrlReplacer();
+
+               String processed = replacer.process(input, scope, 
cssRelativePath);
+               assertThat(processed, is(".class {background-image: 
url('./wicket/resource/org.apache.wicket.resource.CssUrlReplacerTest/res/images/some.img');}"));
+       }
+
+       @Test
+       public void sameFolderAppendFolder()
+       {
+               String input = ".class {background-image: 
url('./images/some.img');}";
+               Class<?> scope = CssUrlReplacerTest.class;
+               String cssRelativePath = "res/css/some.css";
+               CssUrlReplacer replacer = new CssUrlReplacer();
+
+               String processed = replacer.process(input, scope, 
cssRelativePath);
+               assertThat(processed, is(".class {background-image: 
url('./wicket/resource/org.apache.wicket.resource.CssUrlReplacerTest/res/css/images/some.img');}"));
+       }
+
+       @Test
+       public void severalUrls()
+       {
+               String input =
+                               ".class {\n" +
+                                       "a: url('../images/a.img');\n" +
+                                       "b: url('./b.img');\n" +
+                               "}";
+               Class<?> scope = CssUrlReplacerTest.class;
+               String cssRelativePath = "res/css/some.css";
+               CssUrlReplacer replacer = new CssUrlReplacer();
+
+               String processed = replacer.process(input, scope, 
cssRelativePath);
+               assertThat(processed, 
containsString("CssUrlReplacerTest/res/images/a.img');"));
+               assertThat(processed, 
containsString("CssUrlReplacerTest/res/css/b.img');"));
+       }
+}

Reply via email to