/** * 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. */ // // MyCapability.java // Wed May 21 14:00:09 CEST 2008 // Generated by the Apache Muse Code Generation Tool // package org.n52.ses.wsbr; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.xml.namespace.QName; import net.opengis.sensorML.x101.IoComponentPropertyType; import net.opengis.sensorML.x101.SensorMLDocument; import net.opengis.sensorML.x101.SystemType; import net.opengis.sensorML.x101.OutputsDocument.Outputs.OutputList; import net.opengis.sensorML.x101.SensorMLDocument.SensorML.Member; import org.apache.muse.core.Resource; import org.apache.muse.util.xml.XmlUtils; import org.apache.muse.ws.addressing.EndpointReference; import org.apache.muse.ws.addressing.soap.SoapFault; import org.apache.muse.ws.notification.NotificationProducer; import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability; import org.apache.muse.ws.resource.lifetime.ScheduledTermination; import org.apache.muse.ws.resource.lifetime.faults.ResourceNotDestroyedFault; 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.SensorMLConstants; import org.n52.ses.api.common.SesConstants; import org.n52.ses.api.common.WsbrConstants; import org.n52.ses.api.event.DataTypesMap; import org.n52.ses.api.ws.IDestroyRegistration; import org.n52.ses.api.ws.IPublisherEndpoint; import org.n52.ses.persistency.SESFilePersistence; import org.n52.ses.util.common.ConfigurationRegistry; import org.n52.ses.wsn.SESSubscriptionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * @author Jan Torben Heuer <jan.heuer@uni-muenster.de> * * The PRM capability */ public class PublisherEndpoint extends AbstractWsResourceCapability implements IPublisherEndpoint, IDestroyRegistration { private static final Logger logger = LoggerFactory.getLogger(PublisherEndpoint.class); private Element sensorML; private QName[] topics; private static String demand = "foo"; QName[] PROPERTIES = new QName[] { WsbrConstants.CREATION_QNAME, WsbrConstants.PUBLISHER_REFERENCE_QNAME, WsbrConstants.DEMAND, WsbrConstants.TOPIC }; // WsbrConstants.CREATION_QNAME, , , // , @Override public Element renewRegistration(Element terminationTime) throws Exception { Date date = XmlUtils.getDate(terminationTime); ScheduledTermination scheduledTermination = (ScheduledTermination) getResource().getCapability( "http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination"); scheduledTermination.setTerminationTime(date); Element root = XmlUtils.createElement(SesConstants.RENEW_REGISTRATION_RESPONSE); // TODO: use joda time (?) XmlUtils.setElementText(root, new SimpleDateFormat().format(date)); return root; } /* * (non-Javadoc) * * @see org.n52.ses.wsrp.IDestroyRegistration#destroyRegistration(org.w3c.dom.Element) * */ @Override public Element destroyRegistration(Element something) throws ResourceNotDestroyedFault { // see: SimpleImmediateTermination try { // // all we're doing is making the shutdown task public... // getResource().shutdown(); } catch (SoapFault fault) { throw new ResourceNotDestroyedFault(fault); } Element root = XmlUtils.createElement(SesConstants.DESTROY_REGISTRATION_RESPONSE); return root; } @Override public QName[] getPropertyNames() { return this.PROPERTIES; } @Override public void initialize() throws SoapFault { super.initialize(); /* * resubscribe */ if (ConfigurationRegistry.getInstance().persistencyEnabled()) { Element persReg = getResource().getEndpointReference().getParameter( SESFilePersistence.SES_REGPUB_PERS_NAME); /* if no PersistentSubscribe than its an actual new subscribe */ if (persReg != null) { this.sensorML = (Element) persReg.getElementsByTagNameNS( SensorMLConstants.NAMESPACE, SensorMLConstants.SENSORML.getLocalPart()).item(0); try { registerSensorML(this.sensorML); } catch (XMLHandlingException e) { logger.warn(e.getMessage(), e); } //TODO: topic, demand, termination time ConfigurationRegistry.getInstance().getGlobalRegisterPublisher().reRegisterPublisher( getResource().getEndpointReference(), null, false, null, this.sensorML, this); /* * call the registry. this informs the waiting Subscribe-Reload-Thread * of a new Publishers instance. If all instances have been reloaded * the Subscribe-Reload-Thread continues its work. */ ConfigurationRegistry.getInstance().addReregisteredPublisher(this); } } } /** * looks up the <em>first</em> {@link NotificationProducer} instance * * @return * @throws SoapFault */ @SuppressWarnings("unchecked") private Resource getNotificationProducer() throws SoapFault { Resource wsn = null; try { Iterator<EndpointReference> it = getResource().getResourceManager().getResourceEPRs(); EndpointReference ref; while(it.hasNext()) { ref = it.next(); if(ref.getAddress().toString().endsWith(SESSubscriptionManager.CONTEXT_PATH)) { wsn = getResource().getResourceManager().getResource(ref); break; } } if (wsn == null) { throw new SoapFault("Cannot find the NotificationProducer '" + SESSubscriptionManager.CONTEXT_PATH + "'!"); } } catch (RuntimeException e) { throw new SoapFault("Invalid NotificationProducer returned: " + (wsn != null ? wsn.getClass().getSimpleName() : ""), e); } return wsn; } @Override public void initializeCompleted() throws SoapFault { super.initializeCompleted(); } /** * * * @return Capability creation time */ public Date getCreationTime() { return new Date(); } /** * @return the notification producer then Publisher must use to send events */ public EndpointReference getPublisherReference() { return getWsResource().getEndpointReference(); } /** * @return the notification producer then Publisher must use to send events */ public EndpointReference getNotificationProducerReference() { EndpointReference publisherEpr = null; try { publisherEpr = getNotificationProducer().getEndpointReference(); } catch (Exception e) { logger.warn("Cannot find the NotificationProducer", e); } return publisherEpr; } /** * Capability: demand * * @return if the publisher is in on demand mode */ public Object getDemand() { // TODO: implement return demand; } /** * Capability: SensorML * * @return the SensorML description of the publisher */ public Element getSensorML() { return this.sensorML; } /** * Sets the sensorML document. Warning, there is no validation! * * @param sensorML the SensorML document */ public void setSensorML(Element sensorML) { this.sensorML = sensorML; } /** * Registers SenorML Data. including registering phenomenons at * the DataTypesMap (needed for subscriptions). * * @param sml the SensorML document * @throws InvalidXMLContentException if an error occurred on registering */ public void registerSensorML(Element sml) throws XMLHandlingException { this.sensorML = sml; XmlObject smlDoc = XMLBeansParser.parse(sml, true); if (smlDoc != null) { logger.info("Registering SensorML for new Publisher..."); Member[] members = ((SensorMLDocument) smlDoc).getSensorML().getMemberArray(); List<XmlObject> systems = new ArrayList<XmlObject>(); /* * select all System elements. */ for (Member member : members) { systems.addAll(Arrays.asList(member.selectChildren(new QName("http://www.opengis.net/sensorML/1.0.1", "System")))); } for (XmlObject sys : systems) { SystemType sysDoc = (SystemType) sys; //TODO DataRecord -> auslagern OutputList outs = sysDoc.getOutputs().getOutputList(); /* * check outputs for possible data types */ for (IoComponentPropertyType out : outs.getOutputArray()) { //TODO: out.isSetAbstractDataRecord() if (out.isSetQuantity()) { DataTypesMap.getInstance().registerNewDataType(out.getName(), Double.class); } } } } } /** * The unique sensor-id from the sensorML * * @return the id as string * @throws SoapFault if an error occurred on retrieving the ID */ public String getSensorId() throws SoapFault { /* traverse xml tree */ try { if (this.sensorML == null) { logger.info("SensorML is null"); throw new SoapFault("SensorML document hasn't been supplied for this sensor!"); } // Element system = XmlUtils.findFirstInSubTree(sensorML, // SensorMLConstants.SYSTEM); Element identification = XmlUtils.findFirstInSubTree(this.sensorML, SensorMLConstants.IDENTIFICATION); Element term = XmlUtils.findFirstInSubTree(identification, SensorMLConstants.TERM); if (SensorMLConstants.SENSOR_ID_UNIQUEIDS.contains(term.getAttribute("definition"))) { Element value = XmlUtils.getElement(term, SensorMLConstants.VALUE); Node text = value.getFirstChild(); if(text instanceof Text) { return ((Text) text).getData(); } } } catch (DOMException e) { logger.warn(e.getMessage()); } catch (NullPointerException e) { logger.warn(e.getMessage()); } catch (Exception e) { logger.warn("Unrecoverable error: ", e); } return "invalid-id"; } /** * Capability: Topic * * @return the topics of this publisher */ public QName[] getTopic() { return this.topics; } /** * Sets this resource's topic. Used by the {@link RegisterPublisher} class. * * @param topic the topic */ public void setTopic(QName[] topic) { this.topics = topic; } @Override public void reRegister() { } }