package de.spieleck.config;
import java.io.*;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
import de.spieleck.util.EmptyIterator;
public class ConfigNodeImpl
implements ConfigNode
{
public final static char PATHSEP = '/';
protected ConfigNode parent;
protected List children;
protected String name;
protected String value;
protected ConfigParamMap pm;
public ConfigNodeImpl(String name, String value, ConfigParamMap pm)
{
this.name = name == null ? null : name.intern();
this.value = value;
this.pm = pm;
}
public String getSourceFileName()
{
ConfigFileNode srn = getBranchNode();
if (srn == null)
return null;
else
return srn.getSourceFileName();
}
public ConfigFileNode getBranchNode()
{
ConfigFileNode branchNode = null;
while (branchNode == null)
{
ConfigNode n = getParent();
if (n != null)
branchNode = n.getBranchNode();
}
return branchNode;
}
public String getName()
{
return name;
}
public String getPath()
{
if (getParent() == null)
return ""; else
return getParent().getPath() + PATHSEP + getName();
}
void setValue(String v)
{
value = v;
}
protected String getValue()
{
return pm.expand(value);
}
public ConfigNode getParent()
{
return parent;
}
protected void setParent(ConfigNode p)
{
parent = p;
}
public boolean getBoolean()
{
return ConvertHelp.getBoolean(getValue());
}
public boolean getBoolean(String path, boolean deflt)
{
return ConvertHelp.getBoolean(node(path), deflt);
}
public boolean getInhBoolean(String path, boolean deflt)
{
return ConvertHelp.getBoolean(nodeInh(path), deflt);
}
public int getInt()
{
return ConvertHelp.getInt(getValue());
}
public int getInt(String path, int deflt)
{
return ConvertHelp.getInt(node(path), deflt);
}
public int getInhInt(String path, int deflt)
{
return ConvertHelp.getInt(nodeInh(path), deflt);
}
public double getDouble()
{
return ConvertHelp.getDouble(getValue());
}
public double getDouble(String path, double deflt)
{
return ConvertHelp.getDouble(node(path), deflt);
}
public double getInhDouble(String path, double deflt)
{
return ConvertHelp.getDouble(nodeInh(path), deflt);
}
public String getString()
{
return getValue();
}
public String getString(String path, String deflt)
{
return ConvertHelp.getString(node(path), deflt);
}
public String getInhString(String path, String deflt)
{
return ConvertHelp.getString(nodeInh(path), deflt);
}
public ConfigNode node(String path)
{
if (path == null)
return this;
return node(path, 0, path.length());
}
private ConfigNodeImpl node(String path, int begindex, int endIndex)
{
int head = begindex;
while (head < endIndex && path.charAt(head) == PATHSEP)
head++;
if (head == endIndex)
return this;
if (children == null) return null;
int tail = head + 1;
while (tail < endIndex && path.charAt(tail) != PATHSEP)
tail++;
String match = path.substring(head, tail);
for(Iterator it = children(); it.hasNext(); )
{
ConfigNodeImpl child = (ConfigNodeImpl)it.next();
if (child.getName().equals(match))
{
ConfigNodeImpl node = child.node(path, tail, endIndex);
if (node != null)
return node;
}
}
return null;
}
public ConfigNode nodeInh(String path)
{
ConfigNode snr = node(path);
if (snr != null)
return snr;
ConfigNode current = this;
while (snr == null && (current = current.getParent()) != null)
snr = current.node(path);
return snr;
}
public int countChildren()
{
return children == null
? 0
: children.size();
}
public Iterator children()
{
if ( children == null )
return EmptyIterator.getInstance();
return new ConfigIterator(null);
}
public Iterator childrenNamed(String key)
{
if ( children == null )
return EmptyIterator.getInstance();
return new ConfigIterator(key);
}
public int countChildrenNamed(String key)
{
if ( children == null )
return 0;
Iterator it = childrenNamed(key);
int count = 0;
while ( it.hasNext() )
if ( ((ConfigNode)it.next()).getName().equals(key) )
count++;
return count;
}
public void copyChildren(ConfigNode next)
{
Iterator e = next.children();
while (e.hasNext())
{
ConfigNodeImpl n = (ConfigNodeImpl)e.next();
addChild(n);
}
}
public ConfigNodeImpl addChild(String name, String value)
{
ConfigNodeImpl child = new ConfigNodeImpl(name, value, pm);
return addChild(child);
}
public ConfigNodeImpl addChild(ConfigNodeImpl child)
{
if (children == null)
children = new LinkedList();
children.add(child);
child.setParent(this);
return child;
}
public void print(PrintWriter os)
throws IOException
{
print(os, 0);
}
private void print(PrintWriter os, int depth)
throws IOException
{
spc(os, depth);
os.print("<" + getName());
if (getValue() != null)
os.print(" this=\"" + getValue() + "\"");
int length = countChildren();
boolean hasElementChildren = false;
for ( Iterator it = children(); it.hasNext(); )
{
ConfigNodeImpl child = (ConfigNodeImpl)it.next();
if (!hasElementChildren && !(child.countChildren() > 0) )
os.print(" " + child.getName() + "=\""
+ child.getValue() + "\"");
else
{
if (!hasElementChildren)
os.println(">");
hasElementChildren = true;
child.print(os, depth + 2);
}
}
if (!hasElementChildren)
os.println("/>");
else
{
spc(os, depth);
os.println("</" + getName() + ">");
}
}
private static void spc(PrintWriter os, int depth)
throws IOException
{
for (int i = 0; i < depth; i++)
os.print(' ');
}
public String toString()
{
return "["+super.toString()+"(" + getPath() + ", " + getValue() + "), ("
+ getSourceFileName() + ")" + ", " + countChildren()
+ "]";
}
protected class ConfigIterator
implements Iterator
{
private Iterator it;
private String key = null;
private ConfigNodeImpl ci;
public ConfigIterator(String key)
{
if ( key != null )
this.key = key.intern();
if ( children == null )
it = EmptyIterator.getInstance();
else
it = children.iterator();
skip();
}
private void skip()
{
ci = null;
while ( ci == null && it.hasNext() )
{
ci = (ConfigNodeImpl) it.next();
if ( key != null && key != ci.getName() )
ci = null;
}
}
public boolean hasNext()
{
return ci != null;
}
public Object next()
{
ConfigNodeImpl c2 = ci;
skip();
return c2;
}
public void remove()
throws UnsupportedOperationException
{
throw new UnsupportedOperationException("Config is immutable.");
}
}
}