You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2014/02/21 08:37:38 UTC
[13/31] git commit: WICKET-3335 break up and refactor monolithing
dequeuing process into delegatable chunks. all working but borders
WICKET-3335 break up and refactor monolithing dequeuing process into delegatable chunks. all working but borders
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/b9ddb888
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/b9ddb888
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/b9ddb888
Branch: refs/heads/master
Commit: b9ddb88862f15be28dd0a74869489a804e4cda43
Parents: e95c712
Author: Igor Vaynberg <ig...@gmail.com>
Authored: Fri Feb 14 21:38:34 2014 -0800
Committer: Igor Vaynberg <ig...@gmail.com>
Committed: Thu Feb 20 23:37:15 2014 -0800
----------------------------------------------------------------------
.../java/org/apache/wicket/ComponentQueue2.java | 2 +
.../java/org/apache/wicket/DequeueContext.java | 152 +++++++++++
.../java/org/apache/wicket/MarkupContainer.java | 254 +++++--------------
.../markup/repeater/AbstractRepeater.java | 21 ++
4 files changed, 240 insertions(+), 189 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/b9ddb888/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java b/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java
index ec5251c..2ce3e8f 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ComponentQueue2.java
@@ -25,6 +25,8 @@ import org.apache.wicket.util.lang.Args;
* Manages the component queue.
*
* @author igor
+ *
+ * @deprecated uses too much memory compared to ComponentQueue
*/
class ComponentQueue2
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/b9ddb888/wicket-core/src/main/java/org/apache/wicket/DequeueContext.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/DequeueContext.java b/wicket-core/src/main/java/org/apache/wicket/DequeueContext.java
new file mode 100644
index 0000000..8324161
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/DequeueContext.java
@@ -0,0 +1,152 @@
+package org.apache.wicket;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.Markup;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.util.collections.ArrayListStack;
+
+public class DequeueContext
+{
+ private final Markup markup;
+ private int index;
+ private ComponentTag next;
+ private ArrayListStack<ComponentTag> tags = new ArrayListStack<>();
+ private ArrayListStack<MarkupContainer> containers = new ArrayListStack<>();
+
+ public static class Bookmark
+ {
+ private final int index;
+ private final ComponentTag next;
+ private final ArrayListStack<ComponentTag> tags;
+ private final ArrayListStack<MarkupContainer> containers;
+
+ private Bookmark(DequeueContext parser)
+ {
+ this.index = parser.index;
+ this.next = parser.next;
+ this.tags = new ArrayListStack<>(parser.tags);
+ this.containers = new ArrayListStack<>(parser.containers);
+ }
+
+ private void restore(DequeueContext parser)
+ {
+ parser.index = index;
+ parser.next = next;
+ parser.tags = new ArrayListStack<ComponentTag>(tags);
+ parser.containers = new ArrayListStack<MarkupContainer>(containers);
+ }
+ }
+
+ public DequeueContext(Markup markup, MarkupContainer root)
+ {
+ this.markup = markup;
+ containers.push(root);
+ next=nextTag();
+ }
+
+ public Bookmark save()
+ {
+ return new Bookmark(this);
+ }
+
+ public void restore(Bookmark bookmark)
+ {
+ bookmark.restore(this);
+ }
+
+ public ComponentTag peekTag()
+ {
+ return next;
+ }
+
+ public ComponentTag popTag()
+ {
+ ComponentTag taken=next;
+ tags.push(taken);
+ next=nextTag();
+ return taken;
+ }
+
+ public void skipToCloseTag()
+ {
+ if (tags.peek().isOpen())
+ {
+ while (!next.closes(tags.peek()))
+ {
+ next = nextTag();
+ }
+ tags.pop();
+ }
+ }
+
+ private ComponentTag nextTag()
+ {
+ for (; index < markup.size(); index++)
+ {
+ MarkupElement element = markup.get(index);
+ if (element instanceof ComponentTag)
+ {
+ ComponentTag tag = (ComponentTag)element;
+ ComponentTag open = tag.isClose() ? tag.getOpenTag() : tag;
+ if (canDequeue(open))
+ {
+ index++;
+ return tag;
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean canDequeue(ComponentTag open)
+ {
+ if (containers.size() < 1)
+ {
+ // TODO queueing message: called too early
+ throw new IllegalStateException();
+ }
+ for (int i = containers.size() - 1; i >= 0; i--)
+ {
+ if (containers.get(i).supportsDequeueingFrom((open)))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isAtOpenOrOpenCloseTag()
+ {
+ return peekTag() != null && (peekTag().isOpen() || peekTag().isOpenClose());
+ }
+
+ public MarkupContainer peekContainer()
+ {
+ return containers.peek();
+ }
+
+ public void pushContainer(MarkupContainer container)
+ {
+ containers.push(container);
+ }
+
+ public MarkupContainer popContainer()
+ {
+ return containers.pop();
+ }
+
+ public Component dequeue(ComponentTag tag)
+ {
+ for (int j = containers.size() - 1; j >= 0; j--)
+ {
+ MarkupContainer container = containers.get(j);
+ Component child = container.findComponentToDequeue(tag);
+ if (child != null)
+ {
+ return child;
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/b9ddb888/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
index 5005f29..72f7cc9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
@@ -2080,20 +2080,6 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
private void internalDequeue()
{
- class Repeater
- {
- int parentMarkupIndex;
- Iterator<Component> renderIterator;
- ComponentTag tag;
-
- Repeater(int parentMarkupIndex, Iterator<Component> renderIterator, ComponentTag tag)
- {
- this.parentMarkupIndex = parentMarkupIndex;
- this.renderIterator = renderIterator;
- this.tag = tag;
- }
- }
-
Markup markup = getAssociatedMarkup();
if (markup == null)
{
@@ -2101,207 +2087,97 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
// this sometimes happens when we are in a unit test
return;
}
- // use arraydeque?
- ArrayListStack<ComponentTag> tags = new ArrayListStack<>();
- ArrayListStack<MarkupContainer> containers = new ArrayListStack<>();
- ArrayListStack<Repeater> repeaters = new ArrayListStack<>();
- containers.push(this);
+ DequeueContext dequeue = new DequeueContext(markup, this);
- for (int i = 0; i < markup.size(); i++)
+ if (dequeue.peekTag() != null)
{
- MarkupElement element = markup.get(i);
+ dequeue(dequeue);
+ }
- if (!(element instanceof ComponentTag))
- {
- continue;
- }
- ComponentTag tag = (ComponentTag)element;
+ }
+ public void dequeue(DequeueContext dequeue)
+ {
+
+
+ while (dequeue.isAtOpenOrOpenCloseTag())
+ {
+
+ ComponentTag tag = dequeue.popTag();
+
+ // see if child is already added to parent
+
- if (tag instanceof WicketTag)
+ Component child = get(tag.getId()); // TODO queueing add this into findInQueue and
+ // rename it to dequeue
+
+ if (child == null)
{
- ComponentTag openTag = tag.getOpenTag() == null ? tag : tag.getOpenTag();
- if (((WicketTag) tag).isBorderTag())
+ // the container does not yet have a child with this id, see if we can
+ // dequeue
+
+ child = dequeue.dequeue(tag);
+
+ if (child != null)
{
- if (tag.isOpen())
+ add(child);
+ if (child instanceof IQueueRegion)
{
- tags.push(tag);
+ ((MarkupContainer)child).dequeue();
}
- else if (tag.isClose())
- {
- tags.pop();
- }
- continue;
- }
- else if (openTag.getAutoComponentFactory() == null)
- {
- // wicket tags that do not produce auto components can be ignored
- continue;
}
}
-
- if (tag.isClose())
+
+ if (child == null || tag.isOpenClose() || !(child instanceof MarkupContainer))
{
- tags.pop();
- containers.pop();
-
- if (containers.peek() instanceof AbstractRepeater)
- {
- Repeater repeater = repeaters.peek();
- if (repeater.renderIterator.hasNext())
- {
- containers.push((MarkupContainer)repeater.renderIterator.next());
- tags.push(repeater.tag);
- i = repeater.parentMarkupIndex;
- continue;
- }
- else
- {
- // we rendered the last item, now time to close the repeater
- repeaters.pop();
- tags.pop();
- containers.pop();
- }
- }
+ // could not dequeue, or does not contain children
+
+ dequeue.skipToCloseTag();
}
else
{
- String id = tag.getId();
- Component child = containers.peek().get(id);
-
- // see if child is already added to parent
- if (child == null)
- {
- // the container does not yet have a child with this id, see if we can
- // dequeue
- for (int j = containers.size() - 1; j >= 0; j--)
- {
- MarkupContainer container = containers.get(j);
- child = container.queue != null
- ? container.queue.remove(id)
- : null;
- if (child != null)
- {
- break;
- }
- }
-
- if (child != null)
- {
- MarkupContainer parentContainer = containers.peek();
- boolean isInBorder = isInBorder(tags, parentContainer);
- if (isInBorder)
- {
- ((Border) parentContainer).addToBorder(child);
- }
- else
- {
- parentContainer.add(child);
- }
-
- if (child instanceof IQueueRegion)
- {
- ((MarkupContainer)child).dequeue();
- }
+ MarkupContainer container = (MarkupContainer)child;
+ dequeue.pushContainer(container);
+ container.dequeue(dequeue);
+ dequeue.popContainer();
+ }
- }
- }
- if (child == null)
+ if (tag.isOpen())
+ {
+ // pull the close tag off
+ ComponentTag close = dequeue.popTag();
+ if (!close.closes(tag))
{
- // could not dequeue, skip until closing tag
-
- if (tag.isOpen())
- {
- for (i = i + 1; i < markup.size(); i++)
- {
- MarkupElement e = markup.get(i);
- if (e instanceof ComponentTag && e.closes(tag))
- {
- break;
- }
- }
- }
-
- // if (dequeueSites == null)
- // {
- // dequeueSites = new HashSet<String>();
- // }
- // dequeueSites.add(id);
-
+ // sanity check
+ // FIXME queueing message
+ throw new IllegalStateException();
}
- else
- {
- if (tag.isOpen())
- {
- if (child instanceof MarkupContainer)
- {
- containers.push((MarkupContainer)child);
- tags.push(tag);
+ }
- if (child instanceof AbstractRepeater)
- {
- Repeater repeater = new Repeater(i,
- ((AbstractRepeater)child).iterator(), tag);
- if (repeater.renderIterator.hasNext())
- {
- repeaters.push(repeater);
- containers
- .push((MarkupContainer)repeater.renderIterator.next());
- tags.push(tag);
- }
- else
- {
- // empty repeater, skip until closing tag
- for (i = i + 1; i < markup.size(); i++)
- {
- MarkupElement e = markup.get(i);
- if (e instanceof ComponentTag && e.closes(tag))
- {
- break;
- }
- }
- i--;
- continue;
- }
- }
- }
- else
- {
- // web component, skip until closing tag
- for (i = i + 1; i < markup.size(); i++)
- {
- MarkupElement e = markup.get(i);
- if (e instanceof ComponentTag && e.closes(tag))
- {
- break;
- }
- }
- }
- }
- else
- {
- // openclose tag, nothing to do
- }
- }
- }
}
-
}
-
- private boolean isInBorder(ArrayListStack<ComponentTag> tags, MarkupContainer parentContainer)
- {
- boolean result = false;
- if (parentContainer instanceof Border && tags.empty() == false)
- {
- ComponentTag parentsTag = tags.peek();
- if (parentsTag instanceof WicketTag && ((WicketTag)parentsTag).isBorderTag())
+ protected boolean supportsDequeueingFrom(ComponentTag tag) {
+ if (tag instanceof WicketTag) {
+ WicketTag wicketTag=(WicketTag)tag;
+ if (wicketTag.getAutoComponentFactory() != null)
{
- result = true;
+ return true;
+ } else {
+ return false;
}
}
- return result;
+ return true;
+ }
+
+ protected Component findComponentToDequeue(ComponentTag tag)
+ {
+ return queue == null ? null : queue.remove(tag.getId());
+ }
+
+ protected void addDequeuedComponent(Component component, ComponentTag tag) {
+ add(component);
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/b9ddb888/wicket-core/src/main/java/org/apache/wicket/markup/repeater/AbstractRepeater.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/repeater/AbstractRepeater.java b/wicket-core/src/main/java/org/apache/wicket/markup/repeater/AbstractRepeater.java
index 1698197..134e239 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/repeater/AbstractRepeater.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/repeater/AbstractRepeater.java
@@ -21,6 +21,9 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.wicket.Component;
+import org.apache.wicket.DequeueContext;
+import org.apache.wicket.DequeueContext.Bookmark;
+import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.IMarkupFragment;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.IModel;
@@ -150,4 +153,22 @@ public abstract class AbstractRepeater extends WebMarkupContainer
* Callback to let the repeater know it should populate itself with its items.
*/
protected abstract void onPopulate();
+
+ @Override
+ public void dequeue(DequeueContext dequeue) {
+ if (size()>0) {
+ Bookmark bookmark=dequeue.save();
+
+ for (Component child:this) {
+ if (child instanceof MarkupContainer) {
+ dequeue.popContainer(); // pop the repeater
+ MarkupContainer container=(MarkupContainer) child;
+ dequeue.pushContainer(container);
+ container.dequeue(dequeue);
+ dequeue.restore(bookmark);
+ }
+ }
+ }
+ dequeue.skipToCloseTag();
+ }
}