001 // $HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcbase/XMLFactory.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.ogcbase; 037 038 import java.io.ByteArrayInputStream; 039 import java.net.URI; 040 041 import org.deegree.datatypes.CodeList; 042 import org.deegree.datatypes.time.TimeDuration; 043 import org.deegree.datatypes.time.TimePeriod; 044 import org.deegree.datatypes.time.TimePosition; 045 import org.deegree.datatypes.time.TimeSequence; 046 import org.deegree.datatypes.values.Interval; 047 import org.deegree.datatypes.values.TypedLiteral; 048 import org.deegree.datatypes.values.Values; 049 import org.deegree.datatypes.xlink.SimpleLink; 050 import org.deegree.framework.log.ILogger; 051 import org.deegree.framework.log.LoggerFactory; 052 import org.deegree.framework.util.StringTools; 053 import org.deegree.framework.util.TimeTools; 054 import org.deegree.framework.xml.XMLFragment; 055 import org.deegree.framework.xml.XMLTools; 056 import org.deegree.model.crs.CoordinateSystem; 057 import org.deegree.model.metadata.iso19115.Keywords; 058 import org.deegree.model.metadata.iso19115.OnlineResource; 059 import org.deegree.model.spatialschema.Envelope; 060 import org.deegree.model.spatialschema.GMLGeometryAdapter; 061 import org.deegree.model.spatialschema.Geometry; 062 import org.deegree.model.spatialschema.GeometryException; 063 import org.deegree.ogcwebservices.LonLatEnvelope; 064 import org.w3c.dom.Element; 065 import org.w3c.dom.Node; 066 import org.w3c.dom.Text; 067 068 /** 069 * Factory for creating <code>DOM</code> representations from java objects used to represent OGC 070 * related schema types. 071 * 072 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 073 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 074 * @author last edited by: $Author: mschneider $ 075 * 076 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 077 */ 078 public class XMLFactory { 079 080 protected static final ILogger LOG = LoggerFactory.getLogger( XMLFactory.class ); 081 082 protected static final URI OGCNS = CommonNamespaces.OGCNS; 083 084 protected static final URI GMLNS = CommonNamespaces.GMLNS; 085 086 protected static final URI XLNNS = CommonNamespaces.XLNNS; 087 088 /** 089 * Appends the <code>DOM</code> representation of a <code>LonLatEnvelope</code> to the 090 * passed <code>Element</code>. 091 * 092 * @param root 093 * @param lonLatEnvelope 094 * @param namespaceURI 095 */ 096 protected static void appendLonLatEnvelope( Element root, LonLatEnvelope lonLatEnvelope, URI namespaceURI ) { 097 Element lonLatEnvelopeElement = XMLTools.appendElement( root, namespaceURI, "lonLatEnvelope" ); 098 //lonLatEnvelopeElement.setAttribute( "srsName", "WGS84(DD)" ); 099 lonLatEnvelopeElement.setAttribute( "srsName", lonLatEnvelope.getSrs() ); 100 String min = lonLatEnvelope.getMin().getX() + " " + lonLatEnvelope.getMin().getY(); 101 Element elem = XMLTools.appendElement( lonLatEnvelopeElement, GMLNS, "gml:pos", min ); 102 elem.setAttribute( "dimension", "2" ); 103 String max = lonLatEnvelope.getMax().getX() + " " + lonLatEnvelope.getMax().getY(); 104 elem = XMLTools.appendElement( lonLatEnvelopeElement, GMLNS, "gml:pos", max ); 105 elem.setAttribute( "dimension", "2" ); 106 TimePosition[] tpos = lonLatEnvelope.getTimePositions(); 107 if ( tpos != null ) { 108 for ( int i = 0; i < tpos.length; i++ ) { 109 appendTimePosition( lonLatEnvelopeElement, tpos[i] ); 110 } 111 } 112 } 113 114 /** 115 * Appends an <code>XML/GML Envelope</code> -element to the passed <code>Element</code>. 116 * 117 * @param xmlNode 118 * @param envelope 119 */ 120 protected static void appendEnvelope( Element xmlNode, Envelope envelope ) { 121 Element node = XMLTools.appendElement( xmlNode, GMLNS, "gml:Envelope" ); 122 CoordinateSystem crs = envelope.getCoordinateSystem(); 123 if ( crs != null ) { 124 try { 125 node.setAttribute( "srsName", crs.getIdentifier() ); 126 } catch ( Exception e ) { 127 e.printStackTrace(); 128 } 129 } 130 Element env = node; 131 132 String min = envelope.getMin().getX() + " " + envelope.getMin().getY(); 133 node = XMLTools.appendElement( env, GMLNS, "gml:pos", min ); 134 node.setAttribute( "dimension", "2" ); 135 136 String max = envelope.getMax().getX() + " " + envelope.getMax().getY(); 137 node = XMLTools.appendElement( env, GMLNS, "gml:pos", max ); 138 node.setAttribute( "dimension", "2" ); 139 } 140 141 /** 142 * Appends the <code>XML/GML</code> representation of a <code>TimePosition</code> to the 143 * passed <code>Element</code>. 144 * 145 * @param xmlNode 146 * @param tpos 147 */ 148 protected static void appendTimePosition( Element xmlNode, TimePosition tpos ) { 149 if ( tpos != null ) { 150 String s = TimeTools.getISOFormattedTime( tpos.getTime() ); 151 Element element = XMLTools.appendElement( xmlNode, GMLNS, "gml:timePosition", s ); 152 element.setAttribute( "calendarEraName", tpos.getCalendarEraName() ); 153 element.setAttribute( "frame", tpos.getFrame().toString() ); 154 element.setAttribute( "indeterminatePosition", tpos.getIndeterminatePosition().value ); 155 } 156 } 157 158 /** 159 * Appends a <code>keywords</code> -element for each <code>Keywords</code> object of the 160 * passed array to the passed <code>Element</code>. 161 * 162 * @param xmlNode 163 * @param keywords 164 * @param namespaceURI 165 */ 166 protected static void appendKeywords( Element xmlNode, Keywords[] keywords, URI namespaceURI ) { 167 if ( keywords != null ) { 168 for ( int i = 0; i < keywords.length; i++ ) { 169 Element node = XMLTools.appendElement( xmlNode, namespaceURI, "keywords" ); 170 appendKeywords( node, keywords[i], namespaceURI ); 171 } 172 } 173 } 174 175 /** 176 * Appends a <code>keywords</code> -element to the passed <code>Element</code> and fills it 177 * with the available keywords. 178 * 179 * @param xmlNode 180 * @param keywords 181 * @param namespaceURI 182 */ 183 protected static void appendKeywords( Element xmlNode, Keywords keywords, URI namespaceURI ) { 184 if ( keywords != null ) { 185 String[] kw = keywords.getKeywords(); 186 for ( int i = 0; i < kw.length; i++ ) { 187 XMLTools.appendElement( xmlNode, namespaceURI, "keyword", kw[i] ); 188 } 189 if ( keywords.getThesaurusName() != null ) { 190 XMLTools.appendElement( xmlNode, namespaceURI, "type", keywords.getThesaurusName() ); 191 } 192 } 193 } 194 195 /** 196 * Appends an <code>XML</code> representation of the passed <code>TimeSequence</code> to the 197 * passed <code>Element</code>. 198 * 199 * @param xmlNode 200 * @param timeSeq 201 * @param namespaceURI 202 */ 203 protected static void appendTemporalDomain( Element xmlNode, TimeSequence timeSeq, URI namespaceURI ) { 204 if ( timeSeq != null ) { 205 Element node = XMLTools.appendElement( xmlNode, namespaceURI, "temporalDomain", null ); 206 TimePeriod[] tPer = timeSeq.getTimePeriod(); 207 if ( tPer != null ) { 208 for ( int i = 0; i < tPer.length; i++ ) { 209 appendTimePeriod( node, tPer[i], namespaceURI ); 210 } 211 } 212 213 TimePosition[] tPos = timeSeq.getTimePosition(); 214 if ( tPos != null ) { 215 for ( int i = 0; i < tPos.length; i++ ) { 216 appendTimePosition( node, tPos[i] ); 217 } 218 } 219 } 220 } 221 222 /** 223 * Appends an <code>XML</code> representation of the passed <code>TimePeriod</code> to the 224 * passed <code>Element</code>. 225 * 226 * @param xmlNode 227 * @param tPeriod 228 * @param namespaceURI 229 */ 230 protected static void appendTimePeriod( Element xmlNode, TimePeriod tPeriod, URI namespaceURI ) { 231 Element node = XMLTools.appendElement( xmlNode, namespaceURI, "timePeriod" ); 232 appendTimePosition( node, tPeriod.getBeginPosition() ); 233 appendTimePosition( node, tPeriod.getEndPosition() ); 234 appendTimeResolution( node, tPeriod.getTimeResolution() ); 235 } 236 237 /** 238 * Appends an <code>XML/GML</code> representation of the passed <code>TimeDuration</code> to 239 * the passed <code>Element</code>. 240 * 241 * @param xmlNode 242 * @param duration 243 */ 244 protected static void appendTimeResolution( Element xmlNode, TimeDuration duration ) { 245 XMLTools.appendElement( xmlNode, GMLNS, "gml:timeResolution", duration.getAsGMLTimeDuration() ); 246 } 247 248 /** 249 * Appends an <code>XML</code> representation of the passed <code>Values</code> to the 250 * passed <code>Element</code>. 251 * 252 * @param xmlNode 253 * @param values 254 * @param namespaceURI 255 */ 256 protected static void appendValues( Element xmlNode, Values values, URI namespaceURI ) { 257 Element node = XMLTools.appendElement( xmlNode, namespaceURI, "values" ); 258 if ( values.getType() != null ) { 259 node.setAttribute( "type", values.getType().toString() ); 260 } 261 if ( values.getSemantic() != null ) { 262 node.setAttribute( "xmlns:dgr", namespaceURI.toString() ); 263 node.setAttributeNS( namespaceURI.toString(), "dgr:semantic", values.getSemantic().toString() ); 264 } 265 Interval[] intervals = values.getInterval(); 266 if ( intervals != null ) { 267 for ( int i = 0; i < intervals.length; i++ ) { 268 appendInterval( node, intervals[i], namespaceURI ); 269 } 270 } 271 TypedLiteral[] sVal = values.getSingleValue(); 272 if ( sVal != null ) { 273 for ( int i = 0; i < sVal.length; i++ ) { 274 appendTypedLiteral( node, sVal[i], "singleValue", namespaceURI ); 275 } 276 } 277 } 278 279 /** 280 * Appends an <code>XML</code> representation of the passed <code>Interval</code> to the 281 * passed <code>Element</code>. 282 * 283 * @param xmlNode 284 * @param interval 285 * @param namespaceURI 286 */ 287 protected static void appendInterval( Element xmlNode, Interval interval, URI namespaceURI ) { 288 Element node = XMLTools.appendElement( xmlNode, namespaceURI, "interval" ); 289 Element inter = node; 290 if ( interval.getType() != null ) { 291 node.setAttribute( "type", interval.getType().toString() ); 292 } 293 294 if ( interval.getSemantic() != null ) { 295 node.setAttribute( "xmlns:dgr", namespaceURI.toString() ); 296 node.setAttributeNS( namespaceURI.toString(), "dgr:semantic", interval.getSemantic().toString() ); 297 } 298 node.setAttribute( "atomic", "" + interval.isAtomic() ); 299 if ( interval.getClosure() != null && interval.getClosure().value != "" && interval.getClosure().value != null ) { 300 node.setAttribute( "xmlns:dgr", namespaceURI.toString() ); 301 node.setAttributeNS( namespaceURI.toString(), "dgr:closure", interval.getClosure().value ); 302 } 303 node = XMLTools.appendElement( inter, namespaceURI, "min", interval.getMin().getValue() ); 304 if ( interval.getMin().getType() != null ) { 305 node.setAttribute( "type", interval.getMin().getType().toString() ); 306 } 307 node = XMLTools.appendElement( inter, namespaceURI, "max", interval.getMin().getValue() ); 308 if ( interval.getMax().getType() != null ) { 309 node.setAttribute( "type", interval.getMax().getType().toString() ); 310 } 311 node = XMLTools.appendElement( inter, namespaceURI, "res", interval.getRes().getValue() ); 312 if ( interval.getRes().getType() != null ) { 313 node.setAttribute( "type", interval.getRes().getType().toString() ); 314 } 315 } 316 317 /** 318 * Appends an <code>XML</code> representation of the passed <code>TypedLiteral</code> to the 319 * passed <code>Element</code>. 320 * 321 * @param xmlNode 322 * @param singleValue 323 * @param name 324 * @param namespaceURI 325 */ 326 protected static void appendTypedLiteral( Element xmlNode, TypedLiteral singleValue, String name, URI namespaceURI ) { 327 Node node = XMLTools.appendElement( xmlNode, namespaceURI, name, singleValue.getValue() ); 328 if ( singleValue.getType() != null ) { 329 ( (Element) node ).setAttribute( "type", singleValue.getType().toString() ); 330 } 331 } 332 333 /** 334 * Appends an <code>XML</code> representation of the passed <code>CodeList</code> to the 335 * passed <code>Element</code>. 336 * 337 * @param xmlNode 338 * @param codeList 339 * @param namespaceURI 340 */ 341 protected static void appendCodeList( Element xmlNode, CodeList codeList, URI namespaceURI ) { 342 String[] codes = codeList.getCodes(); 343 String s = StringTools.arrayToString( codes, ' ' ); 344 Node node = XMLTools.appendElement( xmlNode, namespaceURI, codeList.getName(), s ); 345 if ( codeList.getCodeSpace() != null ) { 346 ( (Element) node ).setAttribute( "codeSpace", codeList.getCodeSpace().toString() ); 347 } 348 } 349 350 /** 351 * Appends the XML attributes of the given <code>SimpleLink</code> to the also passed 352 * <code>Element</code>. 353 * 354 * @param linkElement 355 * @param simpleLink 356 */ 357 protected static void appendSimpleLinkAttributes( Element linkElement, SimpleLink simpleLink ) { 358 359 linkElement.setAttributeNS( XLNNS.toString(), "xlink:type", "simple" ); 360 if ( simpleLink.getHref() != null ) { 361 linkElement.setAttributeNS( XLNNS.toString(), "xlink:href", simpleLink.getHref().toString() ); 362 } 363 if ( simpleLink.getRole() != null ) { 364 linkElement.setAttributeNS( XLNNS.toString(), "xlink:role", simpleLink.getRole().toString() ); 365 } 366 if ( simpleLink.getArcrole() != null ) { 367 linkElement.setAttributeNS( XLNNS.toString(), "xlink:arcrole", simpleLink.getArcrole().toString() ); 368 } 369 if ( simpleLink.getTitle() != null ) { 370 linkElement.setAttributeNS( XLNNS.toString(), "xlink:title", simpleLink.getTitle() ); 371 } 372 if ( simpleLink.getShow() != null ) { 373 linkElement.setAttributeNS( XLNNS.toString(), "xlink:show", simpleLink.getShow() ); 374 } 375 if ( simpleLink.getActuate() != null ) { 376 linkElement.setAttributeNS( XLNNS.toString(), "xlink:actuate", simpleLink.getActuate() ); 377 } 378 } 379 380 /** 381 * Appends the <code>DOM</code> representation of a simple <code>XLink</code> -element to 382 * the passed <code>Element</code>. 383 * 384 * @param xmlNode 385 * @param elementName 386 * @param onlineResource 387 * @param namespaceURI 388 */ 389 protected static void appendOnlineResource( Element xmlNode, String elementName, OnlineResource onlineResource, 390 URI namespaceURI ) { 391 Element linkElement = XMLTools.appendElement( xmlNode, namespaceURI, elementName ); 392 linkElement.setAttributeNS( XLNNS.toString(), "xlink:type", "simple" ); 393 linkElement.setAttributeNS( XLNNS.toString(), "xlink:href", onlineResource.getLinkage().getHref().toString() ); 394 } 395 396 /** 397 * Appends the <code>DOM</code> representation of the given <code>PropertyPath</code> as a 398 * new text node to the given element (including necessary namespace bindings). 399 * 400 * @param element 401 * Element node where the PropertyPath is appended to 402 * @param propertyPath 403 */ 404 protected static void appendPropertyPath( Element element, PropertyPath propertyPath ) { 405 StringBuffer sb = new StringBuffer(); 406 sb.append( propertyPath ); 407 408 Text textNode = element.getOwnerDocument().createTextNode( sb.toString() ); 409 element.appendChild( textNode ); 410 XMLTools.appendNSBindings( element, propertyPath.getNamespaceContext() ); 411 } 412 413 /** 414 * Appends the <code>DOM</code> representation of the given feature id to the given element. 415 * 416 * @param root 417 * Element node where the "ogc:FeatureId" element is appended to 418 * @param fid 419 * feature identifier 420 */ 421 protected static void appendFeatureId( Element root, String fid ) { 422 Element gmlObjectIdElement = XMLTools.appendElement( root, OGCNS, "ogc:FeatureId" ); 423 gmlObjectIdElement.setAttribute( "fid", fid ); 424 } 425 426 /** 427 * Appends the <code>DOM</code> representation of the given {@link Geometry} to the given 428 * element. 429 * 430 * TODO Do this a better way... 431 * 432 * @param el 433 * element node where the geometry is appended to 434 * @param geom 435 * geometry to be appended 436 * @throws GeometryException 437 */ 438 protected static void appendGeometry( Element el, Geometry geom ) 439 throws GeometryException { 440 441 StringBuffer sb = new StringBuffer(); 442 sb.append( "<dummy xmlns:gml=\"" ); 443 sb.append( CommonNamespaces.GMLNS.toString() ); 444 sb.append( "\">" ); 445 sb.append( GMLGeometryAdapter.export( geom ) ); 446 sb.append( "</dummy>" ); 447 448 ByteArrayInputStream bis = new ByteArrayInputStream( sb.toString().getBytes() ); 449 try { 450 GMLDocument doc = new GMLDocument(); 451 doc.load( bis, XMLFragment.DEFAULT_URL ); 452 XMLTools.insertNodeInto( XMLTools.getFirstChildElement( doc.getRootElement() ), el ); 453 } catch ( Exception e ) { 454 throw new GeometryException( e.getMessage() ); 455 } 456 } 457 }