/*
* Copyright (c) 2008, Aaron Digulla
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Aaron Digulla nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package de.pdark.decentxml;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* This class contains all the code necessary to implement nodes
* which can have child nodes (like Document or Element).
*
* @author digulla
*
*/
public abstract class NodeWithChildren implements Parent
{
private List<Node> nodes;
public NodeWithChildren addNode (Node node)
{
addNode (nodes == null ? 0 : nodes.size (), node);
return this;
}
public NodeWithChildren addNode (int index, Node node)
{
if (nodes == null)
nodes = new ArrayList<Node> ();
nodes.add (index, node);
if (node instanceof Child)
{
Child child = (Child)node;
child.setParent (this);
}
return this;
}
public NodeWithChildren addNodes (Collection<? extends Node> nodes)
{
return addNodes (this.nodes == null ? 0 : this.nodes.size (), nodes);
}
public NodeWithChildren addNodes (int index, Collection<? extends Node> nodes)
{
for (Node node: nodes)
addNode (index++, node);
return this;
}
public NodeWithChildren addNodes (Node... nodes)
{
return addNodes (this.nodes == null ? 0 : this.nodes.size (), nodes);
}
public NodeWithChildren addNodes (int index, Node... nodes)
{
for (Node node: nodes)
addNode (index++, node);
return this;
}
public List<Node> getNodes ()
{
if (nodes == null)
return Collections.emptyList ();
return nodes;
}
public boolean hasNodes ()
{
return nodeCount () != 0;
}
public int nodeCount ()
{
return nodes == null ? 0 : nodes.size ();
}
public int nodeIndexOf (Node node)
{
if (nodes == null)
return -1;
return nodes.indexOf (node);
}
public Node getNode (int index)
{
if (nodes == null)
throw new IndexOutOfBoundsException ("Cannot return child "+index+", node has only "+0+" child nodes");
else if (index < 0 || index >= nodes.size ())
throw new IndexOutOfBoundsException ("Cannot return child "+index+", node has only "+nodes.size ()+" child nodes");
return nodes.get (index);
}
public Node removeNode (int index)
{
Node n = nodes.remove (index);
if (n instanceof Child)
((Child)n).setParent (null);
return n;
}
public boolean removeNode (Node n)
{
if (nodes == null)
return false;
if (nodes.remove (n))
{
if (n instanceof Child)
{
((Child)n).setParent (null);
}
return true;
}
return false;
}
public List<Node> getNodes (NodeFilter filter)
{
if (nodes == null)
return Collections.emptyList ();
List<Node> result = new ArrayList<Node> (nodes.size ());
for (Node n: nodes)
{
if (filter.matches (n))
{
result.add ((Element)n);
}
}
return result;
}
public NodeWithChildren clearNodes ()
{
if (nodes != null)
nodes.clear ();
return this;
}
public String toXML ()
{
return BasicNode.toXML (this);
}
public NodeWithChildren toXML (XMLWriter writer) throws IOException
{
writer.writeChildNodes (this);
return this;
}
@Override
public String toString ()
{
return toXML ();
}
public NodeWithChildren copy (Node orig)
{
NodeWithChildren other = (NodeWithChildren)orig;
if (other.nodes != null)
{
for (Node n: other.nodes)
{
Node copy = n.createClone ();
copy.copy (n);
addNode (copy);
}
}
return this;
}
public NodeWithChildren copy ()
{
NodeWithChildren n = (NodeWithChildren)createClone ();
n.copy (this);
return n;
}
}
|