001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xsl.fun;
030:
031: import com.caucho.xpath.Expr;
032: import com.caucho.xpath.ExprEnvironment;
033: import com.caucho.xpath.XPathException;
034: import com.caucho.xpath.XPathFun;
035: import com.caucho.xpath.pattern.AbstractPattern;
036:
037: import org.w3c.dom.Node;
038: import org.w3c.dom.NodeList;
039:
040: import java.util.ArrayList;
041: import java.util.HashMap;
042: import java.util.Iterator;
043:
044: /**
045: * The key(...) function.
046: */
047: public class KeyFun extends XPathFun {
048: private HashMap<String, Key> _keys;
049:
050: public KeyFun() {
051: _keys = new HashMap<String, Key>();
052: }
053:
054: /**
055: * Add a new key.
056: *
057: * @param name name of the key
058: * @param match the key's match pattern
059: * @param use the key's use expression
060: */
061: public void add(String name, AbstractPattern match, Expr use) {
062: _keys.put(name, new Key(match, use));
063: }
064:
065: public HashMap<String, Key> getKeys() {
066: return _keys;
067: }
068:
069: /**
070: * Evaluate the function.
071: *
072: * @param pattern The context pattern.
073: * @param args The evaluated arguments
074: */
075: public Object eval(Node node, ExprEnvironment env,
076: AbstractPattern pattern, ArrayList args)
077: throws XPathException {
078: if (args.size() < 2)
079: return null;
080:
081: String name = Expr.toString(args.get(0));
082: Key key = _keys.get(name);
083: Object value = args.get(1);
084:
085: if (key == null)
086: return null;
087:
088: if (value == null)
089: return null;
090:
091: ArrayList nodes = new ArrayList();
092: if (value instanceof NodeList) {
093: NodeList list = (NodeList) value;
094: for (int i = 0; i < list.getLength(); i++)
095: key(node, env, key._match, key._use, Expr.toString(list
096: .item(i)), nodes);
097: } else if (value instanceof ArrayList) {
098: ArrayList list = (ArrayList) value;
099: for (int i = 0; i < list.size(); i++)
100: key(node, env, key._match, key._use, Expr.toString(list
101: .get(i)), nodes);
102: } else if (value instanceof Iterator) {
103: Iterator iter = (Iterator) value;
104: while (iter.hasNext())
105: key(node, env, key._match, key._use, Expr.toString(iter
106: .next()), nodes);
107: } else
108: key(node, env, key._match, key._use, Expr.toString(value),
109: nodes);
110:
111: return nodes;
112: }
113:
114: private void key(Node node, ExprEnvironment env,
115: AbstractPattern match, Expr use, String value,
116: ArrayList nodes) throws XPathException {
117: Iterator iter = match.select(node, env);
118: while (iter.hasNext()) {
119: Node subnode = (Node) iter.next();
120: String nodeValue = use.evalString(subnode, env);
121:
122: if (value.equals(nodeValue))
123: nodes.add(subnode);
124: }
125: }
126:
127: public static class Key {
128: AbstractPattern _match;
129: Expr _use;
130:
131: Key(AbstractPattern match, Expr use) {
132: _match = match;
133: _use = use;
134: }
135:
136: public AbstractPattern getMatch() {
137: return _match;
138: }
139:
140: public Expr getUse() {
141: return _use;
142: }
143: }
144: }
|