OSDN Git Service

ed4358c90b6dfc9af61dfa3670b80e57071ec18a
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / xml / transform / CopyOfNode.java
1 /* CopyOfNode.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.ArrayList;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Iterator;
44 import java.util.List;
45 import javax.xml.namespace.QName;
46 import javax.xml.transform.TransformerException;
47 import org.w3c.dom.Document;
48 import org.w3c.dom.NamedNodeMap;
49 import org.w3c.dom.Node;
50 import org.w3c.dom.Text;
51 import gnu.xml.xpath.Expr;
52
53 /**
54  * A template node representing an XSLT <code>copy-of</code> instruction.
55  *
56  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
57  */
58 final class CopyOfNode
59   extends TemplateNode
60 {
61
62   final Expr select;
63
64   CopyOfNode(Expr select)
65   {
66     this.select = select;
67   }
68
69   TemplateNode clone(Stylesheet stylesheet)
70   {
71     TemplateNode ret = new CopyOfNode(select.clone(stylesheet));
72     if (children != null)
73       ret.children = children.clone(stylesheet);
74     if (next != null)
75       ret.next = next.clone(stylesheet);
76     return ret;
77   }
78
79   void doApply(Stylesheet stylesheet, QName mode,
80                Node context, int pos, int len,
81                Node parent, Node nextSibling)
82     throws TransformerException
83   {
84     Object ret = select.evaluate(context, pos, len);
85     Document doc = (parent instanceof Document) ? (Document) parent :
86       parent.getOwnerDocument();
87     if (ret instanceof Collection)
88       {
89         Collection ns = (Collection) ret;
90         List list = new ArrayList(ns);
91         Collections.sort(list, documentOrderComparator);
92         for (Iterator i = list.iterator(); i.hasNext(); )
93           {
94             Node src = (Node) i.next();
95             short nodeType = src.getNodeType();
96             if (nodeType == Node.DOCUMENT_NODE)
97               {
98                 // Use document element
99                 src = ((Document) src).getDocumentElement();
100                 if (src == null)
101                   continue;
102                 nodeType = Node.ELEMENT_NODE;
103               }
104             else if (nodeType == Node.ATTRIBUTE_NODE)
105               {
106                 if (parent.getFirstChild() != null)
107                   {
108                     // Ignore attempt to add attribute after children
109                     continue;
110                   }
111               }
112             if (parent.getNodeType() == Node.ATTRIBUTE_NODE &&
113                 nodeType != Node.TEXT_NODE &&
114                 nodeType != Node.ENTITY_REFERENCE_NODE)
115               {
116                 // Ignore
117                 continue;
118               }
119             Node node = src.cloneNode(true);
120             node = doc.adoptNode(node);
121             if (nodeType == Node.ATTRIBUTE_NODE)
122               {
123                 NamedNodeMap attrs = parent.getAttributes();
124                 if (attrs != null)
125                   attrs.setNamedItemNS(node);
126               }
127             else
128               {
129                 if (nextSibling != null)
130                   parent.insertBefore(node, nextSibling);
131                 else
132                   parent.appendChild(node);
133               }
134           }
135       }
136     else
137       {
138         String value = Expr._string(context, ret);
139         if (value != null && value.length() > 0)
140           {
141             Text textNode = doc.createTextNode(value);
142             if (nextSibling != null)
143               parent.insertBefore(textNode, nextSibling);
144             else
145               parent.appendChild(textNode);
146           }
147       }
148     // copy-of doesn't process children
149     if (next != null)
150       next.apply(stylesheet, mode,
151                  context, pos, len,
152                  parent, nextSibling);
153   }
154   
155   public boolean references(QName var)
156   {
157     if (select != null && select.references(var))
158       return true;
159     return super.references(var);
160   }
161   
162   public String toString()
163   {
164     StringBuffer buf = new StringBuffer("copy-of");
165     buf.append('[');
166     buf.append("select=");
167     buf.append(select);
168     buf.append(']');
169     return buf.toString();
170   }
171   
172 }