package gnu.xml.transform;
import java.io.PrintStream;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Node;
import gnu.xml.xpath.Expr;
import gnu.xml.xpath.NameTest;
import gnu.xml.xpath.NodeTypeTest;
import gnu.xml.xpath.Pattern;
import gnu.xml.xpath.Selector;
import gnu.xml.xpath.Test;
class Template
implements Comparable
{
static final double DEFAULT_PRIORITY = 0.5d;
final Stylesheet stylesheet;
final QName name;
final Pattern match;
final TemplateNode node;
final double priority;
final int precedence;
final QName mode;
Template(Stylesheet stylesheet,
QName name, Pattern match, TemplateNode node,
int precedence, double priority, QName mode)
{
this.stylesheet = stylesheet;
this.name = name;
this.match = match;
this.node = node;
Test test = getNodeTest(match);
if (test != null)
{
if (test instanceof NameTest)
{
NameTest nameTest = (NameTest) test;
if (nameTest.matchesAny() ||
nameTest.matchesAnyLocalName())
{
priority = -0.25d;
}
else
{
priority = 0.0d;
}
}
else
{
NodeTypeTest nodeTypeTest = (NodeTypeTest) test;
if (nodeTypeTest.getNodeType() ==
Node.PROCESSING_INSTRUCTION_NODE &&
nodeTypeTest.getData() != null)
{
priority = 0.0d;
}
else
{
priority = -0.5d;
}
}
}
this.precedence = precedence;
this.priority = priority;
this.mode = mode;
}
Template clone(Stylesheet stylesheet)
{
return new Template(stylesheet,
name,
(match == null) ? null :
(Pattern) match.clone(stylesheet),
(node == null) ? null : node.clone(stylesheet),
precedence,
priority,
mode);
}
public int compareTo(Object other)
{
if (other instanceof Template)
{
Template t = (Template) other;
int d = t.precedence - precedence;
if (d != 0)
{
return d;
}
double d2 = t.priority - priority;
if (d2 != 0.0d)
{
return (int) Math.round(d2 * 1000.0d);
}
}
return 0;
}
Test getNodeTest(Expr expr)
{
if (expr instanceof Selector)
{
Selector selector = (Selector) expr;
Test[] tests = selector.getTests();
if (tests.length > 0)
{
return tests[0];
}
}
return null;
}
boolean matches(QName mode, Node node)
{
if ((mode == null && this.mode != null) ||
(mode != null && !mode.equals(this.mode)))
{
return false;
}
if (match == null)
{
return false;
}
return match.matches(node);
}
boolean matches(QName name)
{
return name.equals(this.name);
}
boolean imports(Template other)
{
for (Stylesheet ctx = other.stylesheet.parent;
ctx != null;
ctx = ctx.parent)
{
if (ctx == stylesheet)
{
return true;
}
}
return false;
}
void apply(Stylesheet stylesheet, QName mode,
Node context, int pos, int len,
Node parent, Node nextSibling)
throws TransformerException
{
if (node != null)
{
node.apply(stylesheet, mode,
context, pos, len,
parent, nextSibling);
}
}
public String toString()
{
StringBuffer buf = new StringBuffer(getClass().getName());
buf.append('[');
if (name != null)
{
buf.append("name=");
buf.append(name);
}
else if (match != null)
{
buf.append("match=");
buf.append(match);
}
if (mode != null)
{
buf.append(",mode=");
buf.append(mode);
}
buf.append(']');
return buf.toString();
}
void list(PrintStream out)
{
out.println(toString());
if (node != null)
{
node.list(1, out, true);
}
}
}