/** * Copyright (C) 2012 52°North Initiative for Geospatial Open Source Software GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.n52.sos.encoder; import java.io.IOException; import java.util.Collection; import java.util.List; import org.n52.sos.Constants; import org.n52.sos.dataTypes.ContactDescription; import org.n52.sos.dataTypes.ObservationOffering; import org.n52.sos.dataTypes.ServiceDescription; import org.n52.sos.handler.capabilities.OperationsMetadataProvider; import org.n52.util.CommonUtilities; /** * @author <a href="mailto:broering@52north.org">Arne Broering</a> */ public class OGCCapabilitiesEncoder extends AbstractEncoder { /* * definition of anchor variables of Capabilities template file: */ private static final String SERVICE_TITLE = "@service-title@"; private static final String SERVICE_DESCRIPTION = "@service-description@"; private static final String SERVICE_KEYWORDS = "@service-keywords@"; private static final String PROVIDER_NAME = "@provider-name@"; private static final String PROVIDER_SITE = "@provider-site@"; private static final String PROVIDER_PHONE = "@provider-phone@"; private static final String PROVIDER_FAX = "@provider-fax@"; private static final String PROVIDER_DELIVERY_POINT = "@provider-delivery-point@"; private static final String PROVIDER_CITY = "@provider-city@"; private static final String PROVIDER_POSTAL_CODE = "@provider-postal-code@"; private static final String PROVIDER_COUNTRY = "@provider-country@"; private static final String PROVIDER_EMAIL = "@provider-email@"; private static final String CONTENTS_OFFERINGS = "@contents-offerings@"; private static final String CONTENTS_RESPONSE_FORMATS = "@contents-response-formats@"; private static final String OFFERING_IDENTIFIER = "@offering-identifier@"; private static final String OFFERING_PROCEDURE = "@offering-procedure@"; private static final String OFFERING_OBSERVABLE_PROPERTIES = "@offering-observable-properties@"; private static final String OFFERING_OBSERVED_AREA = "@offering-observed-area@"; private static final String OFFERING_BEGIN_POSITION = "@offering-begin-position@"; private static final String OFFERING_END_POSITION = "@offering-end-position@"; private static final String OPERATIONS_METADATA = "@operations-metadata@"; private static String template; private static String offeringTemplate; public OGCCapabilitiesEncoder() throws IOException { super(); template = readText(OGCCapabilitiesEncoder.class.getResourceAsStream("template_capabilities.xml")); offeringTemplate = readText(OGCCapabilitiesEncoder.class.getResourceAsStream("template_capabilities_offering.xml")); } public String encodeCapabilities(ServiceDescription sd, Collection<ObservationOffering> obsOfferings, List<OperationsMetadataProvider> operations) throws IOException { // replace variables in Capabilities document template: StringBuilder templateCapabilites = new StringBuilder(); templateCapabilites.append(template); replace(templateCapabilites, SERVICE_TITLE, sd.getTitle()); replace(templateCapabilites, SERVICE_DESCRIPTION, sd.getDescription()); String[] keywordArray = sd.getKeywordArray(); String keywordElement = ""; for (int i = 0; i < keywordArray.length; i++) { keywordElement += "<ows:Keyword>" + keywordArray[i].trim() + "</ows:Keyword>"; } replace(templateCapabilites, SERVICE_KEYWORDS, keywordElement); replace(templateCapabilites, PROVIDER_NAME, sd.getProviderName()); replace(templateCapabilites, PROVIDER_SITE, sd.getProviderSite()); ContactDescription[] contactsArray = sd.getServiceContacts(); replace(templateCapabilites, PROVIDER_PHONE, contactsArray[0].getPhone()); replace(templateCapabilites, PROVIDER_FAX, contactsArray[0].getFacsimile()); replace(templateCapabilites, PROVIDER_DELIVERY_POINT, contactsArray[0].getDeliveryPoint()); replace(templateCapabilites, PROVIDER_CITY, contactsArray[0].getCity()); replace(templateCapabilites, PROVIDER_POSTAL_CODE, contactsArray[0].getPostalCode()); replace(templateCapabilites, PROVIDER_COUNTRY, contactsArray[0].getCountry()); replace(templateCapabilites, PROVIDER_EMAIL, contactsArray[0].getElectronicMailAddress()); // replace variables in ObservationOffering template and add to Capabilities document: StringBuilder allOfferings = new StringBuilder(); StringBuilder templateOffering = new StringBuilder(); templateOffering.append(offeringTemplate); for (ObservationOffering obsOff : obsOfferings){ StringBuilder offeringString = new StringBuilder(); offeringString.append(templateOffering); replace(offeringString, OFFERING_IDENTIFIER, obsOff.getName()); replace(offeringString, OFFERING_PROCEDURE, obsOff.getProcedureIdentifier()); // TODO replace with URL to procedure; e.g. DescribeSensor request to this procedure String[] obsPropArray = obsOff.getObservedProperties(); String obsPropElements = ""; for (int i = 0; i < obsPropArray.length; i++) { obsPropElements += "<swes:observableProperty>" + obsPropArray[i] + "</swes:observableProperty>"; } replace(offeringString, OFFERING_OBSERVABLE_PROPERTIES, obsPropElements); // e.g.: <gml:lowerCorner>50.7167 7.76667</gml:lowerCorner> if (!obsOff.getObservedArea().isEmpty()) { double lowerX = obsOff.getObservedArea().getLowerLeft().getX(); double lowerY = obsOff.getObservedArea().getLowerLeft().getY(); double upperX = obsOff.getObservedArea().getUpperRight().getX(); double upperY = obsOff.getObservedArea().getUpperRight().getY(); String observedArea = "<sos:observedArea>" + "<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG::3857\">" + "<gml:lowerCorner>" + lowerY + " " + lowerX + "</gml:lowerCorner>" + "<gml:upperCorner>" + upperY + " " + upperX + "</gml:upperCorner>" + "</gml:Envelope>" + "</sos:observedArea>"; replace(offeringString, OFFERING_OBSERVED_AREA, observedArea); } else { replace(offeringString, OFFERING_OBSERVED_AREA, ""); } // e.g.: <gml:beginPosition>2009-01-11T16:22:25.00Z</gml:beginPosition> if (obsOff.getTimeExtent() != null) { String beginPos = obsOff.getTimeExtent().getStart().toISO8601Format(); replace(offeringString, OFFERING_BEGIN_POSITION, beginPos); String endPos = obsOff.getTimeExtent().getEnd().toISO8601Format(); replace(offeringString, OFFERING_END_POSITION, endPos); } // add offering to the allOfferings String allOfferings.append(offeringString).append("\n"); } // add the offerings to the Capabilities document: replace(templateCapabilites, CONTENTS_OFFERINGS, allOfferings.toString()); replace(templateCapabilites, OPERATIONS_METADATA, createOperationsMetadataMarkup(operations)); // add the supported response formats: String[] responseFormats = new String[] { Constants.RESPONSE_FORMAT_OM, Constants.RESPONSE_FORMAT_AQ }; replace(templateCapabilites, CONTENTS_RESPONSE_FORMATS, createResponseFormats(responseFormats)); return templateCapabilites.toString(); } // public static StringBuilder replaceFirst(StringBuilder builder, // String replaceWhat, // String replaceWith) // { // return builder.replace(builder.indexOf(replaceWhat), builder.indexOf(replaceWhat) + replaceWhat.length(), replaceWith); // } private String createOperationsMetadataMarkup( List<OperationsMetadataProvider> operations) { if (operations == null || operations.size() == 0) return ""; StringBuilder sb = new StringBuilder(); String sep = CommonUtilities.NEW_LINE_CHAR; sb.append("<ows:OperationsMetadata>"); sb.append(sep); for (OperationsMetadataProvider omp : operations) { sb.append(omp.createMarkup()); sb.append(sep); } sb.append("</ows:OperationsMetadata>"); sb.append(sep); return sb.toString(); } private String createResponseFormats (String[] responseFormats) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < responseFormats.length; i++) { sb.append("<sos:responseFormat>" + responseFormats[i] + "</sos:responseFormat>"); } return sb.toString(); } }