001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/filterencoding/PropertyIsInstanceOfOperation.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.datatypes.QualifiedName; 039 import org.deegree.framework.xml.ElementList; 040 import org.deegree.framework.xml.NamespaceContext; 041 import org.deegree.framework.xml.XMLParsingException; 042 import org.deegree.framework.xml.XMLTools; 043 import org.deegree.io.datastore.PropertyPathResolvingException; 044 import org.deegree.model.feature.Feature; 045 import org.deegree.model.feature.FeatureProperty; 046 import org.deegree.model.spatialschema.Curve; 047 import org.deegree.model.spatialschema.MultiCurve; 048 import org.deegree.model.spatialschema.MultiPoint; 049 import org.deegree.model.spatialschema.MultiSurface; 050 import org.deegree.model.spatialschema.Point; 051 import org.deegree.model.spatialschema.Surface; 052 import org.deegree.model.spatialschema.SurfacePatch; 053 import org.deegree.ogcbase.CommonNamespaces; 054 import org.w3c.dom.Element; 055 056 /** 057 * deegree-specific <code>ComparisonOperation</code> that allows to check the type of a property. 058 * <p> 059 * This is useful if the property has an abstract type with several concrete implementations, for example 060 * 'gml:_Geometry'. 061 * <p> 062 * NOTE: Currently supported types to test are: 063 * <ul> 064 * <li>gml:Point</li> 065 * <li>gml:_Curve</li> 066 * <li>gml:_Surface</li> 067 * </ul> 068 * 069 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> 070 * @author last edited by: $Author: apoth $ 071 * 072 * @version $Revision: 25585 $, $Date: 2010-07-28 16:49:15 +0200 (Mi, 28 Jul 2010) $ 073 */ 074 public class PropertyIsInstanceOfOperation extends ComparisonOperation { 075 076 private PropertyName propertyName; 077 078 private QualifiedName typeName; 079 080 private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 081 082 /** 083 * Creates a new instance of <code>PropertyIsInstanceOfOperation</code>. 084 * 085 * @param propertyName 086 * @param typeName 087 */ 088 public PropertyIsInstanceOfOperation( PropertyName propertyName, QualifiedName typeName ) { 089 super( OperationDefines.PROPERTYISINSTANCEOF ); 090 this.propertyName = propertyName; 091 this.typeName = typeName; 092 } 093 094 public StringBuffer toXML() { 095 StringBuffer sb = new StringBuffer(); 096 sb.append( "<ogc:" ).append( getOperatorName() ).append( ">" ); 097 sb.append( propertyName.toXML() ); 098 sb.append( "<ogc:Literal gml='http://www.opengis.net/gml'>" ); 099 sb.append( "gml:" ).append( typeName.getLocalName() ).append( "</ogc:Literal>" ); 100 sb.append( "</ogc:" ).append( getOperatorName() ).append( ">" ); 101 return sb; 102 } 103 104 public StringBuffer to100XML() { 105 return toXML(); 106 } 107 108 public StringBuffer to110XML() { 109 return toXML(); 110 } 111 112 /** 113 * Calculates the <code>Operation</code>'s logical value based on the certain property values of the given feature. 114 * 115 * @param feature 116 * that determines the values of <code>PropertyNames</code> in the expression 117 * @return true, if the <code>Operation</code> evaluates to true, else false 118 * @throws FilterEvaluationException 119 * if the evaluation fails 120 */ 121 public boolean evaluate( Feature feature ) 122 throws FilterEvaluationException { 123 boolean equals = false; 124 Object propertyValue = null; 125 try { 126 FeatureProperty property = feature.getDefaultProperty( propertyName.getValue() ); 127 if ( property == null ) { 128 return false; 129 } 130 propertyValue = property.getValue(); 131 } catch ( PropertyPathResolvingException e ) { 132 String msg = "Error evaluating PropertyIsInstanceOf operation: " + e.getMessage(); 133 throw new FilterEvaluationException( msg ); 134 } 135 136 if ( CommonNamespaces.GMLNS.equals( this.typeName.getNamespace() ) ) { 137 String localName = this.typeName.getLocalName(); 138 if ( "Point".equals( localName ) ) { 139 equals = propertyValue instanceof Point || propertyValue instanceof MultiPoint; 140 } else if ( "_Curve".equals( localName ) ) { 141 equals = propertyValue instanceof Curve || propertyValue instanceof MultiCurve; 142 } else if ( "_Surface".equals( localName ) ) { 143 equals = propertyValue instanceof Surface || propertyValue instanceof MultiSurface 144 || propertyValue instanceof SurfacePatch; 145 } else { 146 String msg = "Error evaluating PropertyIsInstanceOf operation: " + this.typeName 147 + " is not a supported type to check for."; 148 throw new FilterEvaluationException( msg ); 149 } 150 } else { 151 String msg = "Error evaluating PropertyIsInstanceOf operation: " + this.typeName 152 + " is not a supported type to check for."; 153 throw new FilterEvaluationException( msg ); 154 } 155 return equals; 156 } 157 158 /** 159 * Given a DOM-fragment, a corresponding Operation-object is built. This method recursively calls other buildFromDOM 160 * () - methods to validate the structure of the DOM-fragment. 161 * 162 * @param element 163 * to build from 164 * @return the Bean of the DOM 165 * 166 * @throws FilterConstructionException 167 * if the structure of the DOM-fragment is invalid 168 */ 169 public static Operation buildFromDOM( Element element ) 170 throws FilterConstructionException { 171 172 // check if root element's name equals 'PropertyIsInstanceOf' 173 if ( !element.getLocalName().equals( "PropertyIsInstanceOf" ) ) 174 throw new FilterConstructionException( "Name of element does not equal 'PropertyIsInstanceOf'!" ); 175 176 ElementList children = XMLTools.getChildElements( element ); 177 if ( children.getLength() != 2 ) { 178 throw new FilterConstructionException( "'PropertyIsInstanceOf' requires exactly 2 elements!" ); 179 } 180 181 PropertyName propertyName = (PropertyName) PropertyName.buildFromDOM( children.item( 0 ) ); 182 QualifiedName typeName = null; 183 try { 184 typeName = XMLTools.getRequiredNodeAsQualifiedName( element, "ogc:Literal/text()", nsContext ); 185 } catch ( XMLParsingException e ) { 186 throw new FilterConstructionException( e.getMessage() ); 187 } 188 return new PropertyIsInstanceOfOperation( propertyName, typeName ); 189 } 190 191 /** 192 * @return the propertyName of this Operation 193 */ 194 public PropertyName getPropertyName() { 195 return propertyName; 196 } 197 198 /** 199 * @return the typeName 200 */ 201 public QualifiedName getTypeName() { 202 return typeName; 203 } 204 205 }