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)
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
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
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
;
54 * A template in an XSL stylesheet.
56 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
62 static final double DEFAULT_PRIORITY
= 0.5d
;
64 final Stylesheet stylesheet
;
67 final TemplateNode node
;
68 final double priority
;
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
;
81 this.precedence
= precedence
;
84 double p
= DEFAULT_PRIORITY
;
86 if (priorityAttr
!= null)
87 p
= Double
.parseDouble(priorityAttr
);
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();
99 if (test
instanceof NameTest
)
101 NameTest nameTest
= (NameTest
) test
;
102 if (nameTest
.matchesAny())
104 else if (nameTest
.matchesAnyLocalName())
111 NodeTypeTest nodeTypeTest
= (NodeTypeTest
) test
;
112 if (nodeTypeTest
.getNodeType() ==
113 Node
.PROCESSING_INSTRUCTION_NODE
&&
114 nodeTypeTest
.getData() != null)
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;
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
;
138 this.precedence
= precedence
;
139 this.priority
= priority
;
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
,
150 (match
== null) ?
null :
151 (Pattern
) match
.clone(stylesheet
),
152 (node
== null) ?
null : node
.clone(stylesheet
),
159 public int compareTo(Object other
)
161 if (other
instanceof Template
)
163 Template t
= (Template
) other
;
164 int d
= t
.precedence
- precedence
;
167 double d2
= t
.priority
- priority
;
169 return (int) Math
.round(d2
* 1000.0d
);
174 Test
getNodeTest(Expr expr
)
179 boolean matches(QName mode
, Node node
)
181 if ((mode
== null && this.mode
!= null) ||
182 (mode
!= null && !mode
.equals(this.mode
)))
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
;
202 if (ctx
== stylesheet
)
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
);
224 node
.apply(stylesheet
, mode
,
226 parent
, nextSibling
);
229 public String
toString()
231 CPStringBuilder buf
= new CPStringBuilder(getClass().getName());
238 else if (match
!= null)
240 buf
.append("match=");
245 buf
.append(",mode=");
248 buf
.append(",node=");
251 return buf
.toString();
253 //return (name != null) ? name.toString() : match.toString();
256 void list(PrintStream out
)
258 out
.println(toString());
260 node
.list(1, out
, true);