/**
* 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 15:24:25 CEST 2008
// Generated by the Apache Muse Code Generation Tool
//
package org.n52.ses.wsbr;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.namespace.QName;
import org.apache.muse.core.Resource;
import org.apache.muse.core.ResourceManager;
import org.apache.muse.core.ResourceManagerListener;
import org.apache.muse.core.routing.MessageHandler;
import org.apache.muse.util.ReflectUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.soap.SoapFault;
import org.apache.muse.ws.resource.WsResource;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
import org.apache.muse.ws.resource.lifetime.ScheduledTermination;
import org.n52.oxf.xmlbeans.parser.XMLHandlingException;
import org.n52.ses.api.common.GlobalConstants;
import org.n52.ses.api.common.SensorMLConstants;
import org.n52.ses.api.ws.IPublisherEndpoint;
import org.n52.ses.api.ws.IRegisterPublisher;
import org.n52.ses.common.SensorML;
import org.n52.ses.wsbr.soaphandler.PublisherHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
/**
* @author Jan Torben Heuer <jan.heuer@uni-muenster.de>
*
* Handles the creation of new {@link PublisherEndpoint} resources.
*/
public class RegisterPublisher extends AbstractWsResourceCapability
implements IRegisterPublisher, ResourceManagerListener {
private static Logger logger = LoggerFactory.getLogger(RegisterPublisher.class);
private ConcurrentHashMap<EndpointReference, IPublisherEndpoint> map = new ConcurrentHashMap<EndpointReference, IPublisherEndpoint>();
/**
* constant for the resource type
*/
public final static String RESOURCE_TYPE = GlobalConstants.PUBLISHER_REGISTRATION_MANAGER_CONTEXT_PATH;
private String registerPath;
QName[] PROPERTIES = new QName[] {};
private String publisherRegistrationManagerEndpoint;
private ResourceManager manager;
@Override
public void initialize() throws SoapFault {
super.initialize();
/* get the Manager instance */
WsResource resource = getWsResource();
this.manager = resource.getResourceManager();
/*
* select the register method that is called on "register" by the
* Publisher message handler
*/
setMessageHandler(createrRegisterPublisherHandler());
//
// make sure we're exposing the advertise endpoint so that
// clients can manage subscriptions/consumers
//
this.registerPath = this.manager.getResourceContextPath(RegisterPublisher.class);
if (this.registerPath == null) {
throw new RuntimeException("NoRegisterPublisher");
}
/* retrieve the PublicationEndpoint context path */
this.publisherRegistrationManagerEndpoint = this.manager.getResourceContextPath(PublisherEndpoint.class);
if (this.publisherRegistrationManagerEndpoint == null) {
throw new RuntimeException("No PublicationEndpoint deployed");
}
/* add ourselves as listener for shutdown of PRM instances */
this.manager.addListener(this);
// SESNotificationProducer producer = (SESNotificationProducer)getResource().getCapability(WsnConstants.PRODUCER_URI);
}
@Override
public void initializeCompleted() throws SoapFault {
super.initializeCompleted();
}
/**
* Sets the Handler for incoming SOAP requests
*
* @return a new {@link PublisherHandler} instance
*/
private MessageHandler createrRegisterPublisherHandler() {
MessageHandler handler = new PublisherHandler();
Method method = ReflectUtils.getFirstMethod(getClass(), "registerPublisher");
handler.setMethod(method);
return handler;
}
/*
* (non-Javadoc)
*
* @see org.n52.ses.wsbr.IRegisterPublisher#registerPublisher(org.apache.muse.ws.addressing.EndpointReference,
* org.w3c.dom.Element[], boolean, java.util.Date)
*
* This method is called for incomming SOAP requests. Messages are extracted
* by the PublisherHander. The response is rendered by the PublisherHandler,
* too.
*/
@Override
public Resource registerPublisher(EndpointReference publisherReference, QName[] topic,
boolean demand, Date initialTerminationTime, org.w3c.dom.Element domElem) throws SoapFault {
Resource publisherResource = null;
/* create new resource (@see SimpleNotificationProducer) */
publisherResource = this.manager.createResource(this.publisherRegistrationManagerEndpoint);
EndpointReference epr = publisherResource.getEndpointReference();
PublisherEndpoint publisherCapability =
(PublisherEndpoint) publisherResource.getCapability(IPublisherEndpoint.NAMESPACE_URI);
/* set topics */
publisherCapability.setTopic(topic);
/* check for AdvertiseSOS or SensorML */
if (domElem == null) {
throw new NullPointerException("There" +
" was no SensorML element found in the request.");
}
try {
publisherCapability.registerSensorML(domElem);
SensorML sml = (SensorML) publisherResource.getCapability(SensorMLConstants.NAMESPACE);
sml.setSensorML(domElem);
} catch (XMLHandlingException e) {
throw new SoapFault("An error occured while processing " +
"SensorML: "+ e.getMessage());
}
Collection<IPublisherEndpoint> existingEndpoints = getPublisherEndpoints();
for (IPublisherEndpoint pe : existingEndpoints) {
if (pe.getSensorId().equals(publisherCapability.getSensorId())) {
throw new IllegalStateException("The SensorID '" + pe.getSensorId()
+"' is already registered within this service instance.");
}
}
/*
* set termination time
* @see SimpleScheduledTermination
*/
ScheduledTermination scheduledTermination = (ScheduledTermination) publisherResource
.getCapability("http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination");
scheduledTermination.setTerminationTime(generateTerminationTime(initialTerminationTime));
synchronized (this) {
this.map.put(epr, publisherCapability);
}
/* don't change the EPR after the following step */
publisherResource.initialize();
this.manager.addResource(epr, publisherResource);
return publisherResource;
}
/**
* calculates a valid termination time.
*
* @param initialTerminationTime the termination time. can be null
* @return the generated termination time.
*/
protected Date generateTerminationTime(Date initialTerminationTime) {
Date now = new Date();
if (initialTerminationTime != null && initialTerminationTime.after(now)) {
return initialTerminationTime;
}
/* complicated java date handling ... */
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, 1);
return cal.getTime();
}
/**
*
* @see org.apache.muse.core.ResourceManagerListener#resourceAdded(org.apache.muse.ws.addressing.EndpointReference,
* org.apache.muse.core.Resource)
*
* @throws SoapFault if an error occurred on adding
*/
@Override
public void resourceAdded(EndpointReference epr, Resource resource) throws SoapFault {
/* no action needed, yet */
}
/**
*
* @see org.apache.muse.core.ResourceManagerListener#resourceRemoved(org.apache.muse.ws.addressing.EndpointReference)
*
* @throws SoapFault if an error occurred on removing
*/
@Override
public void resourceRemoved(EndpointReference epr) throws SoapFault {
synchronized (this) {
if (epr != null) {
Object isInMap = this.map.remove(epr);
if(isInMap instanceof PublisherEndpoint) {
logger.info("The PublisherEndpoint " + isInMap.toString() + " has been removed.");
}
} else {
logger.debug("Attemp to remove a null value from PublisherEnpoint map");
}
}
}
/**
* @return all {@link PublisherEndpoint} instances that have been created by
* this instance
*/
public Collection<IPublisherEndpoint> getPublisherEndpoints() {
synchronized (this) {
return this.map.values();
}
}
/*
* (non-Javadoc)
*
* @see org.apache.muse.ws.resource.impl.AbstractWsResourceCapability#getPropertyNames()
*/
@Override
public QName[] getPropertyNames() {
return this.PROPERTIES;
}
/**
* Used as part of the persistency mechanism. Re-registers a publishers endpoint.
*
* TODO: topic, demand and termination time!
*
* @param publisherReference the EPF
* @param topic topic on which the publisher publishes
* @param demand true if the publisher is in "on demand" mode
* @param initialTerminationTime termination time for the publisher
* @param sensorML sensorML doc
* @param publisherCapability the {@link PublisherEndpoint} instance
*/
public void reRegisterPublisher(EndpointReference publisherReference,
QName[] topic, boolean demand, Date initialTerminationTime,
Element sensorML, IPublisherEndpoint publisherCapability) {
synchronized (this) {
this.map.put(publisherCapability.getPublisherReference(), publisherCapability);
}
}
}