package gnu.xml.transform;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPathVariableResolver;
import org.w3c.dom.Node;
public class Bindings
implements XPathVariableResolver, Cloneable
{
final Stylesheet stylesheet;
final LinkedList variables;
final LinkedList parameters;
Bindings(Stylesheet stylesheet)
{
this.stylesheet = stylesheet;
variables = new LinkedList();
parameters = new LinkedList();
push(true);
push(false);
}
public Object clone()
{
try
{
return (Bindings) super.clone();
}
catch (CloneNotSupportedException e)
{
throw new Error(e.getMessage());
}
}
void push(boolean global)
{
if (global)
{
variables.addFirst(new HashMap());
}
else
{
parameters.addFirst(new HashMap());
}
}
void pop(boolean global)
{
if (global)
{
variables.removeFirst();
}
else
{
parameters.removeFirst();
}
}
public boolean containsKey(String name, boolean global)
{
Iterator i = global ? variables.iterator() : parameters.iterator();
while (i.hasNext())
{
Map ctx = (Map) i.next();
if (ctx.containsKey(name))
{
return true;
}
}
return false;
}
public Object get(String name, Node context, int pos, int len)
{
Object ret = null;
for (Iterator i = variables.iterator(); i.hasNext() && ret == null; )
{
Map vctx = (Map) i.next();
ret = vctx.get(name);
}
if (ret == null)
{
for (Iterator i = parameters.iterator(); i.hasNext() && ret == null; )
{
Map pctx = (Map) i.next();
ret = pctx.get(name);
}
}
if (ret instanceof Node)
{
ret = Collections.singleton(ret);
}
if (ret == null)
{
ret = "";
}
return ret;
}
void set(String name, Object value, boolean global)
{
if (global)
{
Map context = (Map) variables.getFirst();
context.put(name, value);
}
else
{
Map context = (Map) parameters.getFirst();
context.put(name, value);
}
}
public Object resolveVariable(QName qName)
{
return get(qName.toString(), null, 1, 1);
}
public String toString()
{
StringBuffer buf = new StringBuffer();
boolean next = false;
Collection seen = new HashSet();
buf.append('{');
for (Iterator i = variables.iterator(); i.hasNext(); )
{
Map ctx = (Map) i.next();
for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
{
if (next)
{
buf.append(',');
}
else
{
next = true;
}
Map.Entry entry = (Map.Entry) j.next();
Object key = entry.getKey();
if (!seen.contains(key))
{
buf.append(key);
buf.append('=');
buf.append(entry.getValue());
seen.add(key);
}
}
}
for (Iterator i = parameters.iterator(); i.hasNext(); )
{
Map ctx = (Map) i.next();
for (Iterator j = ctx.entrySet().iterator(); j.hasNext(); )
{
if (next)
{
buf.append(',');
}
else
{
next = true;
}
Map.Entry entry = (Map.Entry) j.next();
Object key = entry.getKey();
if (!seen.contains(key))
{
buf.append(key);
buf.append('=');
buf.append(entry.getValue());
seen.add(key);
}
}
}
buf.append('}');
return buf.toString();
}
}