    001    // $HeadURL:
    002    // /deegreerepository/deegree/src/org/deegree/model/filterencoding/XMLFactory.java,v
    003    // 1.1.1.1 2005/01/05 10:34:46 poth Exp $
    004    /*----------------------------------------------------------------------------
    005     This file is part of deegree, http://deegree.org/
    006     Copyright (C) 2001-2009 by:
    007       Department of Geography, University of Bonn
    008     and
    009       lat/lon GmbH
    010
    011     This library is free software; you can redistribute it and/or modify it under
    012     the terms of the GNU Lesser General Public License as published by the Free
    013     Software Foundation; either version 2.1 of the License, or (at your option)
    014     any later version.
    015     This library is distributed in the hope that it will be useful, but WITHOUT
    016     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    017     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    018     details.
    019     You should have received a copy of the GNU Lesser General Public License
    020     along with this library; if not, write to the Free Software Foundation, Inc.,
    021     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    022
    023     Contact information:
    024
    025     lat/lon GmbH
    026     Aennchenstr. 19, 53177 Bonn
    027     Germany
    028     http://lat-lon.de/
    029
    030     Department of Geography, University of Bonn
    031     Prof. Dr. Klaus Greve
    032     Postfach 1147, 53001 Bonn
    033     Germany
    034     http://www.geographie.uni-bonn.de/deegree/
    035
    036     e-mail: info@deegree.org
    037    ----------------------------------------------------------------------------*/
    038    package org.deegree.model.filterencoding;
    039
    040    import java.io.StringReader;
    041    import java.net.URI;
    042
    043    import org.deegree.datatypes.QualifiedName;
    044    import org.deegree.framework.xml.XMLException;
    045    import org.deegree.framework.xml.XMLTools;
    046    import org.deegree.model.filterencoding.capabilities.FilterCapabilities;
    047    import org.deegree.model.filterencoding.capabilities.Function;
    048    import org.deegree.model.filterencoding.capabilities.IdCapabilities;
    049    import org.deegree.model.filterencoding.capabilities.Operator;
    050    import org.deegree.model.filterencoding.capabilities.OperatorFactory100;
    051    import org.deegree.model.filterencoding.capabilities.ScalarCapabilities;
    052    import org.deegree.model.filterencoding.capabilities.SpatialCapabilities;
    053    import org.deegree.model.filterencoding.capabilities.SpatialOperator;
    054    import org.deegree.ogcbase.CommonNamespaces;
    055    import org.w3c.dom.Document;
    056    import org.w3c.dom.Element;
    057
    058    /**
    059     *
    060     *
    061     *
    062     * @version $Revision: 18195 $
    063     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    064     * @author last edited by: $Author: mschneider $
    065     *
    066     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    067     */
    068    public class XMLFactory {
    069
    070        private static URI OGCNS = CommonNamespaces.OGCNS;
    071
    072        /**
    073         * Appends the DOM representation of the <code>FilterCapabilities</code> to the passed
    074         * <code>Element</code>. Generated DOM structure fulfills
    075         * <code>Filter Encoding Specification 1.0.0</code>.
    076         *
    077         * @param root
    078         * @param filterCapabilities
    079         */
    080        public static void appendFilterCapabilities100( Element root, FilterCapabilities filterCapabilities ) {
    081
    082            Element filterCapabilitiesNode = XMLTools.appendElement( root, OGCNS, "ogc:Filter_Capabilities" );
    083            Element spatialCapabilitiesNode = XMLTools.appendElement( filterCapabilitiesNode, OGCNS,
    084                                                                      "ogc:Spatial_Capabilities" );
    085            Element spatialOperationsNode = XMLTools.appendElement( spatialCapabilitiesNode, OGCNS, "ogc:Spatial_Operators" );
    086            SpatialCapabilities spatialCapabilities = filterCapabilities.getSpatialCapabilities();
    087            String[] operators = new String[] { OperatorFactory100.OPERATOR_BBOX, OperatorFactory100.OPERATOR_EQUALS,
    088                                               OperatorFactory100.OPERATOR_DISJOINT, OperatorFactory100.OPERATOR_INTERSECT,
    089                                               OperatorFactory100.OPERATOR_TOUCHES, OperatorFactory100.OPERATOR_CROSSES,
    090                                               OperatorFactory100.OPERATOR_WITHIN, OperatorFactory100.OPERATOR_CONTAINS,
    091                                               OperatorFactory100.OPERATOR_OVERLAPS, OperatorFactory100.OPERATOR_BEYOND,
    092                                               OperatorFactory100.OPERATOR_DWITHIN };
    093            for ( int i = 0; i < operators.length; i++ ) {
    094                if ( spatialCapabilities.hasOperator( operators[i] ) ) {
    095                    XMLTools.appendElement( spatialOperationsNode, OGCNS, "ogc:" + operators[i] );
    096                }
    097            }
    098            Element scalarCapabilitiesNode = XMLTools.appendElement( filterCapabilitiesNode, OGCNS,
    099                                                                     "ogc:Scalar_Capabilities" );
    100            ScalarCapabilities scalarCapabilities = filterCapabilities.getScalarCapabilities();
    101            if ( scalarCapabilities.hasLogicalOperatorsSupport() ) {
    102                XMLTools.appendElement( scalarCapabilitiesNode, OGCNS, "ogc:"
    103                                                                       + OperatorFactory100.OPERATOR_LOGICAL_OPERATORS );
    104            }
    105
    106            if ( scalarCapabilities.getComparisonOperators().length > 0 ) {
    107
    108                Element operatorsNode = XMLTools.appendElement( scalarCapabilitiesNode, OGCNS, "ogc:Comparison_Operators" );
    109                operators = new String[] { OperatorFactory100.OPERATOR_SIMPLE_COMPARISONS,
    110                                          OperatorFactory100.OPERATOR_LIKE, OperatorFactory100.OPERATOR_BETWEEN,
    111                                          OperatorFactory100.OPERATOR_NULL_CHECK };
    112                for ( int i = 0; i < operators.length; i++ ) {
    113                    if ( scalarCapabilities.hasComparisonOperator( operators[i] ) ) {
    114                        XMLTools.appendElement( operatorsNode, OGCNS, "ogc:" + operators[i] );
    115                    }
    116                }
    117            }
    118            // 'ogc:Arithmetic_Operators'-element
    119            if ( scalarCapabilities.getArithmeticOperators().length > 0 ) {
    120                Element operatorsNode = XMLTools.appendElement( scalarCapabilitiesNode, OGCNS, "ogc:Arithmetic_Operators" );
    121                // 'ogc:Simple_Arithmetic'-element
    122                int hasFunctions = 1;
    123                if ( scalarCapabilities.hasArithmeticOperator( OperatorFactory100.OPERATOR_SIMPLE_ARITHMETIC ) ) {
    124                    XMLTools.appendElement( operatorsNode, OGCNS, "ogc:" + OperatorFactory100.OPERATOR_SIMPLE_ARITHMETIC );
    125                    hasFunctions = 2;
    126                }
    127                // 'ogc:Functions'-element
    128                Operator[] arithmeticOperators = scalarCapabilities.getArithmeticOperators();
    129                if ( arithmeticOperators.length >= hasFunctions ) {
    130                    Element functionsNode = XMLTools.appendElement( operatorsNode, OGCNS,
    131                                                                    "ogc:" + OperatorFactory100.OPERATOR_FUNCTIONS, null );
    132                    for ( int i = 0; i < arithmeticOperators.length; i++ ) {
    133                        if ( arithmeticOperators[i] instanceof Function ) {
    134                            Function function = (Function) arithmeticOperators[i];
    135                            Element functionNode = XMLTools.appendElement( functionsNode, OGCNS, "ogc:Function_Name" );
    136                            functionNode.setAttribute( "nArgs", "" + function.getArgumentCount() );
    137                        }
    138                    }
    139                }
    140            }
    141        }
    142
    143        /**
    144         * Appends the DOM representation of the <code>FilterCapabilities</code> to the passed
    145         * <code>Element</code>. Generated DOM structure fulfills
    146         * <code>Filter Encoding Specification 1.1.0</code>.
    147         *
    148         * @param root
    149         * @param filterCapabilities
    150         */
    151        public static void appendFilterCapabilities110( Element root, FilterCapabilities filterCapabilities ) {
    152            Element filterCapabilitiesNode = XMLTools.appendElement( root, OGCNS, "ogc:Filter_Capabilities" );
    153            appendSpatialCapabilities110( filterCapabilitiesNode, filterCapabilities.getSpatialCapabilities() );
    154            appendScalarCapabilities110( filterCapabilitiesNode, filterCapabilities.getScalarCapabilities() );
    155            appendIdCapabilities110( filterCapabilitiesNode, filterCapabilities.getIdCapabilities() );
    156        }
    157
    158        /**
    159         * Appends the DOM representation of the <code>SpatialCapabilities</code> to the passed
    160         * <code>Element</code>. Generated DOM structure fulfills
    161         * <code>Filter Encoding Specification 1.1.0</code>.
    162         *
    163         * @param root
    164         * @param spatialCapabilities
    165         */
    166        public static void appendSpatialCapabilities110( Element root, SpatialCapabilities spatialCapabilities ) {
    167            Element spatialCapabilitiesNode = XMLTools.appendElement( root, OGCNS, "ogc:Spatial_Capabilities" );
    168            QualifiedName[] geometryOperands = spatialCapabilities.getGeometryOperands();
    169            if ( geometryOperands != null && geometryOperands.length > 0 ) {
    170                appendGeometryOperands( spatialCapabilitiesNode, geometryOperands );
    171            } else {
    172                // default behavior to ensure that a valid filter capabilities element will be generated
    173                Element geometryOperandsNode = XMLTools.appendElement( spatialCapabilitiesNode, OGCNS,
    174                                                                       "ogc:GeometryOperands" );
    175                XMLTools.appendElement( geometryOperandsNode, OGCNS, "ogc:GeometryOperand", "gml:Envelope" );
    176
    177            }
    178            SpatialOperator[] spatialOperators = spatialCapabilities.getSpatialOperators();
    179            Element spatialOperatorsNode = XMLTools.appendElement( spatialCapabilitiesNode, OGCNS, "ogc:SpatialOperators" );
    180            for ( int i = 0; i < spatialOperators.length; i++ ) {
    181                Element spatialOperatorNode = XMLTools.appendElement( spatialOperatorsNode, OGCNS, "ogc:SpatialOperator" );
    182                spatialOperatorNode.setAttribute( "name", spatialOperators[i].getName() );
    183                geometryOperands = spatialOperators[i].getGeometryOperands();
    184                if ( geometryOperands != null && geometryOperands.length > 0 ) {
    185                    appendGeometryOperands( spatialOperatorsNode, geometryOperands );
    186                }
    187            }
    188        }
    189
    190        /**
    191         * Appends the DOM representation of the <code>SpatialCapabilities</code> to the passed
    192         * <code>Element</code>. Generated DOM structure fulfills
    193         * <code>Filter Encoding Specification 1.1.0</code>.
    194         *
    195         * @param root
    196         * @param geometryOperands
    197         */
    198        public static void appendGeometryOperands( Element root, QualifiedName[] geometryOperands ) {
    199            Element geometryOperandsNode = XMLTools.appendElement( root, OGCNS, "ogc:GeometryOperands" );
    200            for ( int i = 0; i < geometryOperands.length; i++ ) {
    201                XMLTools.appendElement( geometryOperandsNode, OGCNS, "ogc:GeometryOperand",
    202                                        geometryOperands[i].getPrefixedName() );
    203            }
    204        }
    205
    206        /**
    207         * Appends the DOM representation of the <code>ScalarCapabilities</code> to the passed
    208         * <code>Element</code>. Generated DOM structure fulfills
    209         * <code>Filter Encoding Specification 1.1.0</code>.
    210         *
    211         * @param root
    212         * @param scalarCapabilities
    213         */
    214        public static void appendScalarCapabilities110( Element root, ScalarCapabilities scalarCapabilities ) {
    215
    216            Element scalarCapabilitiesNode = XMLTools.appendElement( root, OGCNS, "ogc:Scalar_Capabilities" );
    217            if ( scalarCapabilities.hasLogicalOperatorsSupport() ) {
    218                XMLTools.appendElement( scalarCapabilitiesNode, OGCNS, "ogc:LogicalOperators" );
    219            }
    220            Operator[] comparisonOperators = scalarCapabilities.getComparisonOperators();
    221            if ( comparisonOperators != null ) {
    222                Element comparisonOperatorsNode = XMLTools.appendElement( scalarCapabilitiesNode, OGCNS,
    223                                                                          "ogc:ComparisonOperators" );
    224                for ( int i = 0; i < comparisonOperators.length; i++ ) {
    225                    XMLTools.appendElement( comparisonOperatorsNode, OGCNS, "ogc:ComparisonOperator",
    226                                            comparisonOperators[i].getName() );
    227                }
    228            }
    229            Operator[] arithmeticOperators = scalarCapabilities.getArithmeticOperators();
    230            if ( arithmeticOperators != null ) {
    231                Element arithmeticOperatorsNode = XMLTools.appendElement( scalarCapabilitiesNode, OGCNS,
    232                                                                          "ogc:ArithmeticOperators" );
    233                XMLTools.appendElement( arithmeticOperatorsNode, OGCNS, "ogc:SimpleArithmetic" );
    234
    235                boolean functionAvailable = false;
    236                for ( int i = 0; i < arithmeticOperators.length; i++ ) {
    237                    if ( arithmeticOperators[i] instanceof Function ) {
    238                        functionAvailable = true;
    239                    }
    240                }
    241
    242                if ( functionAvailable ) {
    243                    Element functionsNode = XMLTools.appendElement( arithmeticOperatorsNode, OGCNS, "ogc:Functions" );
    244                    Element functionNamesNode = XMLTools.appendElement( functionsNode, OGCNS, "ogc:FunctionNames" );
    245                    for ( int i = 0; i < arithmeticOperators.length; i++ ) {
    246                        if ( arithmeticOperators[i] instanceof Function ) {
    247                            Function function = (Function) arithmeticOperators[i];
    248                            Element functionNameNode = XMLTools.appendElement( functionNamesNode, OGCNS,
    249                                                                               "ogc:FunctionName", function.getName() );
    250                            functionNameNode.setAttribute( "nArgs", "" + function.getArgumentCount() );
    251                        }
    252                    }
    253                }
    254            }
    255        }
    256
    257        /**
    258         * Appends the DOM representation of the <code>IdCapabilities</code> to the passed
    259         * <code>Element</code>. Generated DOM structure fulfills
    260         * <code>Filter Encoding Specification 1.1.0</code>.
    261         *
    262         * @param root
    263         * @param idCapabilities
    264         */
    265        public static void appendIdCapabilities110( Element root, IdCapabilities idCapabilities ) {
    266            Element idCapabilitiesNode = XMLTools.appendElement( root, OGCNS, "ogc:Id_Capabilities" );
    267            if ( idCapabilities != null ) {
    268                Element[] eidElements = idCapabilities.getEidElements();
    269                for ( int i = 0; i < eidElements.length; i++ ) {
    270                    XMLTools.insertNodeInto( eidElements[i], idCapabilitiesNode );
    271                }
    272                Element[] fidElements = idCapabilities.getFidElements();
    273                for ( int i = 0; i < fidElements.length; i++ ) {
    274                    XMLTools.insertNodeInto( fidElements[i], idCapabilitiesNode );
    275                }
    276            } else {
    277                // default
    278                XMLTools.appendElement( idCapabilitiesNode, OGCNS, "ogc:EID" );
    279
    280            }
    281        }
    282
    283        /**
    284         * Appends the DOM representation of the given <code>Filter</code>- section to the passed
    285         * <code>Element</code>.
    286         *
    287         * TODO: Append the DOM-structure "node by node".
    288         *
    289         * @param root
    290         * @param filter
    291         *            must not be null
    292         * @throws XMLException
    293         */
    294        public static void appendFilter( Element root, Filter filter )
    295                                throws XMLException {
    296            String filterString = filter.toXML().toString();
    297            try {
    298                Document doc = XMLTools.parse( new StringReader( filterString ) );
    299                XMLTools.insertNodeInto( doc.getFirstChild(), root );
    300            } catch ( Exception e ) {
    301                e.printStackTrace();
    302                throw new XMLException( "Error appending Filter-expression: " + e.getMessage() );
    303            }
    304        }
    305    }