    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/model/filterencoding/LogicalOperation.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 java.util.ArrayList;
    039    import java.util.List;
    040
    041    import org.deegree.framework.xml.ElementList;
    042    import org.deegree.framework.xml.XMLTools;
    043    import org.deegree.model.feature.Feature;
    044    import org.w3c.dom.Element;
    045
    046    /**
    047     * Encapsulates the information of a logical_ops entity (as defined in the Filter DTD).
    048     *
    049     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
    050     * @author last edited by: $Author: mschneider $
    051     *
    052     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    053     */
    054    public class LogicalOperation extends AbstractOperation {
    055
    056        /** Arguments of the Operation. */
    057        private List<Operation> arguments;
    058
    059        /**
    060         * Constructs a new LogicalOperation.
    061         *
    062         * @see OperationDefines
    063         *
    064         * @param operatorId
    065         * @param arguments
    066         */
    067        public LogicalOperation( int operatorId, List<Operation> arguments ) {
    068            super( operatorId );
    069            this.arguments = arguments;
    070        }
    071
    072        /**
    073         * Returns the arguments of the operation. These are <tt>OperationsMetadata</tt> as well.
    074         *
    075         * @return a list of arguments of the operation
    076         */
    077        public List<Operation> getArguments() {
    078            return arguments;
    079        }
    080
    081        /**
    082         * Given a DOM-fragment, a corresponding Operation-object is built. This method recursively
    083         * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
    084         *
    085         * @param element
    086         * @return opertation
    087         * @throws FilterConstructionException
    088         *             if the structure of the DOM-fragment is invalid
    089         * @deprecated use the 1.0.0 filter encoding aware method instead.
    090         */
    091        @Deprecated
    092        public static Operation buildFromDOM( Element element )
    093                                throws FilterConstructionException {
    094            return buildFromDOM( element, false );
    095        }
    096
    097        /**
    098         * Given a DOM-fragment, a corresponding Operation-object is built. This method recursively
    099         * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
    100         *
    101         * @param element
    102         * @return opertation
    103         * @throws FilterConstructionException
    104         *             if the structure of the DOM-fragment is invalid
    105         */
    106        public static Operation buildFromDOM( Element element, boolean useVersion_1_0_0 )
    107                                throws FilterConstructionException {
    108
    109            // check if root element's name is a known operator
    110            String name = element.getLocalName();
    111            int operatorId = OperationDefines.getIdByName( name );
    112            List<Operation> arguments = new ArrayList<Operation>();
    113
    114            switch ( operatorId ) {
    115            case OperationDefines.AND:
    116            case OperationDefines.OR: {
    117                ElementList children = XMLTools.getChildElements( element );
    118                if ( children.getLength() < 2 )
    119                    throw new FilterConstructionException( "'" + name + "' requires at least 2 elements!" );
    120                for ( int i = 0; i < children.getLength(); i++ ) {
    121                    Element child = children.item( i );
    122                    Operation childOperation = AbstractOperation.buildFromDOM( child, useVersion_1_0_0 );
    123                    arguments.add( childOperation );
    124                }
    125                break;
    126            }
    127            case OperationDefines.NOT: {
    128                ElementList children = XMLTools.getChildElements( element );
    129                if ( children.getLength() != 1 )
    130                    throw new FilterConstructionException( "'" + name + "' requires exactly 1 element!" );
    131                Element child = children.item( 0 );
    132                Operation childOperation = AbstractOperation.buildFromDOM( child, useVersion_1_0_0 );
    133                arguments.add( childOperation );
    134                break;
    135            }
    136            default: {
    137                throw new FilterConstructionException( "'" + name + "' is not a logical operator!" );
    138            }
    139            }
    140            return new LogicalOperation( operatorId, arguments );
    141        }
    142
    143        public StringBuffer toXML() {
    144            return to110XML();
    145        }
    146
    147        public StringBuffer to100XML() {
    148            StringBuffer sb = new StringBuffer( 1000 );
    149            sb.append( "<ogc:" ).append( getOperatorName() ).append( ">" );
    150
    151            for ( int i = 0; i < arguments.size(); i++ ) {
    152                sb.append( arguments.get( i ).to100XML() );
    153            }
    154
    155            sb.append( "</ogc:" ).append( getOperatorName() ).append( ">" );
    156            return sb;
    157        }
    158
    159        public StringBuffer to110XML() {
    160            StringBuffer sb = new StringBuffer( 1000 );
    161            sb.append( "<ogc:" ).append( getOperatorName() ).append( ">" );
    162
    163            for ( int i = 0; i < arguments.size(); i++ ) {
    164                sb.append( arguments.get( i ).toXML() );
    165            }
    166
    167            sb.append( "</ogc:" ).append( getOperatorName() ).append( ">" );
    168            return sb;
    169        }
    170
    171        /**
    172         * Calculates the <tt>LogicalOperation</tt>'s logical value based on the certain property
    173         * values of the given <tt>Feature</tt>.
    174         *
    175         * @param feature
    176         *            that determines the property values
    177         * @return true, if the <tt>LogicalOperation</tt> evaluates to true, else false
    178         * @throws FilterEvaluationException
    179         *             if the evaluation fails
    180         */
    181        public boolean evaluate( Feature feature )
    182                                throws FilterEvaluationException {
    183            switch ( getOperatorId() ) {
    184            case OperationDefines.AND: {
    185                for ( int i = 0; i < arguments.size(); i++ ) {
    186                    if ( !arguments.get( i ).evaluate( feature ) )
    187                        return false;
    188                }
    189                return true;
    190            }
    191            case OperationDefines.OR: {
    192                for ( int i = 0; i < arguments.size(); i++ ) {
    193                    if ( arguments.get( i ).evaluate( feature ) )
    194                        return true;
    195                }
    196                return false;
    197            }
    198            case OperationDefines.NOT: {
    199                return !arguments.get( 0 ).evaluate( feature );
    200            }
    201            default: {
    202                throw new FilterEvaluationException( "Unknown LogicalOperation encountered: '" + getOperatorName() + "'" );
    203            }
    204            }
    205        }
    206    }