You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by be...@apache.org on 2021/02/12 16:34:21 UTC

[tapestry-5] branch master updated: TAP5-2661: GoogleClosureMinimizerOptionsProvider added

This is an automated email from the ASF dual-hosted git repository.

benw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git


The following commit(s) were added to refs/heads/master by this push:
     new d8c550f  TAP5-2661: GoogleClosureMinimizerOptionsProvider added
d8c550f is described below

commit d8c550fa04c38b2f2fb6923e9aceab7f18946c75
Author: Benjamin Weidig <be...@netzgut.net>
AuthorDate: Fri Feb 12 17:32:59 2021 +0100

    TAP5-2661: GoogleClosureMinimizerOptionsProvider added
    
    The Google Closure compiler was previously used with a fixed options. Due to JavaScript edge-cases this could lead to problems for some JS code.
    
    So far the only solutions were to either disable compression completely, or set the Request parameter "tapestry.disable-javascript-minimization", for example with a RequestFilter.
    
    To give the user more fine-grained control over the options, the "GoogleClosureMinimizerOptionsProvider" is added. In addition to provide custom compiler options, an empty Optional can be returned, and the StreamableResource will be transferred "as-is".
---
 .../webresources/GoogleClosureMinimizer.java       | 58 ++++++++++++----------
 .../GoogleClosureMinimizerOptionsProviderImpl.java | 40 +++++++++++++++
 .../GoogleClosureMinimizerOptionsProvider.java     | 25 ++++++++++
 .../webresources/modules/WebResourcesModule.java   |  2 +
 4 files changed, 100 insertions(+), 25 deletions(-)

diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizer.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizer.java
index 071b238..c3b268b 100644
--- a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizer.java
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizer.java
@@ -12,27 +12,29 @@
 
 package org.apache.tapestry5.internal.webresources;
 
-import com.google.javascript.jscomp.*;
-import com.google.javascript.jscomp.Compiler;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.Level;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.tapestry5.TapestryConstants;
 import org.apache.tapestry5.commons.util.CollectionFactory;
 import org.apache.tapestry5.http.services.Request;
 import org.apache.tapestry5.ioc.OperationTracker;
-import org.apache.tapestry5.ioc.annotations.Symbol;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.services.assets.AssetChecksumGenerator;
 import org.apache.tapestry5.services.assets.StreamableResource;
-import org.apache.tapestry5.webresources.WebResourcesSymbols;
+import org.apache.tapestry5.webresources.GoogleClosureMinimizerOptionsProvider;
 import org.slf4j.Logger;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.CompilerOptions;
+import com.google.javascript.jscomp.Result;
+import com.google.javascript.jscomp.SourceFile;
 
 /**
  * A wrapper around the Google Closure {@link Compiler} used to minimize
@@ -41,25 +43,25 @@ import java.util.logging.Level;
 public class GoogleClosureMinimizer extends AbstractMinimizer
 {
 
-    private final static Charset OUTPUT_CHARSET = StandardCharsets.UTF_8;
-
     private final List<SourceFile> EXTERNS = Collections.emptyList();
 
     private final Request request;
-    private final CompilationLevel compilationLevel;
+    private final GoogleClosureMinimizerOptionsProvider optionsProvider;
 
     static
     {
         Compiler.setLoggingLevel(Level.SEVERE);
     }
 
-    public GoogleClosureMinimizer(Logger logger, OperationTracker tracker, AssetChecksumGenerator checksumGenerator, Request request,
-                                  @Symbol(WebResourcesSymbols.COMPILATION_LEVEL)
-                                  CompilationLevel compilationLevel)
+    public GoogleClosureMinimizer(Logger logger,
+                                  OperationTracker tracker,
+                                  AssetChecksumGenerator checksumGenerator,
+                                  Request request,
+                                  GoogleClosureMinimizerOptionsProvider optionsProvider)
     {
         super(logger, tracker, checksumGenerator, "text/javascript");
         this.request = request;
-        this.compilationLevel = compilationLevel;
+        this.optionsProvider = optionsProvider;
     }
 
     @Override
@@ -71,16 +73,22 @@ public class GoogleClosureMinimizer extends AbstractMinimizer
     @Override
     protected InputStream doMinimize(StreamableResource resource) throws IOException
     {
-        // Don't bother to pool the Compiler
 
-        CompilerOptions options = new CompilerOptions();
+        Optional<CompilerOptions> maybeOptions = optionsProvider.providerOptions(resource);
 
-        compilationLevel.setOptionsForCompilationLevel(options);
+        if (maybeOptions.isPresent() == false)
+        {
+            try (InputStream is = resource.openStream()) {
+                return is;
+            }
+        }
 
-        options.setCodingConvention(new ClosureCodingConvention());
-        options.setOutputCharset(OUTPUT_CHARSET);
-        options.setWarningLevel(DiagnosticGroups.CHECK_VARIABLES, CheckLevel.WARNING);
+        CompilerOptions options = maybeOptions.get();
 
+        // Ensure that UTF-8 is set
+        options.setOutputCharset(StandardCharsets.UTF_8);
+
+        // Don't bother to pool the Compiler
         Compiler compiler = new Compiler();
 
         compiler.disableThreads();
@@ -93,7 +101,7 @@ public class GoogleClosureMinimizer extends AbstractMinimizer
 
         if (result.success)
         {
-            return IOUtils.toInputStream(compiler.toSource(), OUTPUT_CHARSET);
+            return IOUtils.toInputStream(compiler.toSource(), StandardCharsets.UTF_8);
         }
 
         throw new RuntimeException(String.format("Compilation failed: %s.",
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizerOptionsProviderImpl.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizerOptionsProviderImpl.java
new file mode 100644
index 0000000..8217574
--- /dev/null
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/GoogleClosureMinimizerOptionsProviderImpl.java
@@ -0,0 +1,40 @@
+package org.apache.tapestry5.internal.webresources;
+
+import java.util.Optional;
+
+import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.services.assets.StreamableResource;
+import org.apache.tapestry5.webresources.GoogleClosureMinimizerOptionsProvider;
+import org.apache.tapestry5.webresources.WebResourcesSymbols;
+
+import com.google.javascript.jscomp.CheckLevel;
+import com.google.javascript.jscomp.ClosureCodingConvention;
+import com.google.javascript.jscomp.CompilationLevel;
+import com.google.javascript.jscomp.CompilerOptions;
+import com.google.javascript.jscomp.DiagnosticGroups;
+
+public class GoogleClosureMinimizerOptionsProviderImpl implements GoogleClosureMinimizerOptionsProvider
+{
+
+    private CompilationLevel compilationLevel;
+
+    public GoogleClosureMinimizerOptionsProviderImpl(@Symbol(WebResourcesSymbols.COMPILATION_LEVEL)
+                                                     CompilationLevel compilationLevel)
+    {
+        this.compilationLevel = compilationLevel;
+    }
+
+    @Override
+    public Optional<CompilerOptions> providerOptions(StreamableResource resource)
+    {
+        CompilerOptions options = new CompilerOptions();
+
+        options.setCodingConvention(new ClosureCodingConvention());
+        options.setWarningLevel(DiagnosticGroups.CHECK_VARIABLES, CheckLevel.WARNING);
+
+        compilationLevel.setOptionsForCompilationLevel(options);
+
+        return Optional.of(options);
+    }
+
+}
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/GoogleClosureMinimizerOptionsProvider.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/GoogleClosureMinimizerOptionsProvider.java
new file mode 100644
index 0000000..906c797
--- /dev/null
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/GoogleClosureMinimizerOptionsProvider.java
@@ -0,0 +1,25 @@
+package org.apache.tapestry5.webresources;
+
+import java.util.Optional;
+
+import org.apache.tapestry5.services.assets.StreamableResource;
+
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.CompilerOptions;
+
+/**
+ * Provide CompilerOptions for the GoogleClosureMinimizer.
+ * TAP5-2661
+ *
+ * @since 5.7
+ */
+public interface GoogleClosureMinimizerOptionsProvider
+{
+    /**
+     * Returns the compiler options to be used by GoogleClosureMinimizer.
+     * 
+     * An empty Optional will result is the StreamableResource to be not minimized.
+     * @return Optional of the supposed compiler options, or empty to disable minimizer
+     */
+    Optional<CompilerOptions> providerOptions(StreamableResource resource);
+}
diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
index d9892ee..aab9af7 100644
--- a/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
+++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/webresources/modules/WebResourcesModule.java
@@ -31,6 +31,7 @@ import org.apache.tapestry5.services.ObjectRenderer;
 import org.apache.tapestry5.services.assets.ResourceMinimizer;
 import org.apache.tapestry5.services.assets.ResourceTransformer;
 import org.apache.tapestry5.services.assets.StreamableResourceSource;
+import org.apache.tapestry5.webresources.GoogleClosureMinimizerOptionsProvider;
 import org.apache.tapestry5.webresources.WebResourcesSymbols;
 
 import java.util.List;
@@ -51,6 +52,7 @@ public class WebResourcesModule
     public static void bind(ServiceBinder binder)
     {
         binder.bind(ResourceTransformerFactory.class, ResourceTransformerFactoryImpl.class);
+        binder.bind(GoogleClosureMinimizerOptionsProvider.class, GoogleClosureMinimizerOptionsProviderImpl.class);
     }
 
     @Contribute(SymbolProvider.class)