com.tangosol.net.events.internal.Registry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of coherence Show documentation
Show all versions of coherence Show documentation
Oracle Coherence Community Edition
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.net.events.internal;
import com.oracle.coherence.common.base.Disposable;
import com.tangosol.net.events.Event;
import com.tangosol.net.events.EventDispatcher;
import com.tangosol.net.events.EventDispatcherRegistry;
import com.tangosol.net.events.EventInterceptor;
import com.tangosol.net.events.InterceptorRegistry;
import com.tangosol.net.security.LocalPermission;
import com.tangosol.util.Base;
import com.tangosol.util.RegistrationBehavior;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Implementation of both {@link EventDispatcherRegistry} &
* {@link InterceptorRegistry}.
*
* @author mwj, rhan, nsa, rhl, hr 2011.03.29
* @since Coherence 12.1.2
*/
public class Registry
implements InterceptorRegistry, EventDispatcherRegistry, Disposable
{
// ------ constructors --------------------------------------------------
/**
* Default constructor.
*/
public Registry()
{
m_mapInterceptors = new LinkedHashMap<>(); // Preserve the interceptor order
m_setDispatchers = Collections.newSetFromMap(new ConcurrentHashMap());
}
// ----- InterceptorRegistry interface ----------------------------------
/**
* {@inheritDoc}
*/
public synchronized String registerEventInterceptor(EventInterceptor> interceptor)
{
return registerEventInterceptorInternal(null, interceptor, null);
}
/**
* {@inheritDoc}
*/
public synchronized String registerEventInterceptor(EventInterceptor> interceptor, RegistrationBehavior behavior)
{
return registerEventInterceptorInternal(null, interceptor, behavior);
}
/**
* {@inheritDoc}
*/
public synchronized String registerEventInterceptor(String sIdentifier, EventInterceptor> interceptor, RegistrationBehavior behavior)
{
return registerEventInterceptorInternal(sIdentifier, interceptor, behavior);
}
/**
* {@inheritDoc}
*/
public synchronized void unregisterEventInterceptor(String sIdentifier)
{
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkPermission(
new LocalPermission("Service.registerEventInterceptor"));
}
EventInterceptor interceptor = m_mapInterceptors.remove(sIdentifier);
if (interceptor != null)
{
removeInterceptorFromDispatchers(sIdentifier);
}
}
/**
* {@inheritDoc}
*/
public synchronized EventInterceptor> getEventInterceptor(String sIdentifier)
{
NamedEventInterceptor incptr = m_mapInterceptors.get(sIdentifier);
return incptr == null ? null : incptr.getInterceptor();
}
// ----- Disposable methods ---------------------------------------------
/**
* {@inheritDoc}
*/
public synchronized void dispose()
{
m_setDispatchers.clear();
m_mapInterceptors.clear();
}
// ----- EventDispatcherRegistry interface ------------------------------
/**
* {@inheritDoc}
*/
public synchronized void registerEventDispatcher(EventDispatcher dispatcher)
{
m_setDispatchers.add(dispatcher);
introduceDispatcher(dispatcher);
}
/**
* {@inheritDoc}
*/
public synchronized void unregisterEventDispatcher(EventDispatcher dispatcher)
{
m_setDispatchers.remove(dispatcher);
}
// ----- helper methods -------------------------------------------------
/**
* Register the provided {@link EventInterceptor} with the identifier.
*
* @param sIdentifier a unique identifier for the interceptor which upon
* null will cause a default identifier to be generated
* @param interceptor the EventInterceptor to register
* @param behavior the behavior enacted upon discovering duplicate
* interceptors
*
* @param the event that the interceptor accepts
*
* @return the identifier used to register the interceptor
*/
protected > String registerEventInterceptorInternal(
String sIdentifier, EventInterceptor interceptor, RegistrationBehavior behavior)
{
NamedEventInterceptor incptrNamed;
if (interceptor instanceof NamedEventInterceptor)
{
incptrNamed = (NamedEventInterceptor) interceptor;
if (sIdentifier != null && !incptrNamed.getRegisteredName().equals(sIdentifier))
{
// clone the NamedEventInterceptor with the correct identifier
incptrNamed = new NamedEventInterceptor<>(sIdentifier, incptrNamed.getInterceptor(),
incptrNamed.getCacheName(), incptrNamed.getServiceName(), incptrNamed.getOrder(),
behavior == null ? incptrNamed.getBehavior() : behavior,
incptrNamed.getEventTypes());
}
}
else
{
incptrNamed = new NamedEventInterceptor<>(sIdentifier, interceptor, behavior);
}
registerEventInterceptorInternal(incptrNamed);
return incptrNamed.getRegisteredName();
}
/**
* Registers a unique {@link EventInterceptor} based on
* {@link NamedEventInterceptor#getRegisteredName()}. The NamedEventInterceptor is
* passed to the {@link EventDispatcher} however the wrapped
* EventInterceptor is stored locally.
*
* @param incptrNamed the NamedEventInterceptor to pass to the EventDispatcher
*/
protected void registerEventInterceptorInternal(NamedEventInterceptor> incptrNamed)
{
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkPermission(
new LocalPermission("Service.registerEventInterceptor"));
}
String sIdentifier = incptrNamed.getRegisteredName();
RegistrationBehavior behavior = incptrNamed.getBehavior();
Map> mapInterceptors = m_mapInterceptors;
if (mapInterceptors.containsKey(sIdentifier))
{
switch (behavior)
{
case IGNORE:
return;
case REPLACE:
unregisterEventInterceptor(sIdentifier);
break;
case ALWAYS:
// 1024 attempts in generating a unique identifier
for (int i = 0; i < 1024 && mapInterceptors.containsKey(sIdentifier); ++i)
{
sIdentifier = incptrNamed.generateName();
}
if (!mapInterceptors.containsKey(sIdentifier))
{
break;
}
case FAIL:
throw new IllegalArgumentException(
"EventInterceptor " + incptrNamed + " is already registered");
}
}
mapInterceptors.put(sIdentifier, incptrNamed);
try
{
introduceInterceptor(incptrNamed);
}
catch (Exception e)
{
// Don't leave the interceptor partially registered with dispatchers
unregisterEventInterceptor(sIdentifier);
throw Base.ensureRuntimeException(e);
}
}
/**
* Introduce each currently registered {@link EventInterceptor} to the
* newly registered {@link EventDispatcher}.
*
* @param dispatcher the EventDispatcher to be introduced
*/
protected void introduceDispatcher(EventDispatcher dispatcher)
{
for (Entry> entry : m_mapInterceptors.entrySet())
{
entry.getValue().introduceEventDispatcher(entry.getKey(), dispatcher);
}
}
/**
* Introduce the specified {@link NamedEventInterceptor} to each currently
* registered {@link EventDispatcher}.
*
* @param incptrNamed the NamedEventInterceptor to introduce
*/
protected void introduceInterceptor(NamedEventInterceptor incptrNamed)
{
String sIdentifier = incptrNamed.getRegisteredName();
for (EventDispatcher dispatcher : m_setDispatchers)
{
incptrNamed.introduceEventDispatcher(sIdentifier, dispatcher);
}
}
/**
* Call each currently registered {@link EventDispatcher} to remove the
* specified {@link EventInterceptor}, by name.
*
* @param sIdentifier the name of the EventInterceptor to be removed
*/
protected void removeInterceptorFromDispatchers(String sIdentifier)
{
for (EventDispatcher dispatcher : m_setDispatchers)
{
dispatcher.removeEventInterceptor(sIdentifier);
}
}
/**
* The registered {@link EventInterceptor}s.
*/
protected final Map> m_mapInterceptors;
/**
* The registered {@link EventDispatcher}s.
*/
protected final Set m_setDispatchers;
}