    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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: 25586 $, $Date: 2010-07-28 16:50:09 +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    }