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
.util
.Collection
;
43 import java
.util
.Collections
;
44 import java
.util
.HashSet
;
45 import java
.util
.Iterator
;
46 import java
.util
.StringTokenizer
;
47 import javax
.xml
.XMLConstants
;
48 import javax
.xml
.namespace
.QName
;
49 import javax
.xml
.transform
.TransformerException
;
50 import org
.w3c
.dom
.Document
;
51 import org
.w3c
.dom
.DocumentFragment
;
52 import org
.w3c
.dom
.Element
;
53 import org
.w3c
.dom
.NamedNodeMap
;
54 import org
.w3c
.dom
.Node
;
55 import gnu
.xml
.xpath
.Expr
;
58 * A template node representing an XSL <code>element</code> instruction.
60 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
62 final class ElementNode
66 final TemplateNode name
;
67 final TemplateNode namespace
;
70 final Collection elementExcludeResultPrefixes
;
72 ElementNode(TemplateNode name
,
73 TemplateNode namespace
, String uas
, Node source
)
76 this.namespace
= namespace
;
79 NamedNodeMap attrs
= source
.getAttributes();
80 Node attr
= attrs
.getNamedItemNS(Stylesheet
.XSL_NS
,
81 "exclude-result-prefixes");
84 elementExcludeResultPrefixes
= new HashSet();
85 StringTokenizer st
= new StringTokenizer(attr
.getNodeValue());
86 while (st
.hasMoreTokens())
87 elementExcludeResultPrefixes
.add(st
.nextToken());
90 elementExcludeResultPrefixes
= Collections
.EMPTY_SET
;
93 TemplateNode
clone(Stylesheet stylesheet
)
95 TemplateNode ret
= new ElementNode(name
.clone(stylesheet
),
96 (namespace
== null) ?
null :
97 namespace
.clone(stylesheet
),
100 ret
.children
= children
.clone(stylesheet
);
102 ret
.next
= next
.clone(stylesheet
);
106 void doApply(Stylesheet stylesheet
, QName mode
,
107 Node context
, int pos
, int len
,
108 Node parent
, Node nextSibling
)
109 throws TransformerException
111 Document doc
= (parent
instanceof Document
) ?
(Document
) parent
:
112 parent
.getOwnerDocument();
113 // Create a document fragment to hold the name
114 DocumentFragment fragment
= doc
.createDocumentFragment();
115 // Apply name to the fragment
116 name
.apply(stylesheet
, mode
,
119 // Use XPath string-value of fragment
120 String nameValue
= Expr
.stringValue(fragment
);
122 String namespaceValue
= null;
123 if (namespace
!= null)
125 // Create a document fragment to hold the namespace
126 fragment
= doc
.createDocumentFragment();
127 // Apply namespace to the fragment
128 namespace
.apply(stylesheet
, mode
,
131 // Use XPath string-value of fragment
132 namespaceValue
= Expr
.stringValue(fragment
);
133 if (namespaceValue
.length() == 0)
134 namespaceValue
= null;
138 String prefix
= getPrefix(nameValue
);
139 if (XMLConstants
.XMLNS_ATTRIBUTE
.equals(prefix
))
141 int ci
= nameValue
.indexOf(':');
142 nameValue
= nameValue
.substring(ci
+ 1);
146 // Namespace aliasing
149 String resultPrefix
=
150 (String
) stylesheet
.namespaceAliases
.get(prefix
);
151 if (resultPrefix
!= null)
153 if ("#default".equals(resultPrefix
))
155 namespaceValue
= source
.lookupNamespaceURI(resultPrefix
);
157 if (prefix
== "#default")
159 // Look up ordinary namespace for this prefix
160 if (namespaceValue
== null)
162 if (XMLConstants
.XML_NS_PREFIX
.equals(prefix
))
163 namespaceValue
= XMLConstants
.XML_NS_URI
;
166 // Resolve namespace for this prefix
167 namespaceValue
= source
.lookupNamespaceURI(prefix
);
174 Element element
= (namespaceValue
!= null) ?
175 doc
.createElementNS(namespaceValue
, nameValue
) :
176 doc
.createElement(nameValue
);
177 if (nextSibling
!= null)
178 parent
.insertBefore(element
, nextSibling
);
180 parent
.appendChild(element
);
181 stylesheet
.addNamespaceNodes(source
, element
, doc
,
182 elementExcludeResultPrefixes
);
185 StringTokenizer st
= new StringTokenizer(uas
, " ");
186 while (st
.hasMoreTokens())
187 addAttributeSet(stylesheet
, mode
, context
, pos
, len
,
188 element
, null, st
.nextToken());
190 if (children
!= null)
191 children
.apply(stylesheet
, mode
,
195 next
.apply(stylesheet
, mode
,
197 parent
, nextSibling
);
200 final String
getPrefix(String name
)
202 int ci
= name
.indexOf(':');
203 return (ci
== -1) ?
null : name
.substring(0, ci
);
206 void addAttributeSet(Stylesheet stylesheet
, QName mode
,
207 Node context
, int pos
, int len
,
208 Node parent
, Node nextSibling
, String attributeSet
)
209 throws TransformerException
211 stylesheet
.bindings
.global
= true;
212 for (Iterator i
= stylesheet
.attributeSets
.iterator(); i
.hasNext(); )
214 AttributeSet as
= (AttributeSet
) i
.next();
215 if (!as
.name
.equals(attributeSet
))
219 StringTokenizer st
= new StringTokenizer(as
.uas
, " ");
220 while (st
.hasMoreTokens())
221 addAttributeSet(stylesheet
, mode
, context
, pos
, len
,
222 parent
, nextSibling
, st
.nextToken());
224 if (as
.children
!= null)
225 as
.children
.apply(stylesheet
, mode
,
227 parent
, nextSibling
);
229 stylesheet
.bindings
.global
= false;
232 public boolean references(QName var
)
234 if (name
!= null && name
.references(var
))
236 if (namespace
!= null && namespace
.references(var
))
238 return super.references(var
);
241 public String
toString()
243 CPStringBuilder buf
= new CPStringBuilder("element");
246 if (namespace
!= null)
248 buf
.append(",namespace=");
249 buf
.append(namespace
);
258 return buf
.toString();