OSDN Git Service

Imported GNU Classpath 0.20
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / xml / transform / LiteralNode.java
1 /* LiteralNode.java -- 
2    Copyright (C) 2004,2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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.
20
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.
25
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. */
37
38 package gnu.xml.transform;
39
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.HashSet;
43 import java.util.StringTokenizer;
44 import javax.xml.namespace.QName;
45 import javax.xml.transform.TransformerException;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.NamedNodeMap;
48 import org.w3c.dom.Node;
49
50 /**
51  * A template node that copies a DOM node in the template to the result
52  * tree.
53  *
54  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
55  */
56 final class LiteralNode
57   extends TemplateNode
58 {
59
60   /**
61    * The source node in the XSL template.
62    */
63   final Node source;
64
65   final Collection elementExcludeResultPrefixes;
66
67   LiteralNode(Node source)
68   {
69     this.source = source;
70     if (source.getNodeType() == Node.ELEMENT_NODE)
71       {
72         NamedNodeMap attrs = source.getAttributes();
73         Node attr = attrs.getNamedItemNS(Stylesheet.XSL_NS,
74                                          "exclude-result-prefixes");
75         if (attr != null)
76           {
77             elementExcludeResultPrefixes = new HashSet();
78             StringTokenizer st = new StringTokenizer(attr.getNodeValue());
79             while (st.hasMoreTokens())
80               elementExcludeResultPrefixes.add(st.nextToken());
81           }
82         else
83           elementExcludeResultPrefixes = Collections.EMPTY_SET;
84       }
85     else
86       elementExcludeResultPrefixes = null;
87   }
88
89   TemplateNode clone(Stylesheet stylesheet)
90   {
91     TemplateNode ret = new LiteralNode(source);
92     if (children != null)
93       ret.children = children.clone(stylesheet);
94     if (next != null)
95       ret.next = next.clone(stylesheet);
96     return ret;
97   }
98
99   void doApply(Stylesheet stylesheet, QName mode,
100                Node context, int pos, int len,
101                Node parent, Node nextSibling)
102     throws TransformerException
103   {
104     Node result = null;
105     Document doc = (parent instanceof Document) ? (Document) parent :
106       parent.getOwnerDocument();
107     short nodeType = source.getNodeType();
108     if (nodeType == Node.ATTRIBUTE_NODE &&
109         parent.getFirstChild() != null)
110       {
111         // Ignore attributes added after child elements
112       }
113     else
114       {
115         // Namespace aliasing
116         if (nodeType == Node.ELEMENT_NODE)
117           {
118             String prefix = source.getPrefix();
119             if (prefix == null)
120               prefix = "#default";
121             String resultPrefix =
122               (String) stylesheet.namespaceAliases.get(prefix);
123             if (resultPrefix != null)
124               {
125                 if ("#default".equals(resultPrefix))
126                   resultPrefix = null;
127                 String uri = source.lookupNamespaceURI(resultPrefix);
128                 String name = source.getNodeName();
129                 // Create a new element node in the result document
130                 result = doc.createElementNS(uri, name);
131                 // copy attributes
132                 NamedNodeMap srcAttrs = source.getAttributes();
133                 NamedNodeMap dstAttrs = result.getAttributes();
134                 int l = srcAttrs.getLength();
135                 for (int i = 0; i < l; i++)
136                   {
137                     Node attr = srcAttrs.item(i);
138                     if (!Stylesheet.XSL_NS.equals(attr.getNamespaceURI()))
139                       {
140                         attr = attr.cloneNode(true);
141                         attr = doc.adoptNode(attr);
142                         dstAttrs.setNamedItemNS(attr);
143                       }
144                   }
145               }
146           }
147         if (result == null)
148           {
149             // Create result node
150             result = source.cloneNode(false);
151             // Remove any XSL attributes
152             NamedNodeMap attrs = result.getAttributes();
153             if (attrs != null)
154               {
155                 int l = attrs.getLength();
156                 for (int i = 0; i < l; i++)
157                   {
158                     Node attr = attrs.item(i);
159                     if (Stylesheet.XSL_NS.equals(attr.getNamespaceURI()))
160                       {
161                         attrs.removeNamedItem(attr.getNodeName());
162                         i--;
163                         l--;
164                       }
165                   }
166               }
167             Node result2 = doc.adoptNode(result);
168             if (result2 == null)
169               {
170                 String msg = "Error adopting node to result tree: " +
171                   result + " (" + result.getClass().getName() + ")";
172                 DOMSourceLocator l = new DOMSourceLocator(context);
173                 throw new TransformerException(msg, l);
174               }
175             result = result2;
176           }
177         if (nextSibling != null)
178           parent.insertBefore(result, nextSibling);
179         else
180           parent.appendChild(result);
181         if (nodeType == Node.ELEMENT_NODE)
182           stylesheet.addNamespaceNodes(source, result, doc,
183                                        elementExcludeResultPrefixes);
184         // children
185         if (children != null)
186           children.apply(stylesheet, mode,
187                          context, pos, len,
188                          result, null);
189       }
190     // next sibling
191     if (next != null)
192       next.apply(stylesheet, mode,
193                  context, pos, len,
194                  parent, nextSibling);
195   }
196
197   public String toString()
198   {
199     StringBuffer buf = new StringBuffer(getClass().getName());
200     buf.append('[');
201     buf.append("source=");
202     buf.append(source);
203     buf.append(']');
204     return buf.toString();
205   }
206   
207 }