Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / gnu / xml / transform / KeyFunction.java
bloba705dc6b0098587b1bf45c7eec0463e2dda76d14
1 /* KeyFunction.java --
2 Copyright (C) 2004 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 java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Iterator;
44 import java.util.LinkedHashSet;
45 import java.util.LinkedList;
46 import java.util.List;
47 import javax.xml.namespace.QName;
48 import javax.xml.xpath.XPathFunction;
49 import javax.xml.xpath.XPathFunctionException;
50 import org.w3c.dom.Document;
51 import org.w3c.dom.Node;
52 import gnu.xml.xpath.Expr;
53 import gnu.xml.xpath.Function;
54 import gnu.xml.xpath.Pattern;
56 /**
57 * The XSLT <code>key()</code>function.
59 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
61 final class KeyFunction
62 extends Pattern
63 implements XPathFunction, Function
66 final Stylesheet stylesheet;
67 List args;
69 KeyFunction(Stylesheet stylesheet)
71 this.stylesheet = stylesheet;
74 public Object evaluate(List args)
75 throws XPathFunctionException
77 // Useless...
78 return Collections.EMPTY_SET;
81 public void setArguments(List args)
83 this.args = args;
86 public boolean matches(Node context)
88 Object ret = evaluate(context, 1, 1);
89 return !((Collection) ret).isEmpty();
92 public Object evaluate(Node context, int pos, int len)
94 // Evaluate arguments
95 int arity = args.size();
96 List values = new ArrayList(arity);
97 for (int i = 0; i < arity; i++)
99 Expr arg = (Expr) args.get(i);
100 values.add(arg.evaluate(context, pos, len));
102 // Get key name
103 QName keyName = QName.valueOf(_string(context, values.get(0)));
104 // Expand qualified name
105 String uri = keyName.getNamespaceURI();
106 String prefix = keyName.getPrefix();
107 if ((uri == null || uri.length() == 0) &&
108 (prefix != null && prefix.length() > 0))
110 uri = stylesheet.getNamespaceURI(prefix);
111 if (uri != null && uri.length() > 0)
113 String localName = keyName.getLocalPart();
114 keyName = new QName(uri, localName, prefix);
117 // Compute matching key set
118 Collection keySet = new LinkedList();
119 for (Iterator i = stylesheet.keys.iterator(); i.hasNext(); )
121 Key key = (Key) i.next();
122 if (key.name.equals(keyName))
124 keySet.add(key);
127 // Get target
128 Object target = values.get(1);
129 Collection acc = new LinkedHashSet();
130 Document doc = (context instanceof Document) ? (Document) context :
131 context.getOwnerDocument();
132 if (target instanceof Collection)
134 for (Iterator i = ((Collection) target).iterator(); i.hasNext(); )
136 String val = Expr.stringValue((Node) i.next());
137 addKeyNodes(doc, keySet, val, acc);
140 else
142 String val = Expr._string(context, target);
143 addKeyNodes(doc, keySet, val, acc);
145 List ret = new ArrayList(acc);
146 Collections.sort(ret, documentOrderComparator);
147 return ret;
150 final void addKeyNodes(Node node, Collection keySet,
151 String value, Collection acc)
153 addKeyNodeIfMatch(node, keySet, value, acc);
154 // Apply children
155 for (Node ctx = node.getFirstChild(); ctx != null;
156 ctx = ctx.getNextSibling())
158 addKeyNodes(ctx, keySet, value, acc);
162 final void addKeyNodeIfMatch(Node node, Collection keySet,
163 String value, Collection acc)
165 for (Iterator i = keySet.iterator(); i.hasNext(); )
167 Key key = (Key) i.next();
168 if (key.match.matches(node))
170 Object eval = key.use.evaluate(node, 1, 1);
171 if (eval instanceof Collection)
173 for (Iterator j = ((Collection) eval).iterator();
174 j.hasNext(); )
176 String keyValue = Expr.stringValue((Node) j.next());
177 if (value.equals(keyValue))
179 acc.add(node);
180 return;
184 else
186 String keyValue = Expr._string(node, eval);
187 if (value.equals(keyValue))
189 acc.add(node);
190 return;
197 public Expr clone(Object context)
199 Stylesheet s = stylesheet;
200 if (context instanceof Stylesheet)
202 s = (Stylesheet) context;
204 KeyFunction f = new KeyFunction(s);
205 int len = args.size();
206 List args2 = new ArrayList(len);
207 for (int i = 0; i < len; i++)
209 args2.add(((Expr) args.get(i)).clone(context));
211 f.setArguments(args2);
212 return f;
215 public boolean references(QName var)
217 for (Iterator i = args.iterator(); i.hasNext(); )
219 if (((Expr) i.next()).references(var))
221 return true;
224 return false;