You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2019/09/11 10:32:08 UTC

[wicket] branch master updated: WICKET-6673 priority items based on depth

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5af5c05  WICKET-6673 priority items based on depth
5af5c05 is described below

commit 5af5c0539c421851c224c012accadb482d93987e
Author: Sven Meier <sv...@apache.org>
AuthorDate: Wed Sep 11 08:28:27 2019 +0200

    WICKET-6673 priority items based on depth
    
    restored some information of RecordedHeaderItem in case someone
    needs this in their comparator implementation
---
 .../markup/head/PriorityFirstComparator.java       | 21 +++---
 .../wicket/markup/head/ResourceAggregator.java     | 79 ++++++++++++++++------
 .../wicket/markup/head/HeaderResponseTest.java     | 11 +++
 .../wicket/markup/head/PriorityDepthsPage.html     |  7 ++
 .../wicket/markup/head/PriorityDepthsPage.java     | 65 ++++++++++++++++++
 .../markup/head/PriorityDepthsPage_expected.html   |  9 +++
 6 files changed, 163 insertions(+), 29 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/PriorityFirstComparator.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/PriorityFirstComparator.java
index 6e52c08..fbd8b43 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/PriorityFirstComparator.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/PriorityFirstComparator.java
@@ -33,7 +33,8 @@ import org.apache.wicket.markup.head.ResourceAggregator.RecordedHeaderItemLocati
  */
 public class PriorityFirstComparator implements Comparator<RecordedHeaderItem>, Serializable
 {
-	protected static enum HeaderItemType {
+	protected static enum HeaderItemType
+	{
 		PRIORITY, PAGE, COMPONENT;
 	}
 
@@ -81,20 +82,20 @@ public class PriorityFirstComparator implements Comparator<RecordedHeaderItem>,
 	}
 
 	/**
-	 * Compare two recorded {@link PriorityHeaderItem}s, converting the child-first order into parent-first.
+	 * Compare two recorded {@link PriorityHeaderItem}s, converting the child-first order into
+	 * parent-first.
 	 * 
-	 * @param item1 first item
-	 * @param item2 second item
+	 * @param item1
+	 *            first item
+	 * @param item2
+	 *            second item
 	 * @return -1, 0 or 1 if item1 needs to be rendered before, unchanged or after item2.
 	 * 
 	 * @see RecordedHeaderItemLocation#getDepth()
 	 */
 	protected int inversedComponentOrder(RecordedHeaderItem item1, RecordedHeaderItem item2)
 	{
-		RecordedHeaderItemLocation location1 = item1.getLocations().get(item1.getLocations().size() - 1);
-		RecordedHeaderItemLocation location2 = item2.getLocations().get(item2.getLocations().size() - 1);
-
-		return location1.getDepth() - location2.getDepth();
+		return item1.getMinDepth() - item2.getMinDepth();
 	}
 
 	/**
@@ -109,14 +110,14 @@ public class PriorityFirstComparator implements Comparator<RecordedHeaderItem>,
 		{
 			return HeaderItemType.PRIORITY;
 		}
-		
+
 		if (renderPageFirst)
 		{
 			if (item.getItem() instanceof PageHeaderItem)
 			{
 				return HeaderItemType.PAGE;
 			}
-			
+
 			for (RecordedHeaderItemLocation curLocation : item.getLocations())
 			{
 				if (curLocation.getRenderBase() instanceof Page)
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/ResourceAggregator.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/ResourceAggregator.java
index 14938df..2477ac6 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/ResourceAggregator.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/ResourceAggregator.java
@@ -33,6 +33,7 @@ import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.resource.ResourceReference;
 import org.apache.wicket.resource.CircularDependencyException;
 import org.apache.wicket.resource.bundles.ReplacementResourceBundleReference;
+import org.apache.wicket.util.lang.Classes;
 
 /**
  * {@code ResourceAggregator} implements resource dependencies, resource bundles and sorting of
@@ -43,56 +44,70 @@ import org.apache.wicket.resource.bundles.ReplacementResourceBundleReference;
  */
 public class ResourceAggregator extends DecoratingHeaderResponse
 {
+
 	/**
-	 * The location in which a {@link HeaderItem} is added, i.e. the responsible component.
+	 * The location in which a {@link HeaderItem} is added, consisting of the component/behavior
+	 * that added the item, the index in the list for that component/behavior at which the item was
+	 * added and the index in the request.
 	 * 
 	 * @author papegaaij
 	 */
 	public static class RecordedHeaderItemLocation
 	{
 		private final Component renderBase;
-		
+
+		private int indexInRequest;
+
 		private int depth = -1;
 
 		/**
 		 * Construct.
 		 * 
 		 * @param renderBase
-		 *            the component that added the item.
+		 *            The component that added the item.
 		 */
-		public RecordedHeaderItemLocation(Component renderBase)
+		public RecordedHeaderItemLocation(Component renderBase, int indexInRequest)
 		{
 			this.renderBase = renderBase;
+			
+			this.indexInRequest = indexInRequest;
 		}
 
 		/**
-		 * @return the component that rendered the item.
+		 * @return the component or behavior that added the item.
 		 */
-		public Component getRenderBase()
+		public Object getRenderBase()
 		{
 			return renderBase;
 		}
 
 		/**
-		 * Get the depth of this location's component in the component tree.
-		 * <p>
-		 * Used by {@link ResourceAggregator} to give precedence to {@link PriorityHeaderItem}s that are closer to the page.
-		 * 
-		 * @return depth
+		 * @return the number of items added before this one in the same request.
 		 */
+		public int getIndexInRequest()
+		{
+			return indexInRequest;
+		}
+
 		public int getDepth()
 		{
 			if (depth == -1) {
-				Component d = renderBase;
-				while (d != null)  {
+				Component component = renderBase;
+				while (component != null)  {
 					depth++;
 					
-					d = d.getParent();
+					component = component.getParent();
 				}
+
 			}
-			
 			return depth;
 		}
+		
+		@Override
+		public String toString()
+		{
+			return Classes.simpleName(renderBase.getClass());
+		}
 	}
 
 	/**
@@ -105,6 +120,8 @@ public class ResourceAggregator extends DecoratingHeaderResponse
 		private final HeaderItem item;
 
 		private final List<RecordedHeaderItemLocation> locations;
+		
+		private int minDepth = Integer.MAX_VALUE;
 
 		/**
 		 * Construct.
@@ -121,11 +138,15 @@ public class ResourceAggregator extends DecoratingHeaderResponse
 		 * Records a location at which the item was added.
 		 * 
 		 * @param renderBase
-		 *            the component that rendered the item.
+		 *            The component or behavior that added the item.
+		 * @param indexInRequest
+		 *            Indicates the number of items added before this one in this request.
 		 */
-		public void addLocation(Component renderBase)
+		void addLocation(Component renderBase, int indexInRequest)
 		{
-			locations.add(new RecordedHeaderItemLocation(renderBase));
+			locations.add(new RecordedHeaderItemLocation(renderBase, indexInRequest));
+			
+			minDepth = Integer.MAX_VALUE;
 		}
 
 		/**
@@ -143,6 +164,23 @@ public class ResourceAggregator extends DecoratingHeaderResponse
 		{
 			return locations;
 		}
+		
+		/**
+		 * Get the minimum depth in the component tree.
+		 * 
+		 * @return depth
+		 */
+		public int getMinDepth()
+		{
+			if (minDepth == Integer.MAX_VALUE) {
+				for (RecordedHeaderItemLocation location : locations) {
+					minDepth = Math.min(minDepth, location.getDepth());
+				}
+			}
+			
+			return minDepth;
+		}
+
 
 		@Override
 		public String toString()
@@ -164,6 +202,8 @@ public class ResourceAggregator extends DecoratingHeaderResponse
 	 * The currently rendered component
 	 */
 	private Component renderBase;
+	
+	private int indexInRequest;
 
 	/**
 	 * Construct.
@@ -219,7 +259,8 @@ public class ResourceAggregator extends DecoratingHeaderResponse
 			recordedItem = new RecordedHeaderItem(item);
 			itemsToBeRendered.put(item, recordedItem);
 		}
-		recordedItem.addLocation(renderBase);
+		recordedItem.addLocation(renderBase, indexInRequest);
+		indexInRequest++;
 	}
 
 	private void renderDependencies(HeaderItem item, Set<HeaderItem> depsDone)
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/HeaderResponseTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/head/HeaderResponseTest.java
index a98d3b1..8c6000c 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/head/HeaderResponseTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/HeaderResponseTest.java
@@ -57,4 +57,15 @@ class HeaderResponseTest extends WicketTestCase
 			.setHeaderItemComparator(new PriorityFirstComparator(true));
 		executeTest(ConcretePage.class, "ExpectedResultPageFirst.html");
 	}
+	
+	/**
+	 * WICKET-6673 priority items are sorted by minimum depth.
+	 * 
+	 * @throws Exception
+	 */
+	@Test
+    void testPriorityDepths() throws Exception
+	{
+		executeTest(PriorityDepthsPage.class, "PriorityDepthsPage_expected.html");
+	}
 }
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.html b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.html
new file mode 100644
index 0000000..01889d4
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.html
@@ -0,0 +1,7 @@
+<body>
+	<div wicket:id="a"></div>
+
+	<div wicket:id="b">
+		<div wicket:id="c"/>
+	</div>
+</body>
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.java b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.java
new file mode 100644
index 0000000..32c8207
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.head;
+
+import org.apache.wicket.markup.head.StringHeaderItem;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.PriorityHeaderItem;
+
+/**
+ * See {@link HeaderResponseTest#testPriorityDepths()}.
+ */
+public class PriorityDepthsPage extends WebPage
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 */
+	public PriorityDepthsPage()
+	{
+		add(new Priority("a", "x"));
+
+		Priority b = new Priority("b", "y");
+		add(b);
+		
+		b.add(new Priority("c", "x"));
+	}
+
+	private class Priority extends WebMarkupContainer {
+
+		private String title;
+
+		public Priority(String id, String title)
+		{
+			super(id);
+			
+			this.title = title;
+		}
+		
+		@Override
+		public void renderHead(IHeaderResponse response)
+		{
+			super.renderHead(response);
+			
+			response.render(new PriorityHeaderItem(
+				StringHeaderItem.forString(String.format("<title>%s</title>\n", title))));
+		}
+	}
+}
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage_expected.html b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage_expected.html
new file mode 100644
index 0000000..f71b37a
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/PriorityDepthsPage_expected.html
@@ -0,0 +1,9 @@
+<head><title>x</title>
+<title>y</title>
+</head><body>
+	<div wicket:id="a"></div>
+
+	<div wicket:id="b">
+		<div wicket:id="c"></div>
+	</div>
+</body>