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 }