diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Critical.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Critical.java index cba85535..076430b5 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Critical.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Critical.java @@ -40,7 +40,7 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; */ public class Critical extends Check { - private AuxMoving auxMoving = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(AuxMoving.class); + private final AuxMoving auxMoving = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(AuxMoving.class); /** * Instantiates a new critical check. diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java index 80634818..e42e7294 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java @@ -55,6 +55,7 @@ import fr.neatmonster.nocheatplus.compat.Bridge1_9; import fr.neatmonster.nocheatplus.compat.BridgeEnchant; import fr.neatmonster.nocheatplus.compat.BridgeHealth; import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin; +import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle; import fr.neatmonster.nocheatplus.components.registry.feature.JoinLeaveListener; import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.stats.Counters; @@ -110,7 +111,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{ private final int idCancelDead = counters.registerKey("canceldead"); // Assume it to stay the same all time. - private final IBridgeCrossPlugin crossPlugin = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(IBridgeCrossPlugin.class); + private final IGenericInstanceHandle crossPlugin = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstanceHandle(IBridgeCrossPlugin.class); public FightListener() { super(CheckType.FIGHT); @@ -489,7 +490,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{ final Player damagedPlayer = damaged instanceof Player ? (Player) damaged : null; final FightData damagedData = damagedPlayer == null ? null : FightData.getData(damagedPlayer); final boolean damagedIsDead = damaged.isDead(); - final boolean damagedIsFake = !crossPlugin.isNativeEntity(damaged); + final boolean damagedIsFake = !crossPlugin.getHandle().isNativeEntity(damaged); if (damagedPlayer != null && !damagedIsDead) { // God mode check. // (Do not test the savage.) @@ -588,7 +589,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{ attackerData.lastExplosionDamageTick = -1; attackerData.lastExplosionEntityId = Integer.MAX_VALUE; } - else if (handleNormalDamage(player, !crossPlugin.isNativePlayer(player), + else if (handleNormalDamage(player, !crossPlugin.getHandle().isNativePlayer(player), damaged, damagedIsFake, BridgeHealth.getOriginalDamage(event), BridgeHealth.getFinalDamage(event), tick, attackerData)) { diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/GodMode.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/GodMode.java index b7d8f4a4..569115dd 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/GodMode.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/GodMode.java @@ -23,6 +23,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.net.NetData; import fr.neatmonster.nocheatplus.compat.BridgeHealth; import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin; +import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle; import fr.neatmonster.nocheatplus.utilities.CheckUtils; import fr.neatmonster.nocheatplus.utilities.TickTask; @@ -31,6 +32,8 @@ import fr.neatmonster.nocheatplus.utilities.TickTask; */ public class GodMode extends Check { + private final IGenericInstanceHandle crossPlugin = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstanceHandle(IBridgeCrossPlugin.class); + /** * Instantiates a new god mode check. */ @@ -195,7 +198,7 @@ public class GodMode extends Check { // TODO: Is this still relevant ? // First check if the player is really dead (e.g. another plugin could have just fired an artificial event). if (BridgeHealth.getHealth(player) <= 0.0 && player.isDead() - && NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(IBridgeCrossPlugin.class).isNativeEntity(player)) { + && crossPlugin.getHandle().isNativeEntity(player)) { try { // Schedule a task to be executed in roughly 1.5 seconds. // TODO: Get plugin otherwise !? diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/GenericInstanceRegistry.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/GenericInstanceRegistry.java index 97e4355a..3a377943 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/GenericInstanceRegistry.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/GenericInstanceRegistry.java @@ -15,6 +15,7 @@ package fr.neatmonster.nocheatplus.components.registry; import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle; +import fr.neatmonster.nocheatplus.components.registry.exception.RegistrationLockedException; /** * A registry for unique instances of any class type.
@@ -32,17 +33,20 @@ public interface GenericInstanceRegistry { * be aligned to the actual class. * * @param instance + * @throws RegistrationLockedException + * If the registration of the class of instance is locked. */ public T registerGenericInstance(T instance); /** * Register an instance under for a super-class. * - * @todo The registry implementation might specify if overriding is allowed. * @param registerAs * @param instance * @return The previously registered instance. If none was registered, null * is returned. + * @throws RegistrationLockedException + * If the registration of registerFor is locked. */ public T registerGenericInstance(Class registerFor, TI instance); @@ -61,6 +65,8 @@ public interface GenericInstanceRegistry { * @param registeredFor * @return The previously registered instance. If none was registered, null * is returned. + * @throws RegistrationLockedException + * If the registration of registerFor is locked. */ public T unregisterGenericInstance(Class registeredFor); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceRegistryListener.java similarity index 69% rename from NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceListener.java rename to NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceRegistryListener.java index 39a53ea3..ccd34d8d 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/IUnregisterGenericInstanceRegistryListener.java @@ -15,13 +15,14 @@ package fr.neatmonster.nocheatplus.components.registry.event; /** - * Rather an internal interface. + * Allow to unregister listeners, should also disable internally created handles + * if they are this listener. Rather an internal interface. * * @author asofold * */ -public interface IUnregisterGenericInstanceListener { +public interface IUnregisterGenericInstanceRegistryListener { - public void unregisterGenericInstanceListener(Class registeredFor, IGenericInstanceHandle listener); + public void unregisterGenericInstanceRegistryListener(Class registeredFor, IGenericInstanceRegistryListener listener); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/exception/RegistrationLockedException.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/exception/RegistrationLockedException.java new file mode 100644 index 00000000..628db9c7 --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/exception/RegistrationLockedException.java @@ -0,0 +1,37 @@ +package fr.neatmonster.nocheatplus.components.registry.exception; + +/** + * A registration item has been locked versus changes, but was attempted to be + * changed. + * + * @author asofold + * + */ +public class RegistrationLockedException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -7278363049512687206L; + + public RegistrationLockedException() { + super(); + } + + public RegistrationLockedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public RegistrationLockedException(String message, Throwable cause) { + super(message, cause); + } + + public RegistrationLockedException(String message) { + super(message); + } + + public RegistrationLockedException(Throwable cause) { + super(cause); + } + +} diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java index c66743e9..8dba0a0c 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java @@ -935,11 +935,15 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { } // Register some generic stuff. - // Counters: debugging purposes, maybe integrated for statistics later. + // (Deny change some.) registerGenericInstance(new Counters()); + genericInstanceRegistry.denyChangeExistingRegistration(Counters.class); registerGenericInstance(new WRPT()); - registerGenericInstance(new Random(System.currentTimeMillis() ^ ((long) this.hashCode() * (long) listenerManager.hashCode() * (long) logManager.hashCode()))); + genericInstanceRegistry.denyChangeExistingRegistration(WRPT.class); registerGenericInstance(new TraceEntryPool(1000)); // Random number. + genericInstanceRegistry.denyChangeExistingRegistration(TraceEntryPool.class); + // (Allow override others.) + registerGenericInstance(new Random(System.currentTimeMillis() ^ ((long) this.hashCode() * (long) listenerManager.hashCode() * (long) logManager.hashCode()))); addComponent(new BridgeCrossPlugin()); // Initialize MCAccess. diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/DefaultGenericInstanceRegistry.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/DefaultGenericInstanceRegistry.java index 0b4b391c..91a9c377 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/DefaultGenericInstanceRegistry.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/DefaultGenericInstanceRegistry.java @@ -14,37 +14,152 @@ */ package fr.neatmonster.nocheatplus.components.registry; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Map; -import java.util.Set; import fr.neatmonster.nocheatplus.components.registry.event.GenericInstanceHandle.ReferenceCountHandle; import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle; import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceRegistryListener; -import fr.neatmonster.nocheatplus.components.registry.event.IUnregisterGenericInstanceListener; +import fr.neatmonster.nocheatplus.components.registry.event.IUnregisterGenericInstanceRegistryListener; +import fr.neatmonster.nocheatplus.components.registry.exception.RegistrationLockedException; import fr.neatmonster.nocheatplus.logging.details.IGetStreamId; import fr.neatmonster.nocheatplus.logging.details.ILogString; -public class DefaultGenericInstanceRegistry implements GenericInstanceRegistry, IUnregisterGenericInstanceListener { +public class DefaultGenericInstanceRegistry implements GenericInstanceRegistry, IUnregisterGenericInstanceRegistryListener { // TODO: Test cases. - /** Storage for generic instances registration. */ - private final Map, Object> instances = new HashMap, Object>(); + /** + * Hold registration information for a class, as well as some convenience + * functionality. + * + * @author asofold + * + */ + public static class Registration { - /** Listeners for registry events. */ - private final Map, Collection>> listeners = new HashMap, Collection>>(); + private static final long DENY_OVERRIDE_INSTANCE = 0x01; + private static final long DENY_REMOVE_INSTANCE = 0x02; - /** Owned handles by the class they have been registered for. */ - private final Map, IGenericInstanceHandle> uniqueHandles = new LinkedHashMap, IGenericInstanceHandle>(); + // TODO: unique handles + use - /** Handles created within this class, that have to be detached. */ - private final Set> ownedHandles = new LinkedHashSet>(); + private final GenericInstanceRegistry registry; + private final IUnregisterGenericInstanceRegistryListener unregister; + private final Class registeredFor; + private T instance = null; + /** Always kept registered, thus the reference count is ignored. */ + private ReferenceCountHandle uniqueHandle = null; + + private long accessFlags = 0L; + + private final List> listeners = new LinkedList>(); + + public Registration(Class registeredFor, T instance, + GenericInstanceRegistry registry, IUnregisterGenericInstanceRegistryListener unregister) { + this.registry = registry; + this.unregister = unregister; + this.registeredFor = registeredFor; + this.instance = instance; + } + + public void denyOverrideInstance() { + accessFlags |= DENY_OVERRIDE_INSTANCE; + } + + public void denyRemoveInstance() { + accessFlags |= DENY_REMOVE_INSTANCE; + } + + /** + * Call for unregistering this instance officially. Listeners and + * handles may be kept, + * + * @return The previously registered instance. + */ + public T unregisterInstance() { + if ((accessFlags & DENY_REMOVE_INSTANCE) != 0) { + throw new RegistrationLockedException(); + } + T oldInstance = this.instance; + this.instance = null; + if (!listeners.isEmpty()) { + for (IGenericInstanceRegistryListener listener : listeners) { + ((IGenericInstanceRegistryListener) listener).onGenericInstanceRemove(registeredFor, oldInstance); + } + } + return oldInstance; + } + + /** + * Call on register. + * + * @param instance + * The previously registered instance. + * @return + */ + public T registerInstance(T instance) { + if ((accessFlags & DENY_OVERRIDE_INSTANCE) != 0) { + throw new RegistrationLockedException(); + } + T oldInstance = this.instance; + this.instance = instance; + if (!listeners.isEmpty()) { + if (oldInstance == null) { + for (IGenericInstanceRegistryListener listener : listeners) { + listener.onGenericInstanceOverride(registeredFor, instance, oldInstance); + } + } + else { + for (IGenericInstanceRegistryListener listener : listeners) { + listener.onGenericInstanceRegister(registeredFor, instance); + } + } + } + return oldInstance; + } + + public IGenericInstanceHandle getHandle() { + if (uniqueHandle == null) { + uniqueHandle = new ReferenceCountHandle(registeredFor, registry, unregister); + this.listeners.add(uniqueHandle); + } + return uniqueHandle.getNewHandle(); + } + + public void unregisterListener(IGenericInstanceRegistryListener listener) { + IGenericInstanceHandle disable = null; + if (listener == uniqueHandle) { + disable = uniqueHandle; + uniqueHandle = null; + } + this.listeners.remove(listener); + if (disable != null) { + disable.disableHandle(); + } + } + + public T getInstance() { + return (T) instance; + } + + public boolean canBeRemoved() { + return instance == null && uniqueHandle == null && listeners.isEmpty(); + } + + public void clear() { + instance = null; + if (uniqueHandle != null) { + uniqueHandle.disableHandle(); + uniqueHandle = null; + } + listeners.clear(); + } + + } + + private final Map, Registration> registrations = new LinkedHashMap, Registration>(); private ILogString logger = null; @@ -58,19 +173,22 @@ public class DefaultGenericInstanceRegistry implements GenericInstanceRegistry, this.logPrefix = logPrefix; } - @Override - public void unregisterGenericInstanceListener(Class registeredFor, IGenericInstanceHandle listener) { - Collection> registered = listeners.get(registeredFor); - if (registered != null) { - registered.remove(listener); - if (registered.isEmpty()) { - listeners.remove(registeredFor); - } + @SuppressWarnings("unchecked") + private Registration getRegistration(Class registeredFor, boolean create) { + Registration registration = (Registration) registrations.get(registeredFor); + if (registration == null && create) { + // Create empty. + registration = new Registration(registeredFor, null, this, this); + this.registrations.put(registeredFor, registration); } - if ((listener instanceof ReferenceCountHandle) && ownedHandles.contains(listener)) { - ownedHandles.remove(listener); - uniqueHandles.remove(registeredFor); - ((IGenericInstanceHandle) listener).disableHandle(); + return registration; + } + + @Override + public void unregisterGenericInstanceRegistryListener(Class registeredFor, IGenericInstanceRegistryListener listener) { + Registration registration = getRegistration(registeredFor, false); + if (registration != null) { + registration.unregisterListener(listener); } } @@ -80,24 +198,11 @@ public class DefaultGenericInstanceRegistry implements GenericInstanceRegistry, return registerGenericInstance((Class) instance.getClass(), instance); } - @SuppressWarnings("unchecked") @Override public T registerGenericInstance(Class registerFor, TI instance) { - T registered = getGenericInstance(registerFor); - final boolean had = instances.containsKey(registerFor); - instances.put(registerFor, instance); - Collection> registeredListeners = listeners.get(registerFor); - if (registeredListeners != null) { - for (IGenericInstanceRegistryListener rawListener : registeredListeners) { - if (had) { - ((IGenericInstanceRegistryListener) rawListener).onGenericInstanceOverride(registerFor, instance, registered); - } - else { - ((IGenericInstanceRegistryListener) rawListener).onGenericInstanceRegister(registerFor, instance); - } - } - } - if (had) { + Registration registration = getRegistration(registerFor, true); + T registered = registration.registerInstance(instance); + if (registered != null) { logRegistryEvent("Registered (override) for " + registerFor.getName() + ": " + instance.getClass().getName()); } else { @@ -106,64 +211,56 @@ public class DefaultGenericInstanceRegistry implements GenericInstanceRegistry, return registered; } - @SuppressWarnings("unchecked") @Override public T getGenericInstance(Class registeredFor) { - return (T) instances.get(registeredFor); + Registration registration = getRegistration(registeredFor, false); + return registration == null ? null : registration.getInstance(); } - @SuppressWarnings("unchecked") @Override public T unregisterGenericInstance(Class registeredFor) { - T registered = getGenericInstance(registeredFor); // Convenience. - final boolean had = instances.containsKey(registeredFor); - instances.remove(registeredFor); - Collection> registeredListeners = listeners.get(registeredFor); - if (registeredListeners != null) { - for (IGenericInstanceRegistryListener rawListener : registeredListeners) { - ((IGenericInstanceRegistryListener) rawListener).onGenericInstanceRemove(registeredFor, registered); - } - } - if (had) { + Registration registration = getRegistration(registeredFor, false); + T registered = registration == null ? null : registration.unregisterInstance(); + if (registered != null) { logRegistryEvent("Unregister, remove mapping for: " + registeredFor.getName()); } else { logRegistryEvent("Unregister, no mapping present for: " + registeredFor.getName()); } + // Repeat getting for removal test. + if (registrations.containsKey(registeredFor) && getRegistration(registeredFor, false).canBeRemoved()) { + registrations.remove(registeredFor); + } return registered; } @Override public IGenericInstanceHandle getGenericInstanceHandle(Class registeredFor) { - @SuppressWarnings("unchecked") - ReferenceCountHandle handle = (ReferenceCountHandle) uniqueHandles.get(registeredFor); - if (handle == null) { - handle = new ReferenceCountHandle(registeredFor, this, this); - ownedHandles.add(handle); - uniqueHandles.put(registeredFor, handle); - Collection> registered = listeners.get(registeredFor); - if (registered == null) { - registered = new HashSet>(); - listeners.put(registeredFor, registered); - } - registered.add((IGenericInstanceRegistryListener) handle); - } - // else: no need to register. - return handle.getNewHandle(); + return getRegistration(registeredFor, true).getHandle(); } public void clear() { - instances.clear(); - listeners.clear(); // TODO: consider fire unregister or add a removal method ? - // Force detach all handles. - for (IGenericInstanceHandle handle : new ArrayList>(ownedHandles)) { - handle.disableHandle(); + for (final Registration registration : registrations.values()) { + registration.clear(); } - ownedHandles.clear(); + registrations.clear(); logRegistryEvent("Registry cleared."); } + /** + * Convenience method to lock a registration vs. changing. + * + * @param registeredFor + */ + public void denyChangeExistingRegistration(Class registeredFor) { + Registration registration = this.getRegistration(registeredFor, false); + if (registration != null) { + registration.denyOverrideInstance(); + registration.denyRemoveInstance(); + } + } + protected void logRegistryEvent(String message) { if (logger != null) { logger.info(selectStream.getStreamId(), logPrefix == null ? message : logPrefix + message); diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/GenericInstanceHandle.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/GenericInstanceHandle.java index 5ea37e18..d346977a 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/GenericInstanceHandle.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/registry/event/GenericInstanceHandle.java @@ -69,7 +69,8 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene /** * Allow fetching PrarentDelegate instances, increasing reference count with * each returned one. Really unregister only with reaching a count of zero - * on disableHandle. This way only one instance needs to be updated. + * on disableHandle. This way only one instance needs to be updated. This + * doesn't self-register as listener. * * @author asofold * @@ -80,7 +81,7 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene private int references = 0; public ReferenceCountHandle(Class registeredFor, GenericInstanceRegistry registry, - IUnregisterGenericInstanceListener unregister) { + IUnregisterGenericInstanceRegistryListener unregister) { super(registeredFor, registry, unregister); } @@ -102,10 +103,14 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene return new ParentDelegateHandle(getRegisteredFor(), getRegistry(), this); } + public int getNumberOfReferences() { + return references; + } + } private GenericInstanceRegistry registry; - private IUnregisterGenericInstanceListener unregister; + private IUnregisterGenericInstanceRegistryListener unregister; private Class registeredFor; private T handle = null; private boolean initialized = false; @@ -119,7 +124,7 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene * @param registry * @param unregister */ - public GenericInstanceHandle(Class registeredFor, GenericInstanceRegistry registry, IUnregisterGenericInstanceListener unregister) { + public GenericInstanceHandle(Class registeredFor, GenericInstanceRegistry registry, IUnregisterGenericInstanceRegistryListener unregister) { this.registry = registry; this.unregister = unregister; this.registeredFor = registeredFor; @@ -169,7 +174,7 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene registeredFor = null; registry = null; if (unregister != null) { - unregister.unregisterGenericInstanceListener(registeredFor, this); + unregister.unregisterGenericInstanceRegistryListener(registeredFor, this); } unregister = null; } @@ -183,7 +188,7 @@ public class GenericInstanceHandle implements IGenericInstanceRegistryListene return registry; } - public IUnregisterGenericInstanceListener getUnregister() { + public IUnregisterGenericInstanceRegistryListener getUnregister() { return unregister; }