001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/filterencoding/PropertyIsInstanceOfOperation.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstraße 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.model.filterencoding;
044:
045: import org.deegree.datatypes.QualifiedName;
046: import org.deegree.framework.xml.ElementList;
047: import org.deegree.framework.xml.NamespaceContext;
048: import org.deegree.framework.xml.XMLParsingException;
049: import org.deegree.framework.xml.XMLTools;
050: import org.deegree.io.datastore.PropertyPathResolvingException;
051: import org.deegree.model.feature.Feature;
052: import org.deegree.model.feature.FeatureProperty;
053: import org.deegree.model.spatialschema.Curve;
054: import org.deegree.model.spatialschema.MultiCurve;
055: import org.deegree.model.spatialschema.MultiPoint;
056: import org.deegree.model.spatialschema.MultiSurface;
057: import org.deegree.model.spatialschema.Point;
058: import org.deegree.model.spatialschema.Surface;
059: import org.deegree.model.spatialschema.SurfacePatch;
060: import org.deegree.ogcbase.CommonNamespaces;
061: import org.w3c.dom.Element;
062:
063: /**
064: * deegree-specific <code>ComparisonOperation</code> that allows to check the type of a property.
065: * <p>
066: * This is useful if the property has an abstract type with several concrete implementations, for
067: * example 'gml:_Geometry'.
068: * <p>
069: * NOTE: Currently supported types to test are:
070: * <ul>
071: * <li>gml:Point</li>
072: * <li>gml:_Curve</li>
073: * <li>gml:_Surface</li>
074: * </ul>
075: *
076: * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
077: * @author last edited by: $Author: apoth $
078: *
079: * @version $Revision: 9343 $, $Date: 2007-12-27 05:30:32 -0800 (Thu, 27 Dec 2007) $
080: */
081: public class PropertyIsInstanceOfOperation extends ComparisonOperation {
082:
083: private PropertyName propertyName;
084:
085: private QualifiedName typeName;
086:
087: private static NamespaceContext nsContext = CommonNamespaces
088: .getNamespaceContext();
089:
090: /**
091: * Creates a new instance of <code>PropertyIsInstanceOfOperation</code>.
092: *
093: * @param propertyName
094: * @param typeName
095: */
096: public PropertyIsInstanceOfOperation(PropertyName propertyName,
097: QualifiedName typeName) {
098: super (OperationDefines.PROPERTYISINSTANCEOF);
099: this .propertyName = propertyName;
100: this .typeName = typeName;
101: }
102:
103: /**
104: * Produces an XML representation of this object.
105: */
106: public StringBuffer toXML() {
107: StringBuffer sb = new StringBuffer();
108: sb.append("<ogc:").append(getOperatorName()).append("\">");
109: sb.append(propertyName.toXML());
110: sb.append("<ogc:Literal>").append(typeName.getPrefixedName())
111: .append("</ogc:Literal>");
112: sb.append("</ogc:").append(getOperatorName()).append(">");
113: return sb;
114: }
115:
116: /**
117: * Calculates the <code>Operation</code>'s logical value based on the certain property values
118: * of the given feature.
119: *
120: * @param feature
121: * that determines the values of <code>PropertyNames</code> in the expression
122: * @return true, if the <code>Operation</code> evaluates to true, else false
123: * @throws FilterEvaluationException
124: * if the evaluation fails
125: */
126: public boolean evaluate(Feature feature)
127: throws FilterEvaluationException {
128:
129: boolean equals = false;
130: Object propertyValue = null;
131: try {
132: FeatureProperty property = feature
133: .getDefaultProperty(propertyName.getValue());
134: propertyValue = property.getValue();
135: } catch (PropertyPathResolvingException e) {
136: String msg = "Error evaluating PropertyIsInstanceOf operation: "
137: + e.getMessage();
138: throw new FilterEvaluationException(msg);
139: }
140:
141: if (CommonNamespaces.GMLNS.equals(this .typeName.getNamespace())) {
142: String localName = this .typeName.getLocalName();
143: if ("Point".equals(localName)) {
144: equals = propertyValue instanceof Point
145: || propertyValue instanceof MultiPoint;
146: } else if ("_Curve".equals(localName)) {
147: equals = propertyValue instanceof Curve
148: || propertyValue instanceof MultiCurve;
149: } else if ("_Surface".equals(localName)) {
150: equals = propertyValue instanceof Surface
151: || propertyValue instanceof MultiSurface
152: || propertyValue instanceof SurfacePatch;
153: } else {
154: String msg = "Error evaluating PropertyIsInstanceOf operation: "
155: + this .typeName
156: + " is not a supported type to check for.";
157: throw new FilterEvaluationException(msg);
158: }
159: } else {
160: String msg = "Error evaluating PropertyIsInstanceOf operation: "
161: + this .typeName
162: + " is not a supported type to check for.";
163: throw new FilterEvaluationException(msg);
164: }
165: return equals;
166: }
167:
168: /**
169: * Given a DOM-fragment, a corresponding Operation-object is built. This method recursively
170: * calls other buildFromDOM () - methods to validate the structure of the DOM-fragment.
171: *
172: * @param element
173: * to build from
174: * @return the Bean of the DOM
175: *
176: * @throws FilterConstructionException
177: * if the structure of the DOM-fragment is invalid
178: */
179: public static Operation buildFromDOM(Element element)
180: throws FilterConstructionException {
181:
182: // check if root element's name equals 'PropertyIsInstanceOf'
183: if (!element.getLocalName().equals("PropertyIsInstanceOf"))
184: throw new FilterConstructionException(
185: "Name of element does not equal 'PropertyIsInstanceOf'!");
186:
187: ElementList children = XMLTools.getChildElements(element);
188: if (children.getLength() != 2) {
189: throw new FilterConstructionException(
190: "'PropertyIsInstanceOf' requires exactly 2 elements!");
191: }
192:
193: PropertyName propertyName = (PropertyName) PropertyName
194: .buildFromDOM(children.item(0));
195: QualifiedName typeName = null;
196: try {
197: typeName = XMLTools.getRequiredNodeAsQualifiedName(element,
198: "ogc:Literal/text()", nsContext);
199: } catch (XMLParsingException e) {
200: throw new FilterConstructionException(e.getMessage());
201: }
202: return new PropertyIsInstanceOfOperation(propertyName, typeName);
203: }
204:
205: /**
206: * @return the propertyName of this Operation
207: */
208: public PropertyName getPropertyName() {
209: return propertyName;
210: }
211: }
|