/**
* Copyright (C) 2008 - 2014 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* icense version 2 and the aforementioned licenses.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/
package org.n52.ses.common;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import javax.xml.namespace.QName;
import net.opengis.ses.x00.CapabilitiesDocument;
import net.opengis.ses.x00.DescribeSensorDocument;
import net.opengis.ses.x00.ContentsDocument.Contents;
import net.opengis.ses.x00.ContentsDocument.Contents.RegisteredSensors;
import net.opengis.esSf.x00.DescribeStoredFilterDocument;
import net.opengis.esSf.x00.DescribeStoredFilterResponseDocument;
import net.opengis.esSf.x00.DescribeStoredFilterResponseDocument.DescribeStoredFilterResponse;
import net.opengis.esSf.x00.ListStoredFiltersResponseDocument;
import net.opengis.esSf.x00.ListStoredFiltersResponseDocument.ListStoredFiltersResponse;
import net.opengis.esSf.x00.StoredFilterDescriptionType;
import org.apache.muse.ws.addressing.soap.SoapFault;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
import org.apache.xmlbeans.XmlObject;
import org.n52.oxf.xmlbeans.parser.XMLBeansParser;
import org.n52.oxf.xmlbeans.parser.XMLHandlingException;
import org.n52.ses.api.common.WsbrConstants;
import org.n52.ses.api.ws.IPublisherEndpoint;
import org.n52.ses.storedfilters.StoredFilterInstance;
import org.n52.ses.util.common.ConfigurationRegistry;
import org.n52.ses.wsbr.RegisterPublisher;
import org.n52.ses.wsn.SESSubscriptionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* @author Jan Torben Heuer <jan.heuer@uni-muenster.de>
* @author Matthes Rieke <m.rieke@uni-muenster.de
*
*
* This capability informs about what this service provides. Available sensors
* are listed and can be further described.
*/
public class Capabilites extends AbstractWsResourceCapability implements ICapabilites {
private static final Logger logger = LoggerFactory.getLogger(Capabilites.class);
public static final QName CAPABILITIES_QNAME = new QName("http://www.opengis.net/ses/0.0", "Capabilities");
private static final String CAPABILITIES_FILE = "/sesconfig/capabilites_base.xml";
private static final String CAPABILITIES_FILE_FILTER = "/sesconfig/capabilites_filter.xml-fragment";
private static final String CAPABILITIES_FILE_EML = "/sesconfig/capabilites_eml.xml-fragment";
private RegisterPublisher registerpublisher;
private CapabilitiesDocument capabilities;
@Override
public void initialize() throws SoapFault {
super.initialize();
/*
* this is needed because we do not want the default (ReflectionMessageHandler) to take care
* of the XML stuff...
*/
setMessageHandler(new SimpleHandler("http://www.opengis.net/ses/GetCapabilitiesRequest",null,this,"getCapabilities"));
setMessageHandler(new SimpleHandler("http://www.opengis.net/ses/DescribeSensorRequest",null,this,"describeSensor"));
setMessageHandler(new SimpleHandler("http://www.opengis.net/es-sf/DescribeStoredFilterRequest",null,this,"describeStoredFilter"));
setMessageHandler(new SimpleHandler("http://www.opengis.net/es-sf/ListStoredFiltersRequest",null,this,"listStoredFilters"));
this.registerpublisher = getRegisterPublisher();
ConfigurationRegistry.getInstance().setGlobalRegisterPublisher(this.registerpublisher);
this.capabilities = getCapabilityTemplate();
}
/**
* Checks if the capabilities template exists
*
* @return the template or a new instance of CapabilitesDocument
* @throws
*/
private CapabilitiesDocument getCapabilityTemplate() throws SoapFault {
CapabilitiesDocument capabilites;
String capString = null;
try {
capString = readCapabilityFiles();
} catch (IOException e1) {
logger.warn(e1.getMessage(), e1);
}
/* check if a template exists */
if (capString == null) {
capabilites = CapabilitiesDocument.Factory.newInstance();
capabilites.addNewCapabilities();
capabilites.getCapabilities().setVersion("0.0.0");
} else {
try {
capabilites = (CapabilitiesDocument) XMLBeansParser.parse(capString);
} catch (XMLHandlingException e) {
throw new SoapFault("The" +
" capabilites template is invalid! The error is:" + e.getMessage());
} catch (ClassCastException e) {
throw new SoapFault("The capabilites" +
" template is invalid! It doesn't seem to be a valid" +
" Capabilites document.");
}
}
return capabilites;
}
private String readCapabilityFiles() throws IOException {
/*
* read base file
*/
InputStream stream = getClass().getResourceAsStream(CAPABILITIES_FILE);
String lineSep = System.getProperty("line.separator");
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String nextLine = "";
StringBuffer sb = new StringBuffer();
while ((nextLine = br.readLine()) != null) {
sb.append(nextLine);
sb.append(lineSep);
}
String defaulturi = getEnvironment().getDefaultURI().substring(0,
getEnvironment().getDefaultURI().lastIndexOf("/services"));
String subMgrUrl = defaulturi + "/services/" + SESSubscriptionManager.CONTEXT_PATH;
String prmUrl = defaulturi + "/services/" + RegisterPublisher.RESOURCE_TYPE;
String baseString = sb.toString().replace("${broker}", getEnvironment().getDeploymentEPR().getAddress().toString());
baseString = baseString.replace("${subMgr}", subMgrUrl);
baseString = baseString.replace("${pubRegMgr}", prmUrl);
/*
* read filter file
*/
stream = getClass().getResourceAsStream(CAPABILITIES_FILE_FILTER);
lineSep = System.getProperty("line.separator");
br = new BufferedReader(new InputStreamReader(stream));
nextLine = "";
sb = new StringBuffer();
while ((nextLine = br.readLine()) != null) {
sb.append(nextLine);
sb.append(lineSep);
}
baseString = baseString.replace("<!-- Filter_Capabilities here -->", sb.toString());
/*
* read eml file
*/
stream = getClass().getResourceAsStream(CAPABILITIES_FILE_EML);
lineSep = System.getProperty("line.separator");
br = new BufferedReader(new InputStreamReader(stream));
nextLine = "";
sb = new StringBuffer();
while ((nextLine = br.readLine()) != null) {
sb.append(nextLine);
sb.append(lineSep);
}
String emlStr = sb.toString();
if (ConfigurationRegistry.getInstance().getPropertyForKey(ConfigurationRegistry.EML_CONTROLLER).equals(
ConfigurationRegistry.EML_002_IMPL)) {
emlStr = emlStr.replace("http://www.opengis.net/eml/0.0.1", "http://www.opengis.net/eml/0.0.2");
emlStr = emlStr.replace("OGC-EML-0_0_1", "OGC-EML-0_0_2");
}
baseString = baseString.replace("<!-- EML_Capabilities here -->", emlStr);
return baseString;
}
/**
* looks up the <em>first</em> {@link RegisterPublisher} instance
*
* @return its reference
* @throws SoapFault the {@link RegisterPublisher} endpoint instance
*/
protected RegisterPublisher getRegisterPublisher() throws SoapFault {
try {
final RegisterPublisher wsn = (RegisterPublisher) getResource().getCapability(WsbrConstants.NAMESPACE_URI);
if (wsn == null) {
String all = getResource().getCapabilityURIs().toString();
throw new SoapFault("Cannot find the" +
" RegisterPublisher instance. " +
"Known instances are: " + all);
}
return wsn;
} catch (ClassCastException e) {
throw new SoapFault("Internal Server error." +
" Expected " + WsbrConstants.NAMESPACE_URI + " to be handled by "
+ RegisterPublisher.class.getCanonicalName());
}
}
/**
* Reflections-method for describing a sensor.
* @param o xml-text possible.
* @return DescribeSensor response
* @throws Exception if Sensor was not found inside the service.
*/
public Element describeSensorReflect(Object[] o) throws Exception {
return describeSensor((Element) o[0]);
}
/*
* (non-Javadoc)
*
* @see org.n52.ses.common.ICapabilites#describeSensor(org.w3c.dom.Element)
*/
@Override
public Element describeSensor(Element sensor_element) throws Exception {
XmlObject xmlobject = XMLBeansParser.parse(sensor_element, true);
String sensorID;
if(xmlobject instanceof DescribeSensorDocument) {
sensorID=((DescribeSensorDocument)xmlobject).getDescribeSensor().getSensorID();
} else {
throw new Exception(
sensor_element.toString() + " is not a valid sensor identifier");
}
Collection<IPublisherEndpoint> endpoints = this.registerpublisher.getPublisherEndpoints();
/*
* iterate over all endpoints. Could be made faster with either caching
* or hashes.
*/
for (IPublisherEndpoint publisherEndpoint : endpoints) {
if (publisherEndpoint.getSensorId().equals(sensorID)) {
return publisherEndpoint.getSensorML();
}
}
throw new Exception("Sensor " +
sensorID + " does not exist. Please check the capabilites or report an error");
}
/* (non-Javadoc)
* @see org.n52.ses.common.ICapabilites#describeStoredFilter(org.w3c.dom.Element)
*/
public Element describeStoredFilter(Element describeStoredFilter)
throws Exception {
XmlObject xmlobject = XMLBeansParser.parse(describeStoredFilter, true);
String id;
if (xmlobject instanceof DescribeStoredFilterDocument) {
id = ((DescribeStoredFilterDocument) xmlobject).getDescribeStoredFilter().getStoredFilterID();
} else {
throw new Exception(
describeStoredFilter.toString() + " is not a valid stored filter identifier");
}
StoredFilterInstance instance = StoredFilterInstance.getByID(id);
DescribeStoredFilterResponseDocument resultDoc = DescribeStoredFilterResponseDocument.Factory.newInstance();
DescribeStoredFilterResponse resp = resultDoc.addNewDescribeStoredFilterResponse();
resp.addNewStoredFilterDescription();
resp.set(StoredFilterDescriptionType.Factory.parse(instance.getStoredFilterDescription()));
return (Element) resp.getDomNode();
}
public Element listStoredFilters(Element listStoredFilters) throws Exception{
ListStoredFiltersResponseDocument resp = ListStoredFiltersResponseDocument.Factory.newInstance();
ListStoredFiltersResponse sfr = resp.addNewListStoredFiltersResponse();
for (StoredFilterInstance inst : StoredFilterInstance.getAvailableInstances()) {
sfr.addStoredFilterID(inst.getId());
}
return (Element) sfr.getDomNode();
}
/*
* (non-Javadoc)
*
* @see org.n52.ses.common.ICapabilites#getCapabilities()
*/
@Override
public Element getCapabilities(Element xml) throws Exception {
logger.info("creating capabilites");
CapabilitiesDocument temp = (CapabilitiesDocument) this.capabilities.copy();
/* add content section if missing */
Contents content = temp.getCapabilities().getContents();
if (content == null) {
content = temp.getCapabilities().addNewContents();
}
/* read available sensors */
Collection<IPublisherEndpoint> endpoints = this.registerpublisher.getPublisherEndpoints();
if (endpoints.size() > 0) {
RegisteredSensors sensors = content.addNewRegisteredSensors();
for (IPublisherEndpoint publisherEndpoint : endpoints) {
String sensor = publisherEndpoint.getSensorId();
sensors.addSensorID(sensor);
}
}
try {
XMLBeansParser.strictValidate(temp);
logger.info("capabilites are valid!");
} catch (XMLHandlingException e) {
throw new Exception("Internal" +
" server error: capabilities are not valid: " + e.getMessage());
}
Node node = temp.getCapabilities().getDomNode();
if(node instanceof Element) {
logger.info("returning capabilites");
return (Element) temp.getCapabilities().getDomNode();
}
throw new Exception("Expected "
+ node.toString() + " to be an org.w3c.dom.Element, but it is "
+ node.getClass().getCanonicalName());
}
}