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 }