001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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    }