Author: hlship
Date: Thu Sep 4 11:44:45 2008
New Revision: 692189
URL: http://svn.apache.org/viewvc?rev=692189&view=rev
Log:
TAPESTRY-2541: Tapestry DOM needs basic methods to manipulate the DOM
post-render
Modified:
tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt
tapestry/tapestry5/trunk/src/site/apt/index.apt
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
Modified: tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt Thu Sep 4 11:44:45 2008
@@ -43,9 +43,7 @@
allows the majority of code to treat the generation of output as a stream.
In fact,
MarkupWriter is more like a cursor into the DOM tree.
- Once all rendering is complete, the DOM tree is streamed to the client.
Planned enhancements
- will control output formatting, including pretty-printing and/or output
compression (elimination
- of all unnecessary whitespace).
+ Once all rendering is complete, the DOM tree is streamed to the client.
DOM Classes
@@ -156,3 +154,14 @@
writer.comment("Start of JS Menu code");
+----+
+
+DOM Manipulation
+
+ A powerful feature of Tapestry 5 is the ability to manipulate the DOM after
it has been rendered.
+
+ Methods on Node allow an existing node to be moved relative to an Element.
Nodes may be moved before or after the Element,
+ or may be moved inside an Element at the top (the first child) or the bottom
(the last child).
+
+ In addition, the children of an Element may be removed or a Node (and all of
its children) removed entirely.
+
+ Finally, an Element may "pop": the Element is removed and replaced with its
children.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/src/site/apt/index.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/index.apt?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/index.apt Thu Sep 4 11:44:45 2008
@@ -84,6 +84,10 @@
New And Of Note
+ * New methods have been added to
+ {{{../apidocs/org/apache/tapestry5/dom/Node.html}Node}} to allow nodes to
be moved about or otherwise
+ manipulated.
+
* Application State Objects are now automatically saved back to the session
at the end of the request,
which ensures that ASO data is properly replicated across at cluster.
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -24,18 +24,15 @@
{
private final String content;
- private final Document document;
-
- public CData(Node container, Document document, String content)
+ public CData(Node container, String content)
{
super(container);
- this.document = document;
this.content = content;
}
-
- public void toMarkup(PrintWriter writer)
+ @Override
+ void toMarkup(Document document, PrintWriter writer)
{
MarkupModel model = document.getMarkupModel();
@@ -47,13 +44,8 @@
return;
}
- // CDATA not supported, so write it normally, with entities escaped.
Create a working
- // buffer that's plenty big even if a lot of characters need escaping.
-
- StringBuilder builder = new StringBuilder(2 * content.length());
-
- model.encode(content, builder);
+ // CDATA not supported, so write it normally, with entities escaped.
- writer.print(builder.toString());
+ writer.print(model.encode(content));
}
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -31,11 +31,10 @@
}
@Override
- public void toMarkup(PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer)
{
writer.print("<!-- ");
writer.print(comment);
writer.print(" -->");
}
-
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -37,6 +37,15 @@
encode(content, false, buffer);
}
+ public String encode(String content)
+ {
+ StringBuilder buffer = new StringBuilder(content.length() * 2);
+
+ encode(content, false, buffer);
+
+ return buffer.toString();
+ }
+
public void encodeQuoted(String content, StringBuilder buffer)
{
encode(content, true, buffer);
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@
this.encoding = encoding;
}
- Document getDocument()
+ public Document getDocument()
{
return this;
}
@@ -109,7 +109,7 @@
}
@Override
- public void toMarkup(PrintWriter writer)
+ public void toMarkup(Document document, PrintWriter writer)
{
if (rootElement == null) throw new
IllegalStateException(DomMessages.noRootElement());
@@ -129,7 +129,7 @@
dtd.toMarkup(writer);
}
- rootElement.toMarkup(writer);
+ rootElement.toMarkup(document, writer);
}
@Override
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
Thu Sep 4 11:44:45 2008
@@ -48,10 +48,6 @@
this.value = value;
}
- public String getValue()
- {
- return value;
- }
void render(MarkupModel model, StringBuilder builder)
{
@@ -105,12 +101,12 @@
this.namespace = namespace;
this.name = name;
- document = parent.getDocument();
+ document = null;
}
public Document getDocument()
{
- return document;
+ return document != null ? document : super.getDocument();
}
/**
@@ -266,7 +262,7 @@
*/
public Text text(String text)
{
- return newChild(new Text(this, document, text));
+ return newChild(new Text(this, text));
}
/**
@@ -277,7 +273,7 @@
*/
public CData cdata(String content)
{
- return newChild(new CData(this, document, content));
+ return newChild(new CData(this, content));
}
@@ -289,15 +285,16 @@
}
@Override
- public void toMarkup(PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer)
{
+ MarkupModel markupModel = document.getMarkupModel();
+
StringBuilder builder = new StringBuilder();
String prefixedElementName = toPrefixedName(namespace, name);
builder.append("<").append(prefixedElementName);
- MarkupModel markupModel = document.getMarkupModel();
if (attributes != null)
{
@@ -346,7 +343,7 @@
writer.print(builder.toString());
- if (hasChildren) writeChildMarkup(writer);
+ if (hasChildren) writeChildMarkup(document, writer);
// Dangerous -- perhaps it should be an error for a tag of type OMIT
to even have children!
// We'll certainly be writing out unbalanced markup in that case.
@@ -446,7 +443,7 @@
{
Attribute attribute = InternalUtils.get(attributes, attributeName);
- return attribute == null ? null : attribute.getValue();
+ return attribute == null ? null : attribute.value;
}
public String getName()
@@ -529,4 +526,34 @@
{
return namespace;
}
+
+ /**
+ * Removes an element; the element's children take the place of the node
within its container.
+ */
+ public void pop()
+ {
+ // Have to be careful because we'll be modifying the underlying list
of children
+ // as we work, so we need a copy of the children.
+
+ List<Node> childrenCopy = CollectionFactory.newList(getChildren());
+
+ for (Node child : childrenCopy)
+ {
+ child.moveBefore(this);
+ }
+
+ remove();
+ }
+
+ /**
+ * Removes all children from this element.
+ *
+ * @return the element, for method chaining
+ */
+ public Element removeChildren()
+ {
+ clearChildren();
+
+ return this;
+ }
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -28,9 +28,9 @@
* entities (such as &lt;).
*
* @param content to be filtered
- * @param buffer to receive the filtered content
+ * @return the filtered content
*/
- void encode(String content, StringBuilder buffer);
+ String encode(String content);
/**
* Encodes the characters into the buffer for use in a quoted value (that
is, an attribute value), converting
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,7 +15,8 @@
package org.apache.tapestry5.dom;
import org.apache.tapestry5.internal.util.PrintOutCollector;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.Defense;
import java.io.PrintWriter;
import java.util.Collections;
@@ -28,6 +29,10 @@
{
private Node container;
+ /**
+ * Child notes; only Element actually has children. Attributes are
modeled differently in this DOM than in
+ * traditional W3C Dom (where Attributes are another type of child node).
+ */
private List<Node> children;
/**
@@ -41,13 +46,21 @@
this.container = container;
}
+ /**
+ * Returns the containing node for this node, or null if this node is the
root element of the document.
+ */
public Node getContainer()
{
return container;
}
+ public Document getDocument()
+ {
+ return container.getDocument();
+ }
+
/**
- * Returns the node as an [EMAIL PROTECTED] Element}, if it is an element.
Returns null otherwise.
+ * Returns the node as an [EMAIL PROTECTED]
org.apache.tapestry5.dom.Element}, if it is an element. Returns null otherwise.
*/
Element asElement()
{
@@ -56,16 +69,25 @@
void addChild(Node child)
{
- if (children == null) children = newList();
+ ensureChildren();
children.add(child);
+
+ child.container = this;
+ }
+
+ private void ensureChildren()
+ {
+ if (children == null) children = CollectionFactory.newList();
}
void insertChildAt(int index, Node child)
{
- if (children == null) children = newList();
+ ensureChildren();
children.add(index, child);
+
+ child.container = this;
}
boolean hasChildren()
@@ -73,7 +95,7 @@
return children != null && !children.isEmpty();
}
- void writeChildMarkup(PrintWriter writer)
+ void writeChildMarkup(Document document, PrintWriter writer)
{
if (children == null) return;
@@ -88,7 +110,7 @@
{
PrintOutCollector collector = new PrintOutCollector();
- writeChildMarkup(collector.getPrintWriter());
+ writeChildMarkup(getDocument(), collector.getPrintWriter());
return collector.getPrintOut();
}
@@ -100,18 +122,176 @@
public String toString()
{
PrintOutCollector collector = new PrintOutCollector();
+
toMarkup(collector.getPrintWriter());
+
return collector.getPrintOut();
}
+ /**
+ * Returns an unmodifiable list of children for this node. Only [EMAIL
PROTECTED] org.apache.tapestry5.dom.Element}s will have
+ * children. Also, note that unlike W3C DOM, attributes are not
represented as [EMAIL PROTECTED]
+ * org.apache.tapestry5.dom.Node}s.
+ *
+ * @return unmodifiable list of children nodes
+ */
@SuppressWarnings("unchecked")
public List<Node> getChildren()
{
- return children == null ? Collections.EMPTY_LIST : children;
+ return children == null ? Collections.EMPTY_LIST :
Collections.unmodifiableList(children);
}
/**
* Writes the markup for this node to the writer.
*/
- public abstract void toMarkup(PrintWriter writer);
+ public void toMarkup(PrintWriter writer)
+ {
+ toMarkup(getDocument(), writer);
+ }
+
+ /**
+ * Implemented by each subclass, with the document passed in for
efficiency.
+ */
+ abstract void toMarkup(Document document, PrintWriter writer);
+
+ /**
+ * Moves this node so that it becomes a sibling of the element, ordered
just before the element.
+ *
+ * @param element to move the node before
+ * @return the node for further modification
+ */
+ public Node moveBefore(Element element)
+ {
+ validateElement(element);
+
+ remove();
+
+ element.getContainer().insertChildBefore(element, this);
+
+ return this;
+ }
+
+
+ /**
+ * Moves this node so that it becomes a sibling of the element, ordered
just after the element.
+ *
+ * @param element to move the node after
+ * @return the node for further modification
+ */
+ public Node moveAfter(Element element)
+ {
+ validateElement(element);
+
+ remove();
+
+ element.getContainer().insertChildAfter(element, this);
+
+ return this;
+ }
+
+ /**
+ * Moves this node so that it becomes this first child of the element,
shifting existing elements forward.
+ *
+ * @param element to move the node inside
+ * @return the node for further modification
+ */
+ public Node moveToTop(Element element)
+ {
+ validateElement(element);
+
+ remove();
+
+ element.insertChildAt(0, this);
+
+ return this;
+ }
+
+ /**
+ * Moves this node so that it the last child of the element.
+ *
+ * @param element to move the node inside
+ * @return the node for further modification
+ */
+ public Node moveToBottom(Element element)
+ {
+ validateElement(element);
+
+ remove();
+
+ element.addChild(this);
+
+ return this;
+ }
+
+ private void validateElement(Element element)
+ {
+ Defense.notNull(element, "element");
+
+ Node search = element;
+ while (search != null)
+ {
+ if (search.equals(this))
+ {
+ throw new IllegalArgumentException("Unable to move a node
relative to itself.");
+ }
+
+ search = search.getContainer();
+ }
+ }
+
+ /**
+ * Removes a node from its container, setting its container property to
null, and removing it from its container's
+ * list of children.
+ */
+ public void remove()
+ {
+ getContainer().remove(this);
+
+ container = null;
+ }
+
+
+ /**
+ * Removes a child node from this node.
+ */
+ void remove(Node node)
+ {
+ if (children == null || !children.remove(node))
+ throw new IllegalArgumentException("Node to remove was not present
as a child of this node.");
+ }
+
+ private void insertChildBefore(Node existing, Node node)
+ {
+ int index = indexOfNode(existing);
+
+ children.add(index, node);
+
+ node.container = this;
+ }
+
+ private void insertChildAfter(Node existing, Node node)
+ {
+ int index = indexOfNode(existing);
+
+ children.add(index + 1, node);
+
+ node.container = this;
+ }
+
+
+ private int indexOfNode(Node node)
+ {
+ ensureChildren();
+
+ int index = children.indexOf(node);
+
+ if (index < 0) throw new IllegalArgumentException("Existing element
not a child of this node.");
+
+ return index;
+ }
+
+ void clearChildren()
+ {
+ children = null;
+ }
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -34,9 +34,8 @@
* Prints the text exactly as is, no translations, filtering, etc.
*/
@Override
- public void toMarkup(PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer)
{
writer.print(text);
}
-
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,14 +23,10 @@
{
private final StringBuilder buffer;
- private final Document document;
-
- Text(Node container, Document document, String text)
+ Text(Node container, String text)
{
super(container);
- this.document = document;
-
buffer = new StringBuilder(text.length());
write(text);
@@ -41,7 +37,7 @@
*/
public void write(String text)
{
- document.getMarkupModel().encode(text, buffer);
+ buffer.append(text);
}
public void writef(String format, Object... args)
@@ -50,9 +46,10 @@
}
@Override
- public void toMarkup(PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer)
{
- writer.print(buffer.toString());
- }
+ String encoded = document.getMarkupModel().encode(buffer.toString());
+ writer.print(encoded);
+ }
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
Thu Sep 4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -465,4 +465,163 @@
assertEquals(d.toString(), "<?xml version=\"1.0\"
encoding=\"utf-8\"?>\n<root/>");
}
+
+ @Test
+ public void move_before()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ root.element("placeholder");
+
+ Element target = root.element("target");
+ Element mobile = root.element("source").element("mobile");
+
+ mobile.text("On the move");
+
+ assertEquals(d.toString(),
+
"<doc><placeholder></placeholder><target></target><source><mobile>On the
move</mobile></source></doc>");
+
+
+ mobile.moveBefore(target);
+
+ assertEquals(d.toString(),
+ "<doc><placeholder></placeholder><mobile>On the
move</mobile><target></target><source></source></doc>");
+ }
+
+ @Test
+ public void move_after()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+ root.element("placeholder");
+
+ Element target = root.element("target");
+ Element mobile = root.element("source").element("mobile");
+
+ mobile.text("On the move");
+
+ assertEquals(d.toString(),
+
"<doc><placeholder></placeholder><target></target><source><mobile>On the
move</mobile></source></doc>");
+
+
+ mobile.moveAfter(target);
+
+ assertEquals(d.toString(),
+
"<doc><placeholder></placeholder><target></target><mobile>On the
move</mobile><source></source></doc>");
+ }
+
+ @Test
+ public void move_to_top()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ Element target = root.element("target");
+ target.element("placeholder");
+ Element mobile = root.element("source").element("mobile");
+
+ mobile.text("On the move");
+
+ assertEquals(d.toString(),
+
"<doc><target><placeholder></placeholder></target><source><mobile>On the
move</mobile></source></doc>");
+
+ mobile.moveToTop(target);
+
+ assertEquals(d.toString(),
+ "<doc><target><mobile>On the
move</mobile><placeholder></placeholder></target><source></source></doc>");
+ }
+
+ @Test
+ public void move_to_bottom()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ Element target = root.element("target");
+ target.element("placeholder");
+ Element mobile = root.element("source").element("mobile");
+
+ mobile.text("On the move");
+
+ assertEquals(d.toString(),
+
"<doc><target><placeholder></placeholder></target><source><mobile>On the
move</mobile></source></doc>");
+
+ mobile.moveToBottom(target);
+
+ assertEquals(d.toString(),
+ "<doc><target><placeholder></placeholder><mobile>On the
move</mobile></target><source></source></doc>");
+ }
+
+ @Test
+ public void remove_children()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ root.element("before");
+ Element source = root.element("source");
+ Element mobile = source.element("mobile");
+ source.element("grok");
+ root.element("after");
+
+ mobile.text("On the move");
+
+ assertEquals(d.toString(),
+ "<doc><before></before><source><mobile>On the
move</mobile><grok></grok></source><after></after></doc>");
+
+ source.removeChildren();
+
+ assertEquals(d.toString(),
+
"<doc><before></before><source></source><after></after></doc>");
+ }
+
+ @Test
+ public void pop()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ Element source = root.element("source");
+ source.element("mobile").text("On the move");
+ source.element("grok");
+
+ assertEquals(d.toString(),
+ "<doc><source><mobile>On the
move</mobile><grok></grok></source></doc>");
+
+ source.pop();
+
+ assertEquals(d.toString(),
+ "<doc><mobile>On the move</mobile><grok></grok></doc>");
+ }
+
+ @Test
+ public void move_an_node_into_itself()
+ {
+ Document d = new Document();
+
+ Element root = d.newRootElement("doc");
+
+ Element target = root.element("target");
+ target.element("placeholder");
+ Element mobile = root.element("source").element("mobile");
+ mobile.text("On the move");
+ Element inside = mobile.element("inside");
+
+ try
+ {
+ mobile.moveToTop(inside);
+ unreachable();
+ }
+ catch (IllegalArgumentException ex)
+ {
+ assertEquals(ex.getMessage(), "Unable to move a node relative to
itself.");
+ }
+ }
}