You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by pa...@apache.org on 2020/01/15 20:27:21 UTC
[wicket] branch csp updated: WICKET-6729: Add a new API for
managing IHeaderResponseDecorators
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 <em...@topicus.nl>
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);
}