libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / gnu / xml / transform / Template.java
blob7ddef0ae50ecc711b53860570a0fb1e4f59e04b3
1 /* Template.java --
2 Copyright (C) 2004,2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.xml.transform;
40 import gnu.java.lang.CPStringBuilder;
42 import java.io.PrintStream;
43 import javax.xml.namespace.QName;
44 import javax.xml.transform.TransformerException;
45 import org.w3c.dom.Node;
46 import gnu.xml.xpath.Expr;
47 import gnu.xml.xpath.NameTest;
48 import gnu.xml.xpath.NodeTypeTest;
49 import gnu.xml.xpath.Pattern;
50 import gnu.xml.xpath.Selector;
51 import gnu.xml.xpath.Test;
53 /**
54 * A template in an XSL stylesheet.
56 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
58 class Template
59 implements Comparable
62 static final double DEFAULT_PRIORITY = 0.5d;
64 final Stylesheet stylesheet;
65 final QName name;
66 final Pattern match;
67 final TemplateNode node;
68 final double priority;
69 final int precedence;
70 final QName mode;
71 final boolean isAnyNode; // is the match simply "node()"?
73 Template(Stylesheet stylesheet,
74 QName name, Pattern match, TemplateNode node,
75 int precedence, String priorityAttr, QName mode)
77 this.stylesheet = stylesheet;
78 this.name = name;
79 this.match = match;
80 this.node = node;
81 this.precedence = precedence;
82 this.mode = mode;
84 double p = DEFAULT_PRIORITY;
85 boolean a = false;
86 if (priorityAttr != null)
87 p = Double.parseDouble(priorityAttr);
88 else
90 // adjust priority if necessary
91 // see XSLT section 5.5
92 if (match instanceof Selector)
94 Selector selector = (Selector) match;
95 Test[] tests = selector.getTests();
96 if (tests.length > 0)
98 Test test = tests[0];
99 if (test instanceof NameTest)
101 NameTest nameTest = (NameTest) test;
102 if (nameTest.matchesAny())
103 p = -0.25d;
104 else if (nameTest.matchesAnyLocalName())
105 p = -0.20d;
106 else
107 p = 0.0d;
109 else
111 NodeTypeTest nodeTypeTest = (NodeTypeTest) test;
112 if (nodeTypeTest.getNodeType() ==
113 Node.PROCESSING_INSTRUCTION_NODE &&
114 nodeTypeTest.getData() != null)
115 p = 0.0d;
116 else
117 p = -0.5d;
118 a = (nodeTypeTest.getNodeType() == 0);
120 // Add a small difference for predicates
121 if (tests.length > 1)
122 p += ((double) tests.length - 1) * 0.001;
126 this.priority = p;
127 this.isAnyNode = a;
130 private Template(Stylesheet stylesheet,
131 QName name, Pattern match, TemplateNode node,
132 int precedence, double priority, QName mode, boolean isAnyNode)
134 this.stylesheet = stylesheet;
135 this.name = name;
136 this.match = match;
137 this.node = node;
138 this.precedence = precedence;
139 this.priority = priority;
140 this.mode = mode;
141 this.isAnyNode = isAnyNode;
144 Template clone(Stylesheet stylesheet)
146 // FIXME by cloning we lose the imports() functionality, so
147 // apply-imports will be broken.
148 return new Template(stylesheet,
149 name,
150 (match == null) ? null :
151 (Pattern) match.clone(stylesheet),
152 (node == null) ? null : node.clone(stylesheet),
153 precedence,
154 priority,
155 mode,
156 isAnyNode);
159 public int compareTo(Object other)
161 if (other instanceof Template)
163 Template t = (Template) other;
164 int d = t.precedence - precedence;
165 if (d != 0)
166 return d;
167 double d2 = t.priority - priority;
168 if (d2 != 0.0d)
169 return (int) Math.round(d2 * 1000.0d);
171 return 0;
174 Test getNodeTest(Expr expr)
176 return null;
179 boolean matches(QName mode, Node node)
181 if ((mode == null && this.mode != null) ||
182 (mode != null && !mode.equals(this.mode)))
183 return false;
184 if (match == null)
185 return false;
186 if (isAnyNode && node.getNodeType() == Node.DOCUMENT_NODE)
187 return false; // don't match document node
188 return match.matches(node);
191 boolean matches(QName name)
193 return name.equals(this.name);
196 boolean imports(Template other)
198 for (Stylesheet ctx = other.stylesheet.parent;
199 ctx != null;
200 ctx = ctx.parent)
202 if (ctx == stylesheet)
203 return true;
205 return false;
209 * @param stylesheet the stylesheet
210 * @param parent the parent of result nodes
211 * @param context the context node in the source document
212 * @param pos the context position
213 * @param len the context size
214 * @param nextSibling if non-null, add result nodes before this node
216 void apply(Stylesheet stylesheet, QName mode,
217 Node context, int pos, int len,
218 Node parent, Node nextSibling)
219 throws TransformerException
221 if (stylesheet.debug)
222 System.err.println("...applying " + toString() + " to " + context);
223 if (node != null)
224 node.apply(stylesheet, mode,
225 context, pos, len,
226 parent, nextSibling);
229 public String toString()
231 CPStringBuilder buf = new CPStringBuilder(getClass().getName());
232 buf.append('[');
233 if (name != null)
235 buf.append("name=");
236 buf.append(name);
238 else if (match != null)
240 buf.append("match=");
241 buf.append(match);
243 if (mode != null)
245 buf.append(",mode=");
246 buf.append(mode);
248 buf.append(",node=");
249 buf.append(node);
250 buf.append(']');
251 return buf.toString();
253 //return (name != null) ? name.toString() : match.toString();
256 void list(PrintStream out)
258 out.println(toString());
259 if (node != null)
260 node.list(1, out, true);