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 }