001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/filterencoding/Function.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.model.filterencoding;
045:
046: import java.io.IOException;
047: import java.io.InputStream;
048: import java.util.ArrayList;
049: import java.util.HashMap;
050: import java.util.Iterator;
051: import java.util.List;
052: import java.util.Map;
053: import java.util.Properties;
054:
055: import org.deegree.framework.util.BootLogger;
056: import org.deegree.framework.xml.ElementList;
057: import org.deegree.framework.xml.XMLTools;
058: import org.deegree.i18n.Messages;
059: import org.deegree.model.feature.Feature;
060: import org.w3c.dom.Element;
061:
062: /**
063: * Encapsulates the information of a <code>Function</code>element as defined in the Expression
064: * DTD.
065: *
066: * @author Markus Schneider
067: * @version 07.08.2002
068: */
069: public abstract class Function extends Expression {
070:
071: /** The Function's name (as specified in it's name attribute). */
072: protected String name;
073:
074: /** The Function's arguments. */
075: protected List<Expression> args;
076:
077: private static Map<String, Class> functions;
078:
079: static {
080: if (Function.functions == null) {
081: Function.initialize();
082: }
083: }
084:
085: private static void initialize() {
086: Function.functions = new HashMap<String, Class>(50);
087: InputStream is = Function.class
088: .getResourceAsStream("function.properties");
089: Properties props = new Properties();
090: try {
091: props.load(is);
092: } catch (IOException e) {
093: BootLogger.logError(e.getMessage(), e);
094: }
095: Iterator iter = props.keySet().iterator();
096: while (iter.hasNext()) {
097: String key = (String) iter.next();
098: try {
099: String className = props.getProperty(key);
100: if ("org.deegree.model.filterencoding.DBFunction"
101: .equals(className)) {
102: throw new Exception(Messages
103: .getMessage("FILTER_INVALID_NAME"));
104: }
105: Function.functions.put(key, Class.forName(className));
106: } catch (Exception e) {
107: BootLogger.logError(e.getMessage(), e);
108: break;
109: }
110: }
111: }
112:
113: protected Function() {
114:
115: }
116:
117: /** Constructs a new Function. */
118: public Function(String name, List<Expression> args) {
119: this ();
120: this .id = ExpressionDefines.FUNCTION;
121: this .name = name;
122: this .args = args;
123: }
124:
125: /**
126: *
127: * @param args
128: */
129: public void setArguments(List<Expression> args) {
130: this .args = args;
131: }
132:
133: /**
134: * Given a DOM-fragment, a corresponding Expression-object is built. This method recursively
135: * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
136: *
137: * @throws FilterConstructionException
138: * if the structure of the DOM-fragment is invalid
139: */
140: public static Expression buildFromDOM(Element element)
141: throws FilterConstructionException {
142:
143: // check if root element's name equals 'Function'
144: if (!element.getLocalName().toLowerCase().equals("function")) {
145: throw new FilterConstructionException(Messages
146: .getMessage("FILTER_WRONG_ROOTELEMENT"));
147: }
148:
149: // determine the name of the Function
150: String name = element.getAttribute("name");
151: if (name == null) {
152: throw new FilterConstructionException(Messages
153: .getMessage("FILTER_MISSING_NAME"));
154: }
155:
156: // determine the arguments of the Function
157: ElementList children = XMLTools.getChildElements(element);
158: if (children.getLength() < 1) {
159: throw new FilterConstructionException(Messages.getMessage(
160: "FILTER_MISSING_ELEMENT", name));
161: }
162:
163: ArrayList<Expression> args = new ArrayList<Expression>(children
164: .getLength());
165: for (int i = 0; i < children.getLength(); i++) {
166: args.add(Expression.buildFromDOM(children.item(i)));
167: }
168:
169: Class function = Function.functions.get(name);
170: if (function == null) {
171: throw new FilterConstructionException(Messages.getMessage(
172: "FILTER_UNKNOWN_FUNCTION", name));
173: }
174: Function func;
175: try {
176: func = (Function) function.newInstance();
177: } catch (InstantiationException e) {
178: throw new FilterConstructionException(e.getMessage());
179: } catch (IllegalAccessException e) {
180: throw new FilterConstructionException(e.getMessage());
181: }
182: func.setName(name);
183: func.setArguments(args);
184:
185: return func;
186: }
187:
188: /**
189: * Returns the Function's name.
190: *
191: * @return functions name
192: */
193: public String getName() {
194: return this .name;
195: }
196:
197: /**
198: * @see org.deegree.model.filterencoding.Function#getName()
199: *
200: * @param name
201: */
202: public void setName(String name) {
203: this .name = name;
204: }
205:
206: /**
207: * returns the arguments of the function
208: *
209: * @return arguments of the function
210: */
211: public List<Expression> getArguments() {
212: return this .args;
213: }
214:
215: /*
216: * (non-Javadoc)
217: *
218: * @see org.deegree.model.filterencoding.Expression#getExpressionId()
219: */
220: @Override
221: public int getExpressionId() {
222: return ExpressionDefines.FUNCTION;
223: }
224:
225: /**
226: * Returns the <tt>Function</tt>'s value (to be used in the evaluation of a complexer
227: * <tt>Expression</tt>).
228: *
229: * @param feature
230: * that determines the concrete values of <tt>PropertyNames</tt> found in the
231: * expression
232: * @return the resulting value
233: */
234: @Override
235: public abstract Object evaluate(Feature feature)
236: throws FilterEvaluationException;
237:
238: /**
239: * Produces an indented XML representation of this object.
240: *
241: * @return xml representation
242: */
243: @Override
244: public StringBuffer toXML() {
245: StringBuffer sb = new StringBuffer(1000);
246: sb.append("<ogc:Function name=\"").append(this .name).append(
247: "\">");
248: for (int i = 0; i < this .args.size(); i++) {
249: sb.append(this .args.get(i).toXML());
250: }
251: sb.append("</ogc:Function>");
252: return sb;
253: }
254: }
|