/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.vfny.geoserver.wcs.responses;
import static org.geoserver.ows.util.ResponseUtils.*;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.MetadataLinkInfo;
import org.geoserver.config.ContactInfo;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.ows.URLMangler.URLType;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.wcs.WCSInfo;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.xml.transform.TransformerBase;
import org.geotools.xml.transform.Translator;
import org.springframework.context.ApplicationContext;
import org.vfny.geoserver.global.CoverageInfoLabelComparator;
import org.vfny.geoserver.util.requests.CapabilitiesRequest;
import org.vfny.geoserver.wcs.requests.WCSRequest;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* DOCUMENT ME!
*
* @author $Author: Alessio Fabiani (alessio.fabiani@gmail.com) $ (last
* modification)
* @author $Author: Simone Giannecchini (simboss1@gmail.com) $ (last
* modification)
*/
public class WCSCapsTransformer extends TransformerBase {
/** DOCUMENT ME! */
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(WCSCapsTransformer.class.getPackage()
.getName());
protected static final String WCS_URI = "http://www.opengis.net/wcs";
/** DOCUMENT ME! */
protected static final String WFS_URI = "http://www.opengis.net/wcs";
/** DOCUMENT ME! */
protected static final String CUR_VERSION = "1.0.0";
/** DOCUMENT ME! */
protected static final String XSI_PREFIX = "xsi";
/** DOCUMENT ME! */
protected static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
private static final String[] EXCEPTION_FORMATS = {
"application/vnd.ogc.se_xml", "application/vnd.ogc.se_inimage",
"application/vnd.ogc.se_blank"
};
/** DOCUMENT ME! */
private String baseUrl;
private ApplicationContext applicationContext;
/**
* DOCUMENT ME!
*
* @uml.property name="request"
* @uml.associationEnd multiplicity="(0 1)"
*/
protected WCSRequest request;
/**
* Creates a new WFSCapsTransformer object.
*/
public WCSCapsTransformer(String baseUrl,
ApplicationContext applicationContext) {
super();
if (baseUrl == null) {
throw new NullPointerException();
}
this.baseUrl = baseUrl;
this.setNamespaceDeclarationEnabled(false);
this.applicationContext = applicationContext;
}
/**
* DOCUMENT ME!
*
* @param handler
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Translator createTranslator(ContentHandler handler) {
return new WCSCapsTranslator(handler, applicationContext);
}
/**
* DOCUMENT ME!
*
* @return a Transformer propoerly configured to produce DescribeLayer
* responses.
*
* @throws TransformerException
* if it is thrown by <code>super.createTransformer()</code>
*/
public Transformer createTransformer() throws TransformerException {
return super.createTransformer();
}
/**
* DOCUMENT ME!
*
* @author Gabriel Roldan, Axios Engineering
* @version $Id
*/
private static class WCSCapsTranslator extends TranslatorSupport {
/**
* DOCUMENT ME!
*
* @uml.property name="request"
* @uml.associationEnd multiplicity="(0 1)"
*/
private CapabilitiesRequest request;
private ApplicationContext applicationContext;
/**
* Creates a new WFSCapsTranslator object.
*
* @param handler
* DOCUMENT ME!
*/
public WCSCapsTranslator(ContentHandler handler,
ApplicationContext applicationContext) {
super(handler, null, null);
this.applicationContext = applicationContext;
}
/**
* Encode the object.
*
* @param o
* The Object to encode.
*
* @throws IllegalArgumentException
* if the Object is not encodeable.
*/
public void encode(Object o) throws IllegalArgumentException {
if (!(o instanceof CapabilitiesRequest)) {
throw new IllegalArgumentException(new StringBuffer("Not a CapabilitiesRequest: ").append(
o).toString());
}
this.request = (CapabilitiesRequest) o;
final WCSInfo wcs = (WCSInfo) request.getServiceConfig();
final AttributesImpl attributes = new AttributesImpl();
attributes.addAttribute("", "version", "version", "", CUR_VERSION);
attributes.addAttribute("", "xmlns", "xmlns", "", WCS_URI);
attributes.addAttribute("", "xmlns:xlink", "xmlns:xlink", "",
"http://www.w3.org/1999/xlink");
attributes.addAttribute("", "xmlns:ogc", "xmlns:ogc", "", "http://www.opengis.net/ogc");
attributes.addAttribute("", "xmlns:gml", "xmlns:gml", "", "http://www.opengis.net/gml");
final String prefixDef = new StringBuffer("xmlns:").append(XSI_PREFIX).toString();
attributes.addAttribute("", prefixDef, prefixDef, "", XSI_URI);
final String locationAtt = new StringBuffer(XSI_PREFIX).append(":schemaLocation")
.toString();
GeoServerInfo gsInfo = wcs.getGeoServer().getGlobal();
final String locationDef = WCS_URI + " " +
buildURL(request.getBaseUrl(), appendPath(SCHEMAS, "schemas/wcs/1.0.0/wcsCapabilities.xsd"), null, URLType.RESOURCE);
attributes.addAttribute("", locationAtt, locationAtt, "", locationDef);
attributes.addAttribute("", "updateSequence", "updateSequence", "", gsInfo.getUpdateSequence() + "");
start("WCS_Capabilities", attributes);
handleService();
handleCapabilities();
end("WCS_Capabilities");
}
/**
* Handles the service section of the capabilities document.
*
* @param config
* The OGC service to transform.
*
* @throws SAXException
* For any errors.
*/
private void handleService() {
final WCSInfo wcs = (WCSInfo) request.getServiceConfig();
AttributesImpl attributes = new AttributesImpl();
//attributes.addAttribute("", "version", "version", "", CUR_VERSION);
start("Service", attributes);
if(wcs.getMetadataLink() != null)
handleMetadataLink(Collections.singletonList(wcs.getMetadataLink()));
element("description", wcs.getAbstract());
element("name", wcs.getName());
element("label", wcs.getTitle());
handleKeywords(wcs.getKeywords());
handleContact(wcs);
String fees = wcs.getFees();
if ((fees == null) || "".equals(fees)) {
fees = "NONE";
}
element("fees", fees);
String accessConstraints = wcs.getAccessConstraints();
if ((accessConstraints == null) || "".equals(accessConstraints)) {
accessConstraints = "NONE";
}
element("accessConstraints", accessConstraints);
end("Service");
}
/**
* DOCUMENT ME!
*
* @param serviceConfig
* DOCUMENT ME!
*
* @throws SAXException
* DOCUMENT ME!
*/
private void handleCapabilities() {
final WCSInfo wcs = (WCSInfo) request.getServiceConfig();
start("Capability");
handleRequest(wcs);
handleExceptions(wcs);
handleVendorSpecifics(wcs);
end("Capability");
handleContentMetadata(wcs);
}
/**
* Handles the request portion of the document, printing out the
* capabilities and where to bind to them.
*
* @param config
* The global wms.
*
* @throws SAXException
* For any problems.
*/
private void handleRequest(WCSInfo config) {
start("Request");
handleCapability(config, "GetCapabilities");
handleCapability(config, "DescribeCoverage");
handleCapability(config, "GetCoverage");
end("Request");
}
private void handleCapability(WCSInfo config, String capabilityName) {
AttributesImpl attributes = new AttributesImpl();
start(capabilityName);
start("DCPType");
start("HTTP");
String baseURL = buildURL(request.getBaseUrl(), "wcs", null, URLType.EXTERNAL);
// ensure ends in "?" or "&"
if(baseURL.indexOf('?') == -1) {
baseURL = ResponseUtils.appendQueryString(baseURL, "");
}
attributes.addAttribute("", "xlink:href", "xlink:href", "", baseURL);
start("Get");
start("OnlineResource", attributes);
end("OnlineResource");
end("Get");
end("HTTP");
end("DCPType");
attributes = new AttributesImpl();
attributes.addAttribute("", "xlink:href", "xlink:href", "", baseURL);
start("DCPType");
start("HTTP");
start("Post");
start("OnlineResource", attributes);
end("OnlineResource");
end("Post");
end("HTTP");
end("DCPType");
end(capabilityName);
}
/**
* DOCUMENT ME!
*
* @param kwords
* DOCUMENT ME!
*
* @throws SAXException
* DOCUMENT ME!
*/
private void handleKeywords(List kwords) {
start("keywords");
if (kwords != null) {
for (Iterator it = kwords.iterator(); it.hasNext();) {
element("keyword", it.next().toString());
}
}
end("keywords");
}
/**
* Handles contacts.
*
* @param config
* the service.
*/
private void handleContact(WCSInfo config) {
String tmp = "";
GeoServerInfo geoServer = config.getGeoServer().getGlobal();
ContactInfo contact = geoServer.getContact();
String cp = contact.getContactPerson();
String org = contact.getContactOrganization();
if (((cp != null) && (cp != ""))
|| ((org != null) && (org != ""))) {
start("responsibleParty");
tmp = cp;
if ((tmp != null) && (tmp != "")) {
element("individualName", tmp);
tmp = org;
if ((tmp != null) && (tmp != "")) {
element("organisationName", tmp);
}
} else {
tmp = org;
if ((tmp != null) && (tmp != "")) {
element("organisationName", tmp);
}
}
tmp = contact.getContactPosition();
if ((tmp != null) && (tmp != "")) {
element("positionName", tmp);
}
start("contactInfo");
start("phone");
tmp = contact.getContactVoice();
if ((tmp != null) && (tmp != "")) {
element("voice", tmp);
}
tmp = contact.getContactFacsimile();
if ((tmp != null) && (tmp != "")) {
element("facsimile", tmp);
}
end("phone");
start("address");
tmp = contact.getAddressType();
if ((tmp != null) && (tmp != "")) {
String addr = "";
addr = contact.getAddress();
if ((addr != null) && (addr != "")) {
element("deliveryPoint", tmp + " " + addr);
}
} else {
tmp = contact.getAddress();
if ((tmp != null) && (tmp != "")) {
element("deliveryPoint", tmp);
}
}
tmp = contact.getAddressCity();
if ((tmp != null) && (tmp != "")) {
element("city", tmp);
}
tmp = contact.getAddressState();
if ((tmp != null) && (tmp != "")) {
element("administrativeArea", tmp);
}
tmp = contact.getAddressPostalCode();
if ((tmp != null) && (tmp != "")) {
element("postalCode", tmp);
}
tmp = contact.getAddressCountry();
if ((tmp != null) && (tmp != "")) {
element("country", tmp);
}
tmp = contact.getContactEmail();
if ((tmp != null) && (tmp != "")) {
element("electronicMailAddress", tmp);
}
end("address");
tmp = geoServer.getOnlineResource();
if ((tmp != null) && (tmp != "")) {
AttributesImpl attributes = new AttributesImpl();
attributes.addAttribute("", "xlink:href", "xlink:href", "", tmp);
start("onlineResource", attributes);
end("onlineResource");
}
end("contactInfo");
end("responsibleParty");
}
}
/**
* Handles the printing of the exceptions information, prints the
* formats that GeoServer can return exceptions in.
*
* @param config
* The wms service global config.
*
* @throws SAXException
* For any problems.
*/
private void handleExceptions(WCSInfo config) {
start("Exception");
for(String format : EXCEPTION_FORMATS) {
element("Format", format);
}
end("Exception");
}
/**
* Handles the vendor specific capabilities. Right now there are none,
* so we do nothing.
*
* @param config
* The global config that may contain vendor specifics.
*
* @throws SAXException
* For any problems.
*/
private void handleVendorSpecifics(WCSInfo config) {
}
private void handleEnvelope(ReferencedEnvelope envelope) {
AttributesImpl attributes = new AttributesImpl();
attributes.addAttribute("", "srsName", "srsName", "", /*"urn:ogc:def:crs:OGC:1.3:CRS84"*/
"WGS84(DD)");
start("lonLatEnvelope", attributes);
element("gml:pos",
new StringBuffer(Double.toString(envelope.getLowerCorner().getOrdinate(0))).append(
" ").append(envelope.getLowerCorner().getOrdinate(1)).toString());
element("gml:pos",
new StringBuffer(Double.toString(envelope.getUpperCorner().getOrdinate(0))).append(
" ").append(envelope.getUpperCorner().getOrdinate(1)).toString());
end("lonLatEnvelope");
}
/**
* DOCUMENT ME!
*
* @param metadataLink
* DOCUMENT ME!
*
* @throws SAXException
* DOCUMENT ME!
*/
private void handleMetadataLink(List<MetadataLinkInfo> links) {
for (MetadataLinkInfo mdl : links) {
AttributesImpl attributes = new AttributesImpl();
if ((mdl.getAbout() != null) && (mdl.getAbout() != "")) {
attributes.addAttribute("", "about", "about", "", mdl.getAbout());
}
// if( mdl.getType() != null && mdl.getType() != "" ) {
// attributes.addAttribute("", "type", "type", "",
// mdl.getType());
// }
if ((mdl.getMetadataType() != null) && (mdl.getMetadataType() != "")) {
attributes.addAttribute("", "metadataType", "metadataType", "",
mdl.getMetadataType());
}
if (attributes.getLength() > 0) {
start("metadataLink", attributes);
// characters(mdl.getContent());
end("metadataLink");
}
}
}
private void handleContentMetadata(WCSInfo config) {
AttributesImpl attributes = new AttributesImpl();
//attributes.addAttribute("", "version", "version", "", CUR_VERSION);
start("ContentMetadata", attributes);
Catalog catalog = config.getGeoServer().getCatalog();
List<CoverageInfo> coverages = catalog.getCoverages();
// filter out disabled coverages
for (Iterator it = coverages.iterator(); it.hasNext();) {
CoverageInfo cv = (CoverageInfo) it.next();
if(!cv.enabled())
it.remove();
}
// filter out coverages that are not in the requested namespace
if(request.getNamespace() != null) {
String namespace = request.getNamespace();
for (Iterator it = coverages.iterator(); it.hasNext();) {
CoverageInfo cv = (CoverageInfo) it.next();
if(!namespace.equals(cv.getStore().getWorkspace().getName()))
it.remove();
}
}
Collections.sort(coverages, new CoverageInfoLabelComparator());
for (Iterator i = coverages.iterator(); i.hasNext();) {
handleCoverageOfferingBrief(config,
(CoverageInfo) i.next());
}
end("ContentMetadata");
}
private void handleCoverageOfferingBrief(WCSInfo config, CoverageInfo cv) {
if (cv.enabled()) {
start("CoverageOfferingBrief");
String tmp;
handleMetadataLink(cv.getMetadataLinks());
tmp = cv.getDescription();
if ((tmp != null) && (tmp != "")) {
element("description", tmp);
}
tmp = cv.getName();
if ((tmp != null) && (tmp != "")) {
element("name", tmp);
}
tmp = cv.getTitle();
if ((tmp != null) && (tmp != "")) {
element("label", tmp);
}
handleEnvelope(cv.getLatLonBoundingBox());
handleKeywords(cv.getKeywords());
end("CoverageOfferingBrief");
}
}
}
}