001 // $HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/owscommon/XMLFactory.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53115 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.owscommon;
045
046 import java.io.UnsupportedEncodingException;
047 import java.net.URI;
048 import java.net.URL;
049 import java.net.URLEncoder;
050
051 import org.deegree.datatypes.QualifiedName;
052 import org.deegree.framework.util.CharsetUtils;
053 import org.deegree.framework.xml.XMLFragment;
054 import org.deegree.framework.xml.XMLParsingException;
055 import org.deegree.framework.xml.XMLTools;
056 import org.deegree.model.metadata.iso19115.Address;
057 import org.deegree.model.metadata.iso19115.ContactInfo;
058 import org.deegree.model.metadata.iso19115.Keywords;
059 import org.deegree.model.metadata.iso19115.Linkage;
060 import org.deegree.model.metadata.iso19115.OnlineResource;
061 import org.deegree.model.metadata.iso19115.Phone;
062 import org.deegree.model.metadata.iso19115.TypeCode;
063 import org.deegree.ogcbase.CommonNamespaces;
064 import org.deegree.ogcwebservices.ExceptionDocument;
065 import org.deegree.ogcwebservices.ExceptionReport;
066 import org.deegree.ogcwebservices.OGCWebServiceException;
067 import org.deegree.ogcwebservices.getcapabilities.DCPType;
068 import org.deegree.ogcwebservices.getcapabilities.HTTP;
069 import org.deegree.ogcwebservices.getcapabilities.Operation;
070 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
071 import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
072 import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
073 import org.w3c.dom.Element;
074
075 /**
076 * Factory to create XML representations of components that are defined in the
077 * <code>OWS Common Implementation Capabilities Specification 0.3</code>.
078 *
079 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
080 * @author last edited by: $Author: aschmitz $
081 *
082 * @version $Revision: 9502 $, $Date: 2008-01-10 13:23:03 +0100 (Do, 10 Jan 2008) $
083 */
084 public class XMLFactory extends org.deegree.ogcbase.XMLFactory {
085
086 protected static final URI OWSNS = CommonNamespaces.OWSNS;
087
088 private static final String POGC = CommonNamespaces.OGC_PREFIX + ':';
089
090 protected static final URI DEEGREECSWNS = CommonNamespaces.DEEGREECSW;
091
092 /**
093 * Exports an <tt>ExceptionReport</tt> to an XML Document as defined in the
094 * <code>OGC common implementation specification 0.2.0</code>.
095 *
096 * @param exr
097 * @return a new ServiceException document
098 */
099 public static XMLFragment export( ExceptionReport exr ) {
100
101 ExceptionDocument eDoc = new ExceptionDocument();
102 eDoc.createEmptyDocument();
103 Element node = eDoc.getRootElement();
104
105 for ( int i = 0; i < exr.getExceptions().length; i++ ) {
106 appendException( node, exr.getExceptions()[i], false );
107 }
108
109 return eDoc;
110 }
111
112 /**
113 * @param exr
114 * @return a new ServiceException document
115 */
116 public static XMLFragment exportNS( ExceptionReport exr ) {
117
118 ExceptionDocument eDoc = new ExceptionDocument();
119 eDoc.createEmptyDocumentNS();
120 Element node = eDoc.getRootElement();
121
122 for ( int i = 0; i < exr.getExceptions().length; i++ ) {
123 appendException( node, exr.getExceptions()[i], true );
124 }
125
126 return eDoc;
127
128 }
129
130 /**
131 * @param exr
132 * @return a new ExceptionReport document according to OWS 1.0.0
133 */
134 public static XMLFragment exportExceptionReport( ExceptionReport exr ) {
135 XMLFragment doc = new XMLFragment( new QualifiedName( "ows", "ExceptionReport", OWSNS ) );
136 Element root = doc.getRootElement();
137
138 for ( int i = 0; i < exr.getExceptions().length; i++ ) {
139 OGCWebServiceException exc = exr.getExceptions()[i];
140 Element e = XMLTools.appendElement( root, OWSNS, "ows:Exception", exc.getMessage() );
141 if ( exc.getCode() != null ) {
142 e.setAttribute( "exceptionCode", exc.getCode().value );
143 }
144
145 String locator = exc.getLocator();
146 try {
147 if ( locator != null ) {
148 locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() );
149 } else {
150 locator = "unknown";
151 }
152 } catch ( UnsupportedEncodingException _ ) {
153 // if catched why not do something -> setting locator to "unknown"
154 locator = "unknown";
155 }
156 e.setAttribute( "locator", locator );
157 }
158
159 return doc;
160
161 }
162
163 /**
164 * appends a xml representation of an <tt>OGCWebServiceException</tt> to the passed
165 * <tt>Element</tt>
166 *
167 * @param node
168 * @param ex
169 * @param namespace
170 * if true, the ogc prefix (bound to the ogc namespace) will be appended
171 */
172 protected static void appendException( Element node, OGCWebServiceException ex, boolean namespace ) {
173
174 if ( namespace ) {
175 node = XMLTools.appendElement( node, OGCNS, POGC + "ServiceException", ex.getMessage() );
176 } else {
177 node = XMLTools.appendElement( node, null, "ServiceException", ex.getMessage() );
178 }
179
180 if ( ex.getCode() != null ) {
181 node.setAttribute( "code", ex.getCode().value );
182 }
183 String locator = ex.getLocator();
184 try {
185 if ( locator != null ) {
186 locator = URLEncoder.encode( locator, CharsetUtils.getSystemCharset() );
187 } else {
188 locator = "unknown";
189 }
190 } catch ( UnsupportedEncodingException e ) {
191 // if catched why not do something -> setting locator to "unknown"
192 locator = "unknown";
193 }
194 node.setAttribute( "locator", locator );
195 }
196
197 /**
198 * Appends the DOM representation of the <code>ServiceIdentification</code>- section to the
199 * passed <code>Element</code>.
200 *
201 * @param root
202 * @param serviceIdentification
203 * @throws XMLParsingException
204 */
205 protected static void appendServiceIdentification( Element root, ServiceIdentification serviceIdentification ) {
206
207 // 'ServiceIdentification'-element
208 Element serviceIdentificationNode = XMLTools.appendElement( root, OWSNS, "ows:ServiceIdentification" );
209
210 // 'ServiceType'-element
211 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceType",
212 serviceIdentification.getServiceType().getCode() );
213
214 // 'ServiceTypeVersion'-elements
215 String[] versions = serviceIdentification.getServiceTypeVersions();
216 for ( int i = 0; i < versions.length; i++ ) {
217 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:ServiceTypeVersion", versions[i] );
218 }
219
220 // 'Title'-element
221 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Title", serviceIdentification.getTitle() );
222
223 // 'Abstract'-element
224 if ( serviceIdentification.getAbstract() != null ) {
225 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Abstract",
226 serviceIdentification.getAbstract() );
227 }
228
229 // 'Keywords'-element
230 appendOWSKeywords( serviceIdentificationNode, serviceIdentification.getKeywords() );
231
232 // 'Fees'-element
233 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:Fees", serviceIdentification.getFees() );
234
235 // 'AccessConstraints'-element
236 String[] constraints = serviceIdentification.getAccessConstraints();
237 if ( constraints != null ) {
238 for ( int i = 0; i < constraints.length; i++ ) {
239 XMLTools.appendElement( serviceIdentificationNode, OWSNS, "ows:AccessConstraints", constraints[i] );
240 }
241 }
242 }
243
244 /**
245 * Appends a <code>ows:Keywords</code> -element for each <code>Keywords</code> object of the
246 * passed array to the passed <code>Element</code>.
247 *
248 * @param xmlNode
249 * @param keywords
250 */
251 protected static void appendOWSKeywords( Element xmlNode, Keywords[] keywords ) {
252 if ( keywords != null ) {
253 for ( int i = 0; i < keywords.length; i++ ) {
254 Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Keywords" );
255 appendOWSKeywords( node, keywords[i] );
256 }
257 }
258 }
259
260 /**
261 * Appends a <code>ows:Keywords</code> -element to the passed <code>Element</code> and fills
262 * it with the available keywords.
263 *
264 * @param xmlNode
265 * @param keywords
266 */
267 protected static void appendOWSKeywords( Element xmlNode, Keywords keywords ) {
268 if ( keywords != null ) {
269 String[] kw = keywords.getKeywords();
270 for ( int i = 0; i < kw.length; i++ ) {
271 XMLTools.appendElement( xmlNode, OWSNS, "ows:Keyword", kw[i] );
272 }
273 TypeCode typeCode = keywords.getTypeCode();
274 if ( typeCode != null ) {
275 Element node = XMLTools.appendElement( xmlNode, OWSNS, "ows:Type", typeCode.getCode() );
276 if ( typeCode.getCodeSpace() != null ) {
277 node.setAttribute( "codeSpace", typeCode.getCodeSpace().toString() );
278 }
279 }
280 }
281 }
282
283 /**
284 * Appends the DOM representation of the <code>ServiceProvider</code>- section to the passed
285 * <code>Element</code>.
286 *
287 * @param root
288 * @param serviceProvider
289 * @throws XMLParsingException
290 */
291 protected static void appendServiceProvider( Element root, ServiceProvider serviceProvider ) {
292
293 // 'ServiceProvider'-element
294 Element serviceProviderNode = XMLTools.appendElement( root, OWSNS, "ows:ServiceProvider" );
295
296 // 'ProviderName'-element
297 XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ProviderName", serviceProvider.getProviderName() );
298
299 // 'ProviderSite'-element
300 if ( serviceProvider.getProviderSite() != null ) {
301 Element providerSiteNode = XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ProviderSite" );
302 appendSimpleLinkAttributes( providerSiteNode, serviceProvider.getProviderSite() );
303 }
304
305 // 'ServiceContact'-element
306 Element serviceContactNode = XMLTools.appendElement( serviceProviderNode, OWSNS, "ows:ServiceContact" );
307
308 // 'IndividualName'-element
309 XMLTools.appendElement( serviceContactNode, OWSNS, "ows:IndividualName", serviceProvider.getIndividualName() );
310
311 // 'PositionName'-element
312 if ( serviceProvider.getPositionName() != null ) {
313 XMLTools.appendElement( serviceContactNode, OWSNS, "ows:PositionName", serviceProvider.getPositionName() );
314 }
315
316 // 'ContactInfo'-element
317 ContactInfo contactInfo = serviceProvider.getContactInfo();
318 if ( contactInfo != null ) {
319 Element contactInfoNode = XMLTools.appendElement( serviceContactNode, OWSNS, "ows:ContactInfo" );
320 Phone phone = contactInfo.getPhone();
321 if ( phone != null ) {
322 appendPhone( contactInfoNode, phone );
323 }
324 Address address = contactInfo.getAddress();
325 if ( address != null ) {
326 appendAddress( contactInfoNode, address );
327 }
328 OnlineResource onlineResource = contactInfo.getOnLineResource();
329 if ( onlineResource != null ) {
330 appendOnlineResource( contactInfoNode, "ows:OnlineResource", onlineResource, OWSNS );
331 }
332 String hoursOfService = contactInfo.getHoursOfService();
333 if ( hoursOfService != null ) {
334 XMLTools.appendElement( contactInfoNode, OWSNS, "ows:HoursOfService", hoursOfService );
335 }
336 String contactInstructions = contactInfo.getContactInstructions();
337 if ( contactInstructions != null ) {
338 XMLTools.appendElement( contactInfoNode, OWSNS, "ows:ContactInstructions", contactInstructions );
339 }
340 }
341 TypeCode role = serviceProvider.getRole();
342 if ( role != null ) {
343 Element roleElement = XMLTools.appendElement( serviceContactNode, OWSNS, "ows:Role", role.getCode() );
344 if ( role.getCodeSpace() != null ) {
345 roleElement.setAttribute( "codeSpace", role.getCodeSpace().toString() );
346 }
347 }
348 }
349
350 /**
351 * Appends the DOM representation of the <code>Phone</code> -section to the passed
352 * <code>Element</code>.
353 *
354 * @param root
355 * @param phone
356 */
357 protected static void appendPhone( Element root, Phone phone ) {
358
359 // 'Phone'-element
360 Element phoneNode = XMLTools.appendElement( root, OWSNS, "ows:Phone" );
361
362 // 'Voice'-elements
363 String[] voiceNumbers = phone.getVoice();
364 for ( int i = 0; i < voiceNumbers.length; i++ ) {
365 XMLTools.appendElement( phoneNode, OWSNS, "ows:Voice", voiceNumbers[i] );
366 }
367
368 // 'Facsimile'-elements
369 String[] facsimileNumbers = phone.getFacsimile();
370 for ( int i = 0; i < facsimileNumbers.length; i++ ) {
371 XMLTools.appendElement( phoneNode, OWSNS, "ows:Facsimile", facsimileNumbers[i] );
372 }
373 }
374
375 /**
376 * Appends the DOM representation of the <code>Address</code> -section to the passed
377 * <code>Element</code>.
378 *
379 * @param root
380 * @param address
381 */
382 protected static void appendAddress( Element root, Address address ) {
383
384 // 'Address'-element
385 Element addressNode = XMLTools.appendElement( root, OWSNS, "ows:Address" );
386
387 // 'DeliveryPoint'-elements
388 String[] deliveryPoints = address.getDeliveryPoint();
389 for ( int i = 0; i < deliveryPoints.length; i++ ) {
390 XMLTools.appendElement( addressNode, OWSNS, "ows:DeliveryPoint", deliveryPoints[i] );
391 }
392
393 // 'City'-element
394 if ( address.getCity() != null ) {
395 XMLTools.appendElement( addressNode, OWSNS, "ows:City", address.getCity() );
396 }
397
398 // 'AdministrativeArea'-element
399 if ( address.getAdministrativeArea() != null ) {
400 XMLTools.appendElement( addressNode, OWSNS, "ows:AdministrativeArea", address.getAdministrativeArea() );
401 }
402
403 // 'PostalCode'-element
404 if ( address.getPostalCode() != null ) {
405 XMLTools.appendElement( addressNode, OWSNS, "ows:PostalCode", address.getPostalCode() );
406 }
407
408 // 'Country'-element
409 if ( address.getCountry() != null ) {
410 XMLTools.appendElement( addressNode, OWSNS, "ows:Country", address.getCountry() );
411 }
412
413 // 'ElectronicMailAddress'-elements
414 String[] electronicMailAddresses = address.getElectronicMailAddress();
415 if ( address.getElectronicMailAddress() != null ) {
416 for ( int i = 0; i < electronicMailAddresses.length; i++ ) {
417 XMLTools.appendElement( addressNode, OWSNS, "ows:ElectronicMailAddress", electronicMailAddresses[i] );
418 }
419 }
420 }
421
422 /**
423 * Appends the DOM representation of the <code>OperationsMetadata</code>- section to the
424 * passed <code>Element</code>.
425 *
426 * @param root
427 */
428 protected static void appendOperationsMetadata( Element root, OperationsMetadata operationsMetadata ) {
429
430 // 'ows:OperationsMetadata'-element
431 Element operationsMetadataNode = XMLTools.appendElement( root, OWSNS, "ows:OperationsMetadata" );
432
433 // append all Operations
434 Operation[] operations = operationsMetadata.getOperations();
435 for ( int i = 0; i < operations.length; i++ ) {
436 Operation operation = operations[i];
437
438 // 'ows:Operation'-element
439 Element operationElement = XMLTools.appendElement( operationsMetadataNode, OWSNS, "ows:Operation" );
440 operationElement.setAttribute( "name", operation.getName() );
441
442 // 'ows:DCP'-elements
443 DCPType[] dcps = operation.getDCPs();
444 for ( int j = 0; j < dcps.length; j++ ) {
445 appendDCP( operationElement, dcps[j] );
446 }
447
448 // 'ows:Parameter'-elements
449 OWSDomainType[] parameters = operation.getParameters();
450 for ( int j = 0; j < parameters.length; j++ ) {
451 appendParameter( operationElement, parameters[j], "ows:Parameter" );
452 }
453
454 // 'ows:Metadata'-elements
455 Object[] metadata = operation.getMetadata();
456 if ( metadata != null ) {
457 for ( int j = 0; j < metadata.length; j++ ) {
458 appendMetadata( operationElement, metadata[j] );
459 }
460 }
461 }
462
463 // append general parameters
464 OWSDomainType[] parameters = operationsMetadata.getParameter();
465 for ( int i = 0; i < parameters.length; i++ ) {
466 appendParameter( operationsMetadataNode, parameters[i], "ows:Parameter" );
467 }
468
469 // append constraints
470 OWSDomainType[] constraints = operationsMetadata.getConstraints();
471 for ( int i = 0; i < constraints.length; i++ ) {
472 appendParameter( operationsMetadataNode, constraints[i], "ows:Constraint" );
473 }
474 }
475
476 /**
477 * Appends the DOM representation of a <code>DCPType</code> instance to the passed
478 * <code>Element</code>.
479 *
480 * @param root
481 * @param dcp
482 */
483 protected static void appendDCP( Element root, DCPType dcp ) {
484
485 // 'ows:DCP'-element
486 Element dcpNode = XMLTools.appendElement( root, OWSNS, "ows:DCP" );
487
488 // currently, the only supported DCP is HTTP!
489 if ( dcp.getProtocol() instanceof HTTP ) {
490 HTTP http = (HTTP) dcp.getProtocol();
491
492 // 'ows:HTTP'-element
493 Element httpNode = XMLTools.appendElement( dcpNode, OWSNS, "ows:HTTP" );
494
495 // 'ows:Get'-elements
496 URL[] getURLs = http.getGetOnlineResources();
497 for ( int i = 0; i < getURLs.length; i++ ) {
498 appendOnlineResource( httpNode, "ows:Get", new OnlineResource( new Linkage( getURLs[i] ) ), OWSNS );
499 }
500
501 // 'ows:Post'-elements
502 URL[] postURLs = http.getPostOnlineResources();
503 for ( int i = 0; i < postURLs.length; i++ ) {
504 appendOnlineResource( httpNode, "ows:Post", new OnlineResource( new Linkage( postURLs[i] ) ), OWSNS );
505 }
506 }
507 }
508
509 /**
510 * Appends the DOM representation of a <code>OWSDomainType</code> instance to the passed
511 * <code>Element</code>.
512 *
513 * @param root
514 * @param parameter
515 */
516 protected static void appendParameter( Element root, OWSDomainType parameter, String elementName ) {
517
518 // 'ows:Parameter'-element
519 Element parameterNode = XMLTools.appendElement( root, OWSNS, elementName );
520 parameterNode.setAttribute( "name", parameter.getName() );
521
522 // 'ows:Value'-elements
523 String[] values = parameter.getValues();
524 for ( int i = 0; i < values.length; i++ ) {
525 XMLTools.appendElement( parameterNode, OWSNS, "ows:Value", values[i] );
526 }
527 }
528
529 /**
530 * Appends the DOM representation of a <code>Metadata</code> instance to the passed
531 * <code>Element</code>.
532 *
533 * @param root
534 * @param metadata
535 */
536 protected static void appendMetadata( Element root, Object metadata ) {
537
538 // TODO
539
540 }
541 }