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 }