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

papegaaij pushed a commit to branch csp
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/csp by this push:
     new 6043b09  WICKET-6729: Add a new API for managing 
IHeaderResponseDecorators
6043b09 is described below

commit 6043b09872518c55cd16a362752a6cdcaea8c42f
Author: Emond Papegaaij <[email protected]>
AuthorDate: Wed Jan 15 21:26:55 2020 +0100

    WICKET-6729: Add a new API for managing IHeaderResponseDecorators
---
 .../main/java/org/apache/wicket/Application.java   | 37 +++++++---
 .../html/HeaderResponseDecoratorCollection.java    | 82 ++++++++++++++++++++++
 .../head/filter/FilteringHeaderResponseTest.java   | 28 ++++----
 .../markup/html/DecoratingHeaderResponseTest.java  | 32 ++++-----
 .../apache/wicket/examples/csp/CspApplication.java |  2 +-
 .../ResourceDecorationApplication.java             | 12 ++--
 .../apache/wicket/examples/sri/SriApplication.java |  2 +-
 7 files changed, 142 insertions(+), 53 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java 
b/wicket-core/src/main/java/org/apache/wicket/Application.java
index d9b726a..af2632d 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -44,6 +44,7 @@ import org.apache.wicket.markup.MarkupFactory;
 import org.apache.wicket.markup.head.HeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.ResourceAggregator;
+import org.apache.wicket.markup.html.HeaderResponseDecoratorCollection;
 import org.apache.wicket.markup.html.IHeaderContributor;
 import org.apache.wicket.markup.html.IHeaderResponseDecorator;
 import 
org.apache.wicket.markup.html.image.resource.DefaultButtonImageResourceFactory;
@@ -184,9 +185,8 @@ public abstract class Application implements 
UnboundListener, IEventSink, IMetad
        /**
         * The decorator this application uses to decorate any header responses 
created by Wicket
         */
-       private IHeaderResponseDecorator headerResponseDecorator = 
(headerresponse) -> {
-               return new ResourceAggregator(headerresponse);
-       };
+       private HeaderResponseDecoratorCollection headerResponseDecorators =
+               new HeaderResponseDecoratorCollection();
 
        /**
         * Checks if the <code>Application</code> threadlocal is set in this 
thread
@@ -1585,22 +1585,37 @@ public abstract class Application implements 
UnboundListener, IEventSink, IMetad
         * Sets an {@link IHeaderResponseDecorator} that you want your 
application to use to decorate
         * header responses.
         * <p>
-        * Calling this method replaces the default decorator, which utilizes a 
{@link ResourceAggregator}:
-        * The given implementation should make sure, that it too wraps 
responses in a {@link ResourceAggregator},
-        * otherwise no dependencies for {@link HeaderItem}s will be resolved.  
 
+        * Calling this method replaces the default decorator, which utilizes a
+        * {@link ResourceAggregator}: The given implementation should make 
sure, that it too wraps
+        * responses in a {@link ResourceAggregator}, otherwise no dependencies 
for {@link HeaderItem}s
+        * will be resolved.
         * 
         * @param headerResponseDecorator
         *            your custom decorator, must not be null
+        * @deprecated use {@code add(...)} on {@link 
#getHeaderResponseDecorators()}. This method
+        *             removes the {@link ResourceAggregator}, which is needed 
to resolve resource
+        *             dependencies.
         */
-       public final Application setHeaderResponseDecorator(final 
IHeaderResponseDecorator headerResponseDecorator)
+       @Deprecated
+       public final Application
+                       setHeaderResponseDecorator(final 
IHeaderResponseDecorator headerResponseDecorator)
        {
-               Args.notNull(headerResponseDecorator, 
"headerResponseDecorator");
-               
-               this.headerResponseDecorator = headerResponseDecorator;
+               headerResponseDecorators.replaceAll(headerResponseDecorator);
                return this;
        }
 
        /**
+        * Returns the {@link HeaderResponseDecoratorCollection} used by this 
application. On this
+        * collection you can add additional decorators, which will be nested 
in the order added.
+        * 
+        * @return The {@link HeaderResponseDecoratorCollection} used by this 
application.
+        */
+       public HeaderResponseDecoratorCollection getHeaderResponseDecorators()
+       {
+               return headerResponseDecorators;
+       }
+       
+       /**
         * INTERNAL METHOD - You shouldn't need to call this. This is called 
every time Wicket creates
         * an IHeaderResponse. It gives you the ability to incrementally add 
features to an
         * IHeaderResponse implementation by wrapping it in another 
implementation.
@@ -1615,7 +1630,7 @@ public abstract class Application implements 
UnboundListener, IEventSink, IMetad
         */
        public final IHeaderResponse decorateHeaderResponse(final 
IHeaderResponse response)
        {
-               return headerResponseDecorator.decorate(response);
+               return headerResponseDecorators.decorate(response);
        }
 
        /**
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/HeaderResponseDecoratorCollection.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/HeaderResponseDecoratorCollection.java
new file mode 100644
index 0000000..6d245ed
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/HeaderResponseDecoratorCollection.java
@@ -0,0 +1,82 @@
+package org.apache.wicket.markup.html;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.ResourceAggregator;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A collection of {@link IHeaderResponseDecorator}s. The decorators will be 
nested oldest on the
+ * inside, newest on the outside. By default {@link ResourceAggregator} is 
already registered.
+ * 
+ * @author Emond Papegaaij
+ */
+public class HeaderResponseDecoratorCollection implements 
IHeaderResponseDecorator
+{
+       private final List<IHeaderResponseDecorator> decorators = new 
CopyOnWriteArrayList<>();
+
+       public HeaderResponseDecoratorCollection()
+       {
+               decorators.add(response -> new ResourceAggregator(response));
+       }
+
+       /**
+        * Adds a new {@link IHeaderResponseDecorator} that will be invoked 
prior to all already
+        * registered decorators. That means, the first to be added will be 
wrapped by a
+        * {@link ResourceAggregator} like this: {@code new 
ResourceAggregator(first)}. The second will
+        * be wrapped by the first and the aggregator: {@code new 
ResourceAggregator(first(second))}.
+        * 
+        * @param decorator
+        *            The decorator to add, cannot be null.
+        * @return {@code this} for chaining.
+        */
+       public HeaderResponseDecoratorCollection add(IHeaderResponseDecorator 
decorator)
+       {
+               Args.notNull(decorator, "decorator");
+               decorators.add(0, decorator);
+               return this;
+       }
+
+       /**
+        * Adds a new {@link IHeaderResponseDecorator} that will be invoked 
after all already registered
+        * decorators.
+        * 
+        * @param decorator
+        *            The decorator to add, cannot be null.
+        * @return {@code this} for chaining.
+        */
+       public HeaderResponseDecoratorCollection
+                       addPostProcessingDecorator(IHeaderResponseDecorator 
decorator)
+       {
+               Args.notNull(decorator, "decorator");
+               decorators.add(decorator);
+               return this;
+       }
+
+       /**
+        * Replaces all registered {@link IHeaderResponseDecorator}s with the 
given decorator. This also
+        * removes the {@link ResourceAggregator}, which is required to render 
resource dependencies.
+        * 
+        * @param decorator
+        *            The decorator to add, cannot be null.
+        * @return {@code this} for chaining.
+        */
+       public HeaderResponseDecoratorCollection 
replaceAll(IHeaderResponseDecorator decorator)
+       {
+               Args.notNull(decorator, "decorator");
+               decorators.clear();
+               decorators.add(decorator);
+               return this;
+       }
+
+       @Override
+       public IHeaderResponse decorate(IHeaderResponse response)
+       {
+               IHeaderResponse ret = response;
+               for (IHeaderResponseDecorator curDecorator : decorators)
+                       ret = curDecorator.decorate(ret);
+               return ret;
+       }
+}
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
index 70ea9d8..63bbadf 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
@@ -41,17 +41,11 @@ class FilteringHeaderResponseTest extends WicketTestCase
        @Test
        void footerDependsOnHeadItem() throws Exception
        {
-               tester.getApplication().setHeaderResponseDecorator(new 
IHeaderResponseDecorator()
-               {
-                       @Override
-                       public IHeaderResponse decorate(IHeaderResponse 
response)
-                       {
-                               // use this header resource decorator to load 
all JavaScript resources in the page
-                               // footer (after </body>)
-                               return new ResourceAggregator(
-                                       new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
-                       }
-               });
+               // use this header resource decorator to load all JavaScript 
resources in the page
+               // footer (after </body>)
+               tester.getApplication()
+                       .getHeaderResponseDecorators()
+                       .add(response -> new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
                executeTest(FilteredHeaderPage.class, 
"FilteredHeaderPageExpected.html");
        }
 
@@ -90,19 +84,21 @@ class FilteringHeaderResponseTest extends WicketTestCase
        @Test
        void deferred() throws Exception
        {
-               tester.getApplication().setHeaderResponseDecorator(
-                       response -> new ResourceAggregator(new 
JavaScriptDeferHeaderResponse(response)));
+               tester.getApplication()
+                       .getHeaderResponseDecorators()
+                       .add(response -> new 
JavaScriptDeferHeaderResponse(response));
                executeTest(DeferredPage.class, "DeferredPageExpected.html");
        }
-       
+
        /**
         * WICKET-6682
         */
        @Test
        void nonce() throws Exception
        {
-               tester.getApplication().setHeaderResponseDecorator(
-                       response -> new ResourceAggregator(new 
CspNonceHeaderResponse(response, "NONCE")));
+               tester.getApplication()
+                       .getHeaderResponseDecorators()
+                       .add(response -> new CspNonceHeaderResponse(response, 
"NONCE"));
                executeTest(CspNoncePage.class, "CspNoncePageExpected.html");
        }
 }
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/DecoratingHeaderResponseTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/DecoratingHeaderResponseTest.java
index 65eb1ca..f166d41 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/DecoratingHeaderResponseTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/DecoratingHeaderResponseTest.java
@@ -55,27 +55,25 @@ class DecoratingHeaderResponseTest extends WicketTestCase
        void decoratedStringPrepend() throws IOException, 
ResourceStreamNotFoundException,
                ParseException
        {
-               tester.getApplication().setHeaderResponseDecorator(new 
IHeaderResponseDecorator()
-               {
-                       @Override
-                       public IHeaderResponse decorate(IHeaderResponse 
response)
+               tester.getApplication()
+                       .getHeaderResponseDecorators()
+                       .add(response -> new DecoratingHeaderResponse(response)
                        {
-                               return new ResourceAggregator(new 
DecoratingHeaderResponse(response)
+                               @Override
+                               public void render(HeaderItem item)
                                {
-                                       @Override
-                                       public void render(HeaderItem item)
+                                       if (item instanceof 
JavaScriptReferenceHeaderItem)
                                        {
-                                               if (item instanceof 
JavaScriptReferenceHeaderItem)
-                                               {
-                                                       
JavaScriptReferenceHeaderItem original = (JavaScriptReferenceHeaderItem)item;
-                                                       item = 
JavaScriptHeaderItem.forReference(new PackageResourceReference(
-                                                               "DECORATED-" + 
original.getReference().getName()), original.getId());
-                                               }
-                                               super.render(item);
+                                               JavaScriptReferenceHeaderItem 
original =
+                                                       
(JavaScriptReferenceHeaderItem) item;
+                                               item = 
JavaScriptHeaderItem.forReference(
+                                                       new 
PackageResourceReference(
+                                                               "DECORATED-" + 
original.getReference().getName()),
+                                                       original.getId());
                                        }
-                               });
-                       }
-               });
+                                       super.render(item);
+                               }
+                       });
                tester.startPage(TestPage.class);
                XmlPullParser parser = new XmlPullParser();
                parser.parse(tester.getLastResponseAsString());
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/csp/CspApplication.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/csp/CspApplication.java
index b4b8341..e8eff7e 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/csp/CspApplication.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/csp/CspApplication.java
@@ -45,7 +45,7 @@ public class CspApplication extends WicketExampleApplication
        {
                super.init();
 
-               setHeaderResponseDecorator(response -> new 
ResourceAggregator(new CspNonceHeaderResponse(response, getNonce())));
+               getHeaderResponseDecorators().add(response -> new 
CspNonceHeaderResponse(response, getNonce()));
                
                mountPage("noncedemo", NonceDemoPage.class);
        }
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/resourcedecoration/ResourceDecorationApplication.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/resourcedecoration/ResourceDecorationApplication.java
index b8b45e9..1fddce4 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/resourcedecoration/ResourceDecorationApplication.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/resourcedecoration/ResourceDecorationApplication.java
@@ -17,7 +17,6 @@
 package org.apache.wicket.examples.resourcedecoration;
 
 import org.apache.wicket.Application;
-import org.apache.wicket.markup.head.ResourceAggregator;
 import 
org.apache.wicket.markup.head.filter.JavaScriptFilteredIntoFooterHeaderResponse;
 import org.apache.wicket.markup.html.IHeaderResponseDecorator;
 import org.apache.wicket.protocol.http.WebApplication;
@@ -28,7 +27,7 @@ import 
org.apache.wicket.request.resource.CssResourceReference;
  * 
  * <p>
  * The key is to register a custom {@link IHeaderResponseDecorator} via
- * {@link Application#setHeaderResponseDecorator(IHeaderResponseDecorator)} 
that will intercept all
+ * {@link Application#getHeaderResponseDecorators()} that will intercept all
  * resource contributions.
  * 
  * @author jthomerson
@@ -44,11 +43,10 @@ public class ResourceDecorationApplication extends 
WebApplication
                        new CssResourceReference(HomePage.class, "footer.css"),
                        new CssResourceReference(HomePage.class, "header.css"));
 
-               setHeaderResponseDecorator(response -> {
-                       // use this header resource decorator to load all 
JavaScript resources in the page
-                       // footer (after </body>)
-                       return new ResourceAggregator(new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
-               });
+               // use this header resource decorator to load all JavaScript 
resources in the page
+               // footer (after </body>)
+               getHeaderResponseDecorators()
+                               .add(response -> new 
JavaScriptFilteredIntoFooterHeaderResponse(response, "footerJS"));
        }
 
        @Override
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
index 8b9a4f4..6221e60 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/sri/SriApplication.java
@@ -35,7 +35,7 @@ public class SriApplication extends WicketExampleApplication
        {
                super.init();
 
-               setHeaderResponseDecorator(response -> new 
ResourceAggregator(integrity.wrap(response)));
+               getHeaderResponseDecorators().add(integrity::wrap);
 
                mountPage("integritydemo", IntegrityDemoPage.class);
        }

Reply via email to