001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/filterencoding/ArithmeticExpression.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: 53177 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 org.deegree.framework.xml.ElementList;
047: import org.deegree.framework.xml.XMLTools;
048: import org.deegree.model.feature.Feature;
049: import org.w3c.dom.Element;
050:
051: /**
052: * Encapsulates the information of a <Add> / <Sub>/ <Mul> or <DIV> element
053: * as defined in the Expression DTD.
054: *
055: * @author Markus Schneider
056: * @version 07.08.2002
057: * @author last edited by: $Author: apoth $
058: *
059: * @version $Revision: 9343 $, $Date: 2007-12-27 05:30:32 -0800 (Thu, 27 Dec 2007) $
060: */
061: public class ArithmeticExpression extends Expression {
062:
063: /**
064: * The first operand.
065: *
066: */
067: Expression expr1;
068:
069: /**
070: * The second operand.
071: *
072: */
073: Expression expr2;
074:
075: /**
076: * Constructs a new ArithmeticExpression.
077: *
078: * @param id
079: * @param expr1
080: * @param expr2
081: */
082: public ArithmeticExpression(int id, Expression expr1,
083: Expression expr2) {
084: this .id = id;
085: this .expr1 = expr1;
086: this .expr2 = expr2;
087: }
088:
089: /**
090: * Given a DOM-fragment, a corresponding Expression-object is built. This method recursively
091: * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
092: *
093: * @param element
094: * @return
095: *
096: * @throws FilterConstructionException
097: * if the structure of the DOM-fragment is invalid
098: */
099: public static Expression buildFromDOM(Element element)
100: throws FilterConstructionException {
101:
102: // check if root element's name is 'Add' / 'Sub' / 'Mul' or 'Div'
103: String name = element.getLocalName();
104: int id = ExpressionDefines.getIdByName(name);
105: switch (id) {
106: case ExpressionDefines.ADD:
107: case ExpressionDefines.SUB:
108: case ExpressionDefines.MUL:
109: case ExpressionDefines.DIV: {
110: break;
111: }
112: default: {
113: throw new FilterConstructionException(
114: "Element's name does not match 'Add' / 'Sub' / 'Mul' or 'Div'!");
115: }
116: }
117:
118: // determine the arguments
119: ElementList children = XMLTools.getChildElements(element);
120: if (children.getLength() != 2)
121: throw new FilterConstructionException("'" + name
122: + "' requires exactly 2 elements!");
123:
124: Expression expr1 = Expression.buildFromDOM(children.item(0));
125: Expression expr2 = Expression.buildFromDOM(children.item(1));
126:
127: return new ArithmeticExpression(id, expr1, expr2);
128: }
129:
130: /**
131: * Produces an indented XML representation of this object.
132: *
133: * @return XML representation of this object.
134: */
135: public StringBuffer toXML() {
136: StringBuffer sb = new StringBuffer();
137:
138: sb.append("<ogc:").append(getExpressionName()).append(">");
139: sb.append(expr1.toXML());
140: sb.append(expr2.toXML());
141: sb.append("</ogc:").append(getExpressionName()).append(">");
142: return sb;
143: }
144:
145: /**
146: * Returns this <tt>ArithmeticExpression/tt>'s value (to be used in the
147: * evaluation of complex <tt>Expression</tt>s).
148: * TODO: Improve datatype handling.
149: * @param feature that determines the concrete values of
150: * <tt>PropertyNames</tt> in the expression
151: * @return the resulting value (as <tt>Double</tt>)
152: * @throws FilterEvaluationException if the expressions are not numerical
153: */
154: public Object evaluate(Feature feature)
155: throws FilterEvaluationException {
156:
157: Object o1 = expr1.evaluate(feature);
158: Object o2 = expr2.evaluate(feature);
159:
160: if (!(o1 instanceof Number && o2 instanceof Number)) {
161: throw new FilterEvaluationException(
162: "ADD/SUB/DIV/MUL may only be applied to numerical expressions.");
163: }
164: double d1 = ((Number) o1).doubleValue();
165: double d2 = ((Number) o2).doubleValue();
166: switch (id) {
167: case ExpressionDefines.ADD:
168: return new Double(d1 + d2);
169: case ExpressionDefines.SUB:
170: return new Double(d1 - d2);
171: case ExpressionDefines.MUL:
172: return new Double(d1 * d2);
173: case ExpressionDefines.DIV:
174: return new Double(d1 / d2);
175: default: {
176: throw new FilterEvaluationException(
177: "Unknown ArithmeticExpression: '"
178: + getExpressionName() + "'!");
179: }
180: }
181: }
182:
183: /**
184: * returns the first expression
185: *
186: * @return the first expression
187: */
188: public Expression getFirstExpression() {
189: return expr1;
190: }
191:
192: /**
193: * returns the second expression
194: *
195: * @return the second expression
196: */
197: public Expression getSecondExpression() {
198: return expr2;
199: }
200: }
|