/*=============================================================================*
* Copyright 2004 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.ws.notification.base;
import org.apache.ws.notification.base.v2004_06.BaseNotificationConstants;
import org.apache.ws.notification.base.v2004_06.impl.SubscriptionHome;
import org.apache.ws.notification.topics.Topic;
import org.apache.ws.resource.ResourceException;
import org.apache.ws.resource.ResourceHome;
import org.apache.ws.resource.WsrfRuntime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A singleton that manages all subscriptions.
*/
public class SubscriptionManager
{
private static final SubscriptionManager INSTANCE = new SubscriptionManager( );
/*
* Maps producer {@link EndpointReference}s to {@link Map}s of {@link Topic}s to
* the ids of the {@link Subscription}s associated with those Topics.
*/
private final Map m_producerToTopicToSubscriptionsMap = Collections.synchronizedMap( new HashMap( ) );
private SubscriptionManager( )
{
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public static SubscriptionManager getInstance( )
{
return INSTANCE;
}
/**
* DOCUMENT_ME
*
* @param producerResource DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourceHome getSubscriptionManagerHome( NotificationProducerResource producerResource )
{
String baseNotifXsdNsURI =
( (WsnNamespaceVersionHolder) producerResource.getNamespaceSet( ) ).getBaseNotificationXsdNamespace( );
String subMgrServiceName;
if ( baseNotifXsdNsURI.equals( BaseNotificationConstants.NSURI_WSNT_SCHEMA ) )
{
subMgrServiceName = "SubscriptionManager";
}
else
{
throw new IllegalArgumentException( "Unsupported WS-BaseNotification XSD namespace URI: "
+ baseNotifXsdNsURI );
}
try
{
return (SubscriptionHome) WsrfRuntime.getRuntime( ).getResourceHome( subMgrServiceName );
}
catch ( ResourceException re )
{
throw new RuntimeException( "Failed to obtain subscription manager home.", re );
}
}
/**
* @param producerResource
* @param topic
*
* @return the subscriptions associated with the specified topics on the specified producer
*/
public Subscription[] getSubscriptions( NotificationProducerResource producerResource,
Topic topic )
{
List subscriptions = new ArrayList( );
Map topicToSubscriptionMap =
(Map) m_producerToTopicToSubscriptionsMap.get( producerResource.getEndpointReference( ) );
if ( topicToSubscriptionMap != null )
{
List subscriptionIds = (List) topicToSubscriptionMap.get( topic );
if ( subscriptionIds != null )
{
ResourceHome subMgrHome = getSubscriptionManagerHome( producerResource );
synchronized ( subscriptionIds )
{
for ( int i = 0; i < subscriptionIds.size( ); i++ )
{
String subscriptionId = (String) subscriptionIds.get( i );
Subscription subscription;
try
{
subscription = (Subscription) subMgrHome.find( subscriptionId );
}
catch ( ResourceException re )
{
subscriptionIds.remove( i ); // remove stale subscription id from list
continue;
}
subscriptions.add( subscription );
}
}
}
}
return (Subscription[]) subscriptions.toArray( new Subscription[0] );
}
/**
* @param subscription
* @param topics
*/
public void addSubscription( Subscription subscription,
Topic[] topics )
{
Map topicToSubscriptionMap = getTopicToSubscriptionMap( subscription );
for ( int i = 0; i < topics.length; i++ )
{
Topic topic = topics[i];
List subscriptionIds = (List) topicToSubscriptionMap.get( topic );
if ( subscriptionIds == null )
{
subscriptionIds = new ArrayList( );
topicToSubscriptionMap.put( topic, subscriptionIds );
}
synchronized ( subscriptionIds )
{
subscriptionIds.add( subscription.getID( ) );
}
}
}
/**
* @param subscription
* @param topics
*/
public void removeSubscription( Subscription subscription,
Topic[] topics )
{
Map topicToSubscriptionMap = getTopicToSubscriptionMap( subscription );
for ( int i = 0; i < topics.length; i++ )
{
Topic topic = topics[i];
List subscriptionIds = (List) topicToSubscriptionMap.get( topic );
synchronized ( subscriptionIds )
{
subscriptionIds.remove( subscription.getID( ) );
}
}
}
private Map getTopicToSubscriptionMap( Subscription subscription )
{
Map topicToSubscriptionMap =
(Map) m_producerToTopicToSubscriptionsMap.get( subscription.getProducerReference( ) );
if ( topicToSubscriptionMap == null )
{
topicToSubscriptionMap = Collections.synchronizedMap( new HashMap( ) );
m_producerToTopicToSubscriptionsMap.put( subscription.getProducerReference( ),
topicToSubscriptionMap );
}
return topicToSubscriptionMap;
}
}