Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / gnu / xml / transform / AttributeNode.java
blobbc5bc30c9c17e55837a6dcc589f9290920f09988
1 /* AttributeNode.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 javax.xml.XMLConstants;
41 import javax.xml.namespace.QName;
42 import javax.xml.transform.TransformerException;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.DocumentFragment;
45 import org.w3c.dom.Attr;
46 import org.w3c.dom.NamedNodeMap;
47 import org.w3c.dom.Node;
48 import gnu.xml.xpath.Expr;
50 /**
51 * A template node representing an XSL <code>attribute</code> instruction.
53 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
55 final class AttributeNode
56 extends TemplateNode
59 final TemplateNode name;
60 final TemplateNode namespace;
61 final Node source;
63 AttributeNode(TemplateNode name,
64 TemplateNode namespace, Node source)
66 this.name = name;
67 this.namespace = namespace;
68 this.source = source;
71 TemplateNode clone(Stylesheet stylesheet)
73 TemplateNode ret = new AttributeNode(name.clone(stylesheet),
74 (namespace == null) ? null :
75 namespace.clone(stylesheet),
76 source);
77 if (children != null)
78 ret.children = children.clone(stylesheet);
79 if (next != null)
80 ret.next = next.clone(stylesheet);
81 return ret;
84 void doApply(Stylesheet stylesheet, QName mode,
85 Node context, int pos, int len,
86 Node parent, Node nextSibling)
87 throws TransformerException
89 Document doc = (parent instanceof Document) ? (Document) parent :
90 parent.getOwnerDocument();
91 // Create a document fragment to hold the name
92 DocumentFragment fragment = doc.createDocumentFragment();
93 // Apply name to the fragment
94 name.apply(stylesheet, mode,
95 context, pos, len,
96 fragment, null);
97 // Use XPath string-value of fragment
98 String nameValue = Expr.stringValue(fragment);
100 String namespaceValue = null;
101 if (namespace != null)
103 // Create a document fragment to hold the namespace
104 fragment = doc.createDocumentFragment();
105 // Apply namespace to the fragment
106 namespace.apply(stylesheet, mode,
107 context, pos, len,
108 fragment, null);
109 // Use XPath string-value of fragment
110 namespaceValue = Expr.stringValue(fragment);
111 if (namespaceValue.length() == 0)
112 namespaceValue = null;
115 String prefix = getPrefix(nameValue);
116 if (namespaceValue == null)
118 if (prefix != null)
120 if (XMLConstants.XML_NS_PREFIX.equals(prefix))
121 namespaceValue = XMLConstants.XML_NS_URI;
122 else
124 // Resolve namespace for this prefix
125 namespaceValue = source.lookupNamespaceURI(prefix);
129 else
131 if (prefix != null)
133 String ns2 = source.lookupNamespaceURI(prefix);
134 if (ns2 != null && !ns2.equals(namespaceValue))
136 // prefix clashes, reset it
137 prefix = null;
138 int ci = nameValue.indexOf(':');
139 nameValue = nameValue.substring(ci + 1);
143 if (prefix == null)
145 // Resolve prefix for this namespace
146 prefix = source.lookupPrefix(namespaceValue);
147 if (prefix != null)
148 nameValue = prefix + ":" + nameValue;
149 else
151 if (namespaceValue != null)
153 // Must invent a prefix
154 prefix = inventPrefix(parent);
155 nameValue = prefix + ":" + nameValue;
159 NamedNodeMap attrs = parent.getAttributes();
160 boolean insert = true;
161 if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceValue) ||
162 XMLConstants.XMLNS_ATTRIBUTE.equals(nameValue) ||
163 nameValue.startsWith("xmlns:"))
165 // Namespace declaration, do not output
166 insert = false;
168 if (prefix != null && namespaceValue == null)
170 // Not a QName
171 insert = false;
173 if (parent.getNodeType() == Node.ELEMENT_NODE &&
174 parent.getFirstChild() != null)
176 // XSLT 7.1.3 Adding an attribute to an element after children have
177 // been added to it is an error
178 insert = false;
180 if (insert)
182 // Insert attribute
183 Attr attr = (namespaceValue != null) ?
184 doc.createAttributeNS(namespaceValue, nameValue) :
185 doc.createAttribute(nameValue);
186 if (attrs != null)
188 if (namespace != null)
189 attrs.setNamedItemNS(attr);
190 else
191 attrs.setNamedItem(attr);
193 if (children != null)
194 children.apply(stylesheet, mode,
195 context, pos, len,
196 attr, null);
198 if (next != null)
199 next.apply(stylesheet, mode,
200 context, pos, len,
201 parent, nextSibling);
204 final String getPrefix(String name)
206 int ci = name.indexOf(':');
207 return (ci == -1) ? null : name.substring(0, ci);
210 final String inventPrefix(Node parent)
212 String base = "ns";
213 int count = 0;
214 String ret = base + Integer.toString(count);
215 while (parent.lookupNamespaceURI(ret) != null)
217 count++;
218 ret = base + Integer.toString(count);
220 return ret;
223 public boolean references(QName var)
225 if (name != null && name.references(var))
226 return true;
227 if (namespace != null && namespace.references(var))
228 return true;
229 return super.references(var);
232 public String toString()
234 StringBuffer buf = new StringBuffer(getClass().getName());
235 buf.append('[');
236 buf.append("name=");
237 buf.append(name);
238 buf.append(']');
239 return buf.toString();