/* * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package thredds.wcs.v1_0_0_Plus; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.output.XMLOutputter; import java.net.URI; import java.util.List; import java.util.Collections; import java.util.ArrayList; import java.io.PrintWriter; import java.io.IOException; /** * _more_ * * @author edavis * @since 4.0 */ public class GetCapabilities extends WcsRequest { // private static org.slf4j.Logger log = // org.slf4j.LoggerFactory.getLogger( GetCapabilities.class ); public enum Section { All( ""), Service( "WCS_Capabilities/Service"), Capability( "WCS_Capabilities/Capability" ), ContentMetadata( "WCS_Capabilities/ContentMetadata" ); private final String altId; Section( String altId) { this.altId = altId; } public String toString() { return altId; } public static Section getSection( String altId) { for ( Section curSection : Section.values()) { if ( curSection.altId.equals( altId)) return curSection; } throw new IllegalArgumentException( "No such instance <" + altId + ">."); } } private URI serverURI; private Section section; private ServiceInfo serviceInfo; private String updateSequence; private Document capabilitiesReport; public GetCapabilities( Operation operation, String version, WcsDataset dataset, URI serverURI, Section section, String updateSequence, ServiceInfo serviceInfo ) { super( operation, version, dataset); this.serverURI = serverURI; this.section = section; this.serviceInfo = serviceInfo; this.updateSequence = updateSequence; if ( this.serverURI == null ) throw new IllegalArgumentException( "Non-null server URI required."); if ( this.section == null ) throw new IllegalArgumentException( "Non-null sections list required (may be empty)."); } String getCurrentUpdateSequence() { // ToDo If decide to support updateSequence, need to // ToDo 1) update getCurrentUpdateSequence() and // ToDo 2) update logic to handle exceptions appropriately. // if (updateSequence == null) // return null; return null; } public Document getCapabilitiesReport() throws WcsException { if ( this.capabilitiesReport == null ) capabilitiesReport = generateCapabilities(); return capabilitiesReport; } public void writeCapabilitiesReport( PrintWriter pw ) throws WcsException, IOException { XMLOutputter xmlOutputter = new XMLOutputter( org.jdom2.output.Format.getPrettyFormat() ); xmlOutputter.output( getCapabilitiesReport(), pw ); } public Document generateCapabilities() throws WcsException { Element rootElem; if ( section.equals( Section.All)) { rootElem = new Element( "WCS_Capabilities", wcsNS ); rootElem.addContent( generateServiceSection( this.serviceInfo ) ); rootElem.addContent( generateCapabilitySection() ); rootElem.addContent( generateContentMetadataSection() ); } else if ( section.equals( Section.Service)) { rootElem = generateServiceSection( this.serviceInfo ); } else if ( section.equals( Section.Capability)) { rootElem = generateCapabilitySection(); } else if ( section.equals( Section.ContentMetadata)) { rootElem = generateContentMetadataSection(); } else { throw new WcsException(); } rootElem.addNamespaceDeclaration( gmlNS ); rootElem.addNamespaceDeclaration( xlinkNS ); rootElem.setAttribute( "version", this.getVersion() ); // ToDo If decide to support updateSequence, need to // ToDo 1) update getCurrentUpdateSequence() and // ToDo 2) update logic to handle exceptions appropriately. if ( this.getCurrentUpdateSequence() != null ) rootElem.setAttribute( "updateSequence", this.getCurrentUpdateSequence()); return new Document( rootElem ); } public Element generateServiceSection( ServiceInfo serviceInfo ) { // WCS_Capabilities/Service Element serviceElem = new Element( "Service", wcsNS ); if ( serviceInfo != null ) { // WCS_Capabilities/Service/gml:metaDataProperty [0..*] // WCS_Capabilities/Service/gml:description [0..1] // WCS_Capabilities/Service/gml:name [0..*] // WCS_Capabilities/Service/metadataLink [0..*] // WCS_Capabilities/Service/description [0..1] if ( serviceInfo.getDescription() != null ) serviceElem.addContent( new Element( "description", wcsNS ).addContent( serviceInfo.getDescription() ) ); // WCS_Capabilities/Service/name if ( serviceInfo.getName() != null ) serviceElem.addContent( new Element( "name", wcsNS ).addContent( serviceInfo.getName() ) ); // WCS_Capabilities/Service/label (string) if ( serviceInfo.getLabel() != null ) serviceElem.addContent( new Element( "label", wcsNS ).addContent( serviceInfo.getLabel() ) ); // WCS_Capabilities/Service/keywords [0..*](string) // WCS_Capabilities/Service/keywords/keyword [1..*](string) // WCS_Capabilities/Service/keywords/type [0..1](string) // WCS_Capabilities/Service/keywords/type@codeSpace [0..1](URI) if ( serviceInfo.getKeywords() != null && serviceInfo.getKeywords().size() > 0 ) { Element keywordsElem = new Element( "keywords", wcsNS ); for ( String curKey : serviceInfo.getKeywords() ) { keywordsElem.addContent( new Element( "keyword", wcsNS ).addContent( curKey ) ); } serviceElem.addContent( keywordsElem ); } ResponsibleParty respParty = serviceInfo.getResponsibleParty(); if ( respParty != null ) { // WCS_Capabilities/Service/responsibleParty [0..1](string) Element respPartyElem = new Element( "responsibleParty", wcsNS ); //----- // WCS_Capabilities/Service/responsibleParty/individualName [1](string) // AND/OR // WCS_Capabilities/Service/responsibleParty/organisationName [1](string) //----- if (respParty.getIndividualName() != null ) respPartyElem.addContent( new Element( "individualName", wcsNS).addContent( respParty.getIndividualName())); if (respParty.getOrganizationName() != null ) respPartyElem.addContent( new Element( "organisationName", wcsNS).addContent( respParty.getOrganizationName())); // WCS_Capabilities/Service/responsibleParty/positionName [0..1](string) if (respParty.getPositionName() != null ) respPartyElem.addContent( new Element( "positionName", wcsNS).addContent( respParty.getPositionName())); // WCS_Capabilities/Service/responsibleParty/contactInfo [0..1] if ( respParty.getContact() != null ) { Element contactElem = new Element( "contactInfo", wcsNS); // WCS_Capabilities/Service/responsibleParty/contactInfo/phone/{voice|facsimile} [0..1] (string) Element phoneElem = new Element( "phone", wcsNS ); if ( respParty.getContact().getVoicePhone() != null ) for ( String curVoicePhone : respParty.getContact().getVoicePhone() ) phoneElem.addContent( new Element( "voice", wcsNS ).addContent( curVoicePhone ) ); if ( respParty.getContact().getFaxPhone() != null ) for ( String curFaxPhone : respParty.getContact().getFaxPhone() ) phoneElem.addContent( new Element( "facsimile", wcsNS ).addContent( curFaxPhone ) ); if ( phoneElem.getContentSize() > 0 ) contactElem.addContent( phoneElem); // WCS_Capabilities/Service/responsibleParty/contactInfo/address [0..1] ResponsibleParty.Address contactAddress = respParty.getContact().getAddress(); if ( contactAddress != null ) { Element addressElem = new Element( "address", wcsNS ); if ( contactAddress.getDeliveryPoint() != null ) { for ( String curDP : contactAddress.getDeliveryPoint() ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/deliveryPoint [0..*] addressElem.addContent( new Element( "deliveryPoint", wcsNS ).addContent( curDP ) ); } } if ( contactAddress.getCity() != null ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/city [0..1] addressElem.addContent( new Element( "city", wcsNS ).addContent( contactAddress.getCity() ) ); } if ( contactAddress.getAdminArea() != null ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/administrativeArea [0..1] addressElem.addContent( new Element( "administrativeArea", wcsNS ) .addContent( contactAddress.getAdminArea() ) ); } if ( contactAddress.getPostalCode() != null ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/postalCode [0..1] addressElem.addContent( new Element( "postalCode", wcsNS ) .addContent( contactAddress.getPostalCode() ) ); } if ( contactAddress.getCountry() != null ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/country [0..1] addressElem.addContent( new Element( "country", wcsNS ) .addContent( contactAddress.getCountry() ) ); } if ( contactAddress.getEmail() != null ) { for ( String curEmail : contactAddress.getEmail() ) { // WCS_Capabilities/Service/responsibleParty/contactInfo/address/electronicMailAddress [0..*] addressElem.addContent( new Element( "electronicMailAddress", wcsNS ) .addContent( curEmail ) ); } } contactElem.addContent( addressElem ); } // WCS_Capabilities/Service/responsibleParty/contactInfo/onlineResource@{xlink:href|xlink:title} [0..1] ResponsibleParty.OnlineResource onlineRes = respParty.getContact().getOnlineResource(); if ( onlineRes != null ) { Element onlineResElem = new Element( "onlineResource", wcsNS); onlineResElem.setAttribute( "type", "simple" ); if ( onlineRes.getTitle() != null ) onlineResElem.setAttribute( "title", onlineRes.getTitle(), xlinkNS ); if ( onlineRes.getLink() != null ) onlineResElem.setAttribute( "href", onlineRes.getLink().toString(), xlinkNS ); contactElem.addContent( onlineResElem); } respPartyElem.addContent( contactElem); } serviceElem.addContent( respPartyElem ); } } // WCS_Capabilities/Service/fees [1] ("NONE") serviceElem.addContent( new Element( "fees", wcsNS ).addContent( "NONE")); // WCS_Capabilities/Service/accessConstraints [1..*] ("NONE") serviceElem.addContent( new Element( "accessConstraints", wcsNS ).addContent( "NONE" ) ); return serviceElem; } public Element generateCapabilitySection() { // WCS_Capabilities/Capability Element capElem = new Element( "Capability", wcsNS ); // WCS_Capabilities/Capability/ Element requestElem = new Element( "Request", wcsNS ); requestElem.addContent( genCapabilityOperationElem( Operation.GetCapabilities.toString() )); requestElem.addContent( genCapabilityOperationElem( Operation.DescribeCoverage.toString() )); requestElem.addContent( genCapabilityOperationElem( Operation.GetCoverage.toString() )); capElem.addContent( requestElem); capElem.addContent( new Element( "Exception", wcsNS ).addContent( new Element( "Format", wcsNS).addContent( "application/vnd.ogc.se_xml"))); return capElem; } private Element genCapabilityOperationElem( String operationAsString ) { Element getCapOpsElem; getCapOpsElem= new Element( operationAsString, wcsNS ); getCapOpsElem.addContent( new Element( "DCPType", wcsNS ).addContent( new Element( "HTTP", wcsNS ).addContent( new Element( "Get", wcsNS ).addContent( new Element( "OnlineResource", wcsNS ).setAttribute( "href", serverURI.toString(), xlinkNS ) ) ) ) ); return getCapOpsElem; } public Element generateContentMetadataSection() { // WCS_Capabilities/ContentMetadata Element contMdElem = new Element( "ContentMetadata", wcsNS ); // ToDo WCS 1.0Plus - change GridDatatype to GridDataset.Gridset for ( WcsCoverage curCoverage : this.getDataset().getAvailableCoverageCollection()) // WCS_Capabilities/ContentMetadata/CoverageOfferingBrief // WCS_Capabilities/ContentMetadata/CoverageOfferingBrief contMdElem.addContent( genCoverageOfferingBriefElem( "CoverageOfferingBrief", curCoverage.getName(), curCoverage.getLabel(), curCoverage.getDescription(), curCoverage.getCoordinateSystem() ) ); return contMdElem; } /** * Contain the content needed for a WCS_Capabilities/Service section. */ public static class ServiceInfo { private String name, label, description; private List<String> keywords; private ResponsibleParty responsibleParty; private String fees; private List<String> accessConstraints; public ServiceInfo( String name, String label, String description, List<String> keywords, ResponsibleParty responsibleParty, String fees, List<String> accessConstraints ) { this.name = name; this.label = label; this.description = description; this.keywords = new ArrayList<String>( keywords); this.responsibleParty = responsibleParty; this.fees = fees; this.accessConstraints = new ArrayList<String>( accessConstraints ); } public String getName() { return name; } public String getLabel() { return label; } public String getDescription() { return description; } public List<String> getKeywords() { return Collections.unmodifiableList( keywords); } public ResponsibleParty getResponsibleParty() { return responsibleParty; } public String getFees() { return fees; } public List<String> getAccessConstraints() { return Collections.unmodifiableList( accessConstraints); } } /** * Contain content needed for a GetCapabilities ServiceProvider section. */ public static class ResponsibleParty { public ResponsibleParty( String individualName, String organizationName, String positionName, ContactInfo contactInfo ) { this.individualName = individualName; this.organizationName = organizationName; this.positionName = positionName; this.contactInfo = contactInfo; } public String getIndividualName() { return individualName; } private String individualName; public String getOrganizationName() { return organizationName; } private String organizationName; public String getPositionName() { return positionName; } private String positionName; public ContactInfo getContact() { return contactInfo; } private ContactInfo contactInfo; public static class ContactInfo { public ContactInfo( List<String> voicePhone, List<String> faxPhone, Address address, OnlineResource onlineResource ) { this.voicePhone = new ArrayList<String>( voicePhone); this.faxPhone = new ArrayList<String>( faxPhone); this.address = address; this.onlineResource = onlineResource; } public List<String> getVoicePhone() { return Collections.unmodifiableList( voicePhone); } private List<String> voicePhone; public List<String> getFaxPhone() { return Collections.unmodifiableList( faxPhone); } private List<String> faxPhone; public Address getAddress() { return address; } private Address address; public OnlineResource getOnlineResource() { return onlineResource; } private OnlineResource onlineResource; } public static class Address { public Address( List<String> deliveryPoint, String city, String adminArea, String postalCode, String country, List<String> email ) { this.deliveryPoint = new ArrayList<String>( deliveryPoint); this.city = city; this.adminArea = adminArea; this.postalCode = postalCode; this.country = country; this.email = new ArrayList<String>( email); } public List<String> getDeliveryPoint() { return Collections.unmodifiableList( deliveryPoint); } private List<String> deliveryPoint; public String getCity() { return city; } private String city; public String getAdminArea() { return adminArea; } private String adminArea; public String getPostalCode() { return postalCode; } private String postalCode; public String getCountry() { return country; } private String country; public List<String> getEmail() { return Collections.unmodifiableList( email); } private List<String> email; } public static class OnlineResource { public OnlineResource( URI link, String title ) { this.link = link; this.title = title; } public URI getLink() { return link; } private URI link; public String getTitle() { return title; } private String title; } } }