/*=============================================================================*
* Copyright 2006 The Apache Software Foundation
*
* 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.apache.muse.ws.notification.impl;
import java.util.Date;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.muse.core.Environment;
import org.apache.muse.util.LoggingUtils;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.notification.Filter;
import org.apache.muse.ws.notification.NotificationMessage;
import org.apache.muse.ws.notification.Policy;
import org.apache.muse.ws.notification.SubscriptionManager;
import org.apache.muse.ws.notification.WsnConstants;
import org.apache.muse.ws.notification.remote.NotificationConsumerClient;
import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
import org.apache.muse.ws.addressing.soap.SoapFault;
/**
*
* SimpleSubscriptionManager is Muse's default implementation of the
* WS-Notification SubscriptionManager port type. It uses the
* {@linkplain NotificationConsumerClient NotificationConsumerClient class}
* to send messages to its subscribers. It also provides an initialization
* flag, <em>trace-notifications</em> that allows users to turn on tracing
* for the outgoing notification messages (the default is 'false').
* <br><br>
* This implementation does not support subscription policies.
*
* @author Dan Jemiolo (danj)
*
*/
public class SimpleSubscriptionManager
extends AbstractWsResourceCapability implements SubscriptionManager
{
//
// Used to lookup all exception messages
//
private static Messages _MESSAGES = MessagesFactory.get(SimpleSubscriptionManager.class);
//
// init. param used to turn on SOAP tracing for notifications
//
private static final String _TRACE_PARAM = "trace-notifications";
//
// The client that is used to publish messages to the consumer
//
private NotificationConsumerClient _client = null;
//
// EPR of the resource receiving our messages
//
private EndpointReference _consumer = null;
//
// When was the subscription created? Right now!
//
private Date _creationTime = new Date();
//
// The filter will approve of messages that are published
//
private Filter _filter = null;
private boolean _isPaused = false;
private boolean _isUsingTrace = false;
//
// EPR of the resource using this capability
//
private EndpointReference _producer = null;
/**
*
* Users can override this method to provide a different implementation of
* the WS-N client class without changing the implementation of subscription
* management.
*
* @return An instance of NotificationConsumerClient.
*
*/
protected NotificationConsumerClient createConsumerClient()
{
EndpointReference consumer = getConsumerReference();
EndpointReference producer = getProducerReference();
Environment env = getEnvironment();
NotificationConsumerClient client = new NotificationConsumerClient(consumer, producer, env);
client.setTrace(isUsingTrace());
return client;
}
protected synchronized NotificationConsumerClient getConsumerClient()
{
if (_client == null)
_client = createConsumerClient();
return _client;
}
public EndpointReference getConsumerReference()
{
return _consumer;
}
public Date getCreationTime()
{
return _creationTime;
}
public Filter getFilter()
{
return _filter;
}
public EndpointReference getProducerReference()
{
return _producer;
}
public QName[] getPropertyNames()
{
return PROPERTIES;
}
/**
*
* This implementation always returns null.
*
*/
public Policy getSubscriptionPolicy()
{
return null;
}
public void initialize()
throws SoapFault
{
super.initialize();
//
// turn on tracing for notifications, if desired
//
String traceString = getInitializationParameter(_TRACE_PARAM);
if (traceString != null)
_isUsingTrace = Boolean.valueOf(traceString).booleanValue();
}
public synchronized boolean isPaused()
{
return _isPaused;
}
protected boolean isUsingTrace()
{
return _isUsingTrace;
}
public synchronized void pauseSubscription()
{
_isPaused = true;
}
public void publish(NotificationMessage message)
{
if (isPaused() || !getFilter().accepts(message))
return;
//
// set subscription reference for this publication
//
message.setSubscriptionReference(getResource().getEndpointReference());
try
{
NotificationConsumerClient client = getConsumerClient();
client.notify(new NotificationMessage[]{ message });
}
catch (SoapFault error)
{
//
// log the error and include a follow up message to
// provide some context
//
LoggingUtils.logError(getLog(), error);
Object[] filler = { error.getMessage() };
getLog().info(_MESSAGES.get("LastPublishFailed", filler));
}
}
public synchronized void resumeSubscription()
{
_isPaused = false;
}
public void setConsumerReference(EndpointReference consumer)
{
if (consumer == null)
throw new NullPointerException(_MESSAGES.get("NullConsumerEPR"));
_consumer = consumer;
}
public void setFilter(Filter filter)
{
_filter = filter;
}
public void setProducerReference(EndpointReference producer)
{
if (producer == null)
throw new NullPointerException(_MESSAGES.get("NullProducerEPR"));
_producer = producer;
}
/**
*
* Logs a warning message that this feature is not supported.
*
*/
public void setSubscriptionPolicy(Policy policy)
{
Object[] filler = { policy };
getLog().warning(_MESSAGES.get("PolicyNotSupported", filler));
}
public Element toXML()
{
return toXML(XmlUtils.EMPTY_DOC);
}
public Element toXML(Document doc)
{
Element root = XmlUtils.createElement(doc, WsnConstants.SUBSCRIBE_QNAME);
EndpointReference sub = getWsResource().getEndpointReference();
EndpointReference consumer = getConsumerReference();
EndpointReference producer = getProducerReference();
Filter filter = getFilter();
XmlUtils.setElement(root, WsnConstants.SUBSCRIPTION_EPR_QNAME, sub);
XmlUtils.setElement(root, WsnConstants.CONSUMER_QNAME, consumer);
XmlUtils.setElement(root, WsnConstants.PRODUCER_QNAME, producer);
XmlUtils.setElement(root, WsnConstants.FILTER_QNAME, filter);
return root;
}
}