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