    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/model/filterencoding/ArithmeticExpression.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.model.filterencoding;
    037
    038    import org.deegree.framework.xml.ElementList;
    039    import org.deegree.framework.xml.XMLTools;
    040    import org.deegree.model.feature.Feature;
    041    import org.w3c.dom.Element;
    042
    043    /**
    044     * Encapsulates the information of a &lt;Add&gt; / &lt;Sub&gt;/ &lt;Mul&gt; or &lt;DIV&gt; element
    045     * as defined in the Expression DTD.
    046     *
    047     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
    048     * @author last edited by: $Author: mschneider $
    049     *
    050     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    051     */
    052    public class ArithmeticExpression extends Expression {
    053
    054        /**
    055         * The first operand.
    056         *
    057         */
    058        Expression expr1;
    059
    060        /**
    061         * The second operand.
    062         *
    063         */
    064        Expression expr2;
    065
    066        /**
    067         * Constructs a new ArithmeticExpression.
    068         *
    069         * @param id
    070         * @param expr1
    071         * @param expr2
    072         */
    073        public ArithmeticExpression( int id, Expression expr1, Expression expr2 ) {
    074            this.id = id;
    075            this.expr1 = expr1;
    076            this.expr2 = expr2;
    077        }
    078
    079        /**
    080         * Given a DOM-fragment, a corresponding Expression-object is built. This method recursively
    081         * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
    082         *
    083         * @param element
    084         * @return the new instance
    085         *
    086         * @throws FilterConstructionException
    087         *             if the structure of the DOM-fragment is invalid
    088         */
    089        public static Expression buildFromDOM( Element element )
    090                                throws FilterConstructionException {
    091
    092            // check if root element's name is 'Add' / 'Sub' / 'Mul' or 'Div'
    093            String name = element.getLocalName();
    094            int id = ExpressionDefines.getIdByName( name );
    095            switch ( id ) {
    096            case ExpressionDefines.ADD:
    097            case ExpressionDefines.SUB:
    098            case ExpressionDefines.MUL:
    099            case ExpressionDefines.DIV: {
    100                break;
    101            }
    102            default: {
    103                throw new FilterConstructionException( "Element's name does not match 'Add' / 'Sub' / 'Mul' or 'Div'!" );
    104            }
    105            }
    106
    107            // determine the arguments
    108            ElementList children = XMLTools.getChildElements( element );
    109            if ( children.getLength() != 2 )
    110                throw new FilterConstructionException( "'" + name + "' requires exactly 2 elements!" );
    111
    112            Expression expr1 = Expression.buildFromDOM( children.item( 0 ) );
    113            Expression expr2 = Expression.buildFromDOM( children.item( 1 ) );
    114
    115            return new ArithmeticExpression( id, expr1, expr2 );
    116        }
    117
    118        /**
    119         * Produces an indented XML representation of this object.
    120         *
    121         * @return XML representation of this object.
    122         */
    123        @Override
    124        public StringBuffer toXML() {
    125            StringBuffer sb = new StringBuffer();
    126
    127            sb.append( "<ogc:" ).append( getExpressionName() ).append( ">" );
    128            sb.append( expr1.toXML() );
    129            sb.append( expr2.toXML() );
    130            sb.append( "</ogc:" ).append( getExpressionName() ).append( ">" );
    131            return sb;
    132        }
    133
    134        /**
    135         * Returns this <tt>ArithmeticExpression/tt>'s value (to be used in the
    136         * evaluation of complex <tt>Expression</tt>s).
    137         * TODO: Improve datatype handling.
    138         * @param feature that determines the concrete values of
    139         *                <tt>PropertyNames</tt> in the expression
    140         * @return the resulting value (as <tt>Double</tt>)
    141         * @throws FilterEvaluationException if the expressions are not numerical
    142         */
    143        @Override
    144        public Object evaluate( Feature feature )
    145                                throws FilterEvaluationException {
    146
    147            Object o1 = expr1.evaluate( feature );
    148            Object o2 = expr2.evaluate( feature );
    149
    150            if ( !( o1 instanceof Number && o2 instanceof Number ) ) {
    151                throw new FilterEvaluationException( "ADD/SUB/DIV/MUL may only be applied to numerical expressions." );
    152            }
    153            double d1 = ( (Number) o1 ).doubleValue();
    154            double d2 = ( (Number) o2 ).doubleValue();
    155            switch ( id ) {
    156            case ExpressionDefines.ADD:
    157                return new Double( d1 + d2 );
    158            case ExpressionDefines.SUB:
    159                return new Double( d1 - d2 );
    160            case ExpressionDefines.MUL:
    161                return new Double( d1 * d2 );
    162            case ExpressionDefines.DIV:
    163                return new Double( d1 / d2 );
    164            default: {
    165                throw new FilterEvaluationException( "Unknown ArithmeticExpression: '" + getExpressionName() + "'!" );
    166            }
    167            }
    168        }
    169
    170        /**
    171         * returns the first expression
    172         *
    173         * @return the first expression
    174         */
    175        public Expression getFirstExpression() {
    176            return expr1;
    177        }
    178
    179        /**
    180         * returns the second expression
    181         *
    182         * @return the second expression
    183         */
    184        public Expression getSecondExpression() {
    185            return expr2;
    186        }
    187    }