libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / gnu / xml / transform / ElementNode.java
blobc5a4dd20da415278a3b5be7df282d4e0a8d1c867
1 /* ElementNode.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.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;
57 /**
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
63 extends TemplateNode
66 final TemplateNode name;
67 final TemplateNode namespace;
68 final String uas;
69 final Node source;
70 final Collection elementExcludeResultPrefixes;
72 ElementNode(TemplateNode name,
73 TemplateNode namespace, String uas, Node source)
75 this.name = name;
76 this.namespace = namespace;
77 this.uas = uas;
78 this.source = source;
79 NamedNodeMap attrs = source.getAttributes();
80 Node attr = attrs.getNamedItemNS(Stylesheet.XSL_NS,
81 "exclude-result-prefixes");
82 if (attr != null)
84 elementExcludeResultPrefixes = new HashSet();
85 StringTokenizer st = new StringTokenizer(attr.getNodeValue());
86 while (st.hasMoreTokens())
87 elementExcludeResultPrefixes.add(st.nextToken());
89 else
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),
98 uas, source);
99 if (children != null)
100 ret.children = children.clone(stylesheet);
101 if (next != null)
102 ret.next = next.clone(stylesheet);
103 return ret;
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,
117 context, pos, len,
118 fragment, null);
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,
129 context, pos, len,
130 fragment, null);
131 // Use XPath string-value of fragment
132 namespaceValue = Expr.stringValue(fragment);
133 if (namespaceValue.length() == 0)
134 namespaceValue = null;
136 else
138 String prefix = getPrefix(nameValue);
139 if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
141 int ci = nameValue.indexOf(':');
142 nameValue = nameValue.substring(ci + 1);
144 else
146 // Namespace aliasing
147 if (prefix == null)
148 prefix = "#default";
149 String resultPrefix =
150 (String) stylesheet.namespaceAliases.get(prefix);
151 if (resultPrefix != null)
153 if ("#default".equals(resultPrefix))
154 resultPrefix = null;
155 namespaceValue = source.lookupNamespaceURI(resultPrefix);
157 if (prefix == "#default")
158 prefix = null;
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;
164 else
166 // Resolve namespace for this prefix
167 namespaceValue = source.lookupNamespaceURI(prefix);
173 // Create element
174 Element element = (namespaceValue != null) ?
175 doc.createElementNS(namespaceValue, nameValue) :
176 doc.createElement(nameValue);
177 if (nextSibling != null)
178 parent.insertBefore(element, nextSibling);
179 else
180 parent.appendChild(element);
181 stylesheet.addNamespaceNodes(source, element, doc,
182 elementExcludeResultPrefixes);
183 if (uas != null)
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,
192 context, pos, len,
193 element, null);
194 if (next != null)
195 next.apply(stylesheet, mode,
196 context, pos, len,
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))
216 continue;
217 if (as.uas != null)
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,
226 context, pos, len,
227 parent, nextSibling);
229 stylesheet.bindings.global = false;
232 public boolean references(QName var)
234 if (name != null && name.references(var))
235 return true;
236 if (namespace != null && namespace.references(var))
237 return true;
238 return super.references(var);
241 public String toString()
243 CPStringBuilder buf = new CPStringBuilder("element");
244 buf.append('[');
245 buf.append("name=");
246 if (namespace != null)
248 buf.append(",namespace=");
249 buf.append(namespace);
251 buf.append(name);
252 if (uas != null)
254 buf.append(",uas=");
255 buf.append(uas);
257 buf.append(']');
258 return buf.toString();