diff options
30 files changed, 800 insertions, 164 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java index 86a29b24d8..8b219a1ecb 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java @@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.internal.common.revision.cache.EvictionEventImpl; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -417,7 +418,11 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache } else { - fireEvent(new EvictionEventImpl(LRURevisionCache.this, revision)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new EvictionEventImpl(LRURevisionCache.this, revision), listeners); + } } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java index dd57919e1f..d299514fbb 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java @@ -23,6 +23,7 @@ import org.eclipse.emf.cdo.internal.common.revision.cache.EvictionEventImpl; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.net4j.util.ref.KeyedPhantomReference; import org.eclipse.net4j.util.ref.KeyedReference; @@ -206,12 +207,20 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision> InternalCDORevision revision = removeRevision(id, version); if (revision == null) { - fireEvent(new EvictionEventImpl(this, id, version)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new EvictionEventImpl(this, id, version), listeners); + } } else { // Should not happen with garbage collector triggered eviction - fireEvent(new EvictionEventImpl(this, revision)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new EvictionEventImpl(this, revision), listeners); + } } } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOWatchListView.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOWatchListView.java index 30936fc69d..57b30b4e28 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOWatchListView.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOWatchListView.java @@ -669,13 +669,21 @@ public class CDOWatchListView extends ViewPart implements ISelectionProvider public void addNotification(Notification msg) { getData(msg.getNotifier()).setNotification(msg); - fireEvent(dataRegistryEvent); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(dataRegistryEvent, listeners); + } } public void removeNotification(Object object) { getData(object).deleteNotification(); - fireEvent(dataRegistryEvent); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(dataRegistryEvent, listeners); + } } public void removeData(Object object) @@ -690,7 +698,11 @@ public class CDOWatchListView extends ViewPart implements ISelectionProvider data.deleteNotification(); } - fireEvent(dataRegistryEvent); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(dataRegistryEvent, listeners); + } } public Notification getNotification(Object object) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java index 97a47cc1fb..9874b0396d 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java @@ -863,7 +863,11 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled; // TODO Check inconsistent state if switching off? - fireEvent(new GeneratedPackageEmulationEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new GeneratedPackageEmulationEventImpl(), listeners); + } } } @@ -886,7 +890,11 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter getSessionProtocol().setPassiveUpdate(allRevisions, initialChunkSize, passiveUpdateEnabled); } - fireEvent(new PassiveUpdateEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new PassiveUpdateEventImpl(), listeners); + } } } @@ -905,7 +913,11 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter if (collectionLoadingPolicy != policy) { collectionLoadingPolicy = policy; - fireEvent(new CollectionLoadingPolicyEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new CollectionLoadingPolicyEventImpl(), listeners); + } } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java index 39f97ccff1..bb31e5b1af 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/remote/CDORemoteSessionManagerImpl.java @@ -254,24 +254,29 @@ public class CDORemoteSessionManagerImpl extends Container<CDORemoteSession> imp } @Override - protected void listenersEmptyChanged(boolean empty) + protected void firstListenerAdded() { IEvent[] events = null; synchronized (this) { - if (empty) + if (!subscribed) { - if (!forceSubscription) - { - events = unsubscribe(); - } + events = subscribe(); } - else + } + + fireEvents(events); + } + + @Override + protected void lastListenerRemoved() + { + IEvent[] events = null; + synchronized (this) + { + if (!forceSubscription) { - if (!subscribed) - { - events = subscribe(); - } + events = unsubscribe(); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index 753c10b4ee..85cfee29bd 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -57,6 +57,7 @@ import org.eclipse.emf.internal.cdo.view.CDOViewImpl; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.ObjectUtil; import org.eclipse.net4j.util.WrappedException; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.net4j.util.options.OptionsEvent; @@ -210,7 +211,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa { ConflictEvent event = new ConflictEvent(object, conflict == 0); ++conflict; - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } } /** @@ -467,7 +472,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa public void detach(CDOResourceImpl cdoResource) { CDOStateMachine.INSTANCE.detach(cdoResource); - fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.REMOVED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.REMOVED), listeners); + } } /** @@ -899,7 +908,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (!dirty) { dirty = true; - fireEvent(new StartedEvent()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new StartedEvent(), listeners); + } } } @@ -969,7 +982,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } Map<CDOIDTemp, CDOID> idMappings = Collections.emptyMap(); - fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.ROLLED_BACK, idMappings)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.ROLLED_BACK, idMappings), listeners); + } + for (CDOTransactionHandler handler : getTransactionHandlers()) { try @@ -1137,7 +1155,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (!dirty) { dirty = true; - fireEvent(new StartedEvent()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new StartedEvent(), listeners); + } } } @@ -1433,7 +1455,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa cleanUp(); Map<CDOIDTemp, CDOID> idMappings = result.getIDMappings(); - fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings), listeners); + } } catch (RuntimeException ex) { @@ -1640,7 +1666,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } } - fireEvent(new ConflictResolversEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ConflictResolversEventImpl(), listeners); + } } public void addConflictResolver(CDOConflictResolver resolver) @@ -1658,7 +1688,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (changed) { - fireEvent(new ConflictResolversEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ConflictResolversEventImpl(), listeners); + } } } @@ -1673,7 +1707,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (changed) { resolver.setTransaction(null); - fireEvent(new ConflictResolversEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ConflictResolversEventImpl(), listeners); + } } } @@ -1717,7 +1755,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (autoReleaseLocksEnabled != on) { autoReleaseLocksEnabled = on; - fireEvent(new AutoReleaseLockEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new AutoReleaseLockEventImpl(), listeners); + } } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java index 24d96db2a8..f1838b7d41 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java @@ -68,6 +68,7 @@ import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.collection.HashBag; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; @@ -1312,7 +1313,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView { if (!dirtyObjects.isEmpty() || !detachedObjects.isEmpty()) { - fireEvent(new InvalidationEvent(timeStamp, dirtyObjects, detachedObjects)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new InvalidationEvent(timeStamp, dirtyObjects, detachedObjects), listeners); + } } } @@ -2060,7 +2065,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (invalidationNotificationEnabled != enabled) { invalidationNotificationEnabled = enabled; - fireEvent(new InvalidationNotificationEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new InvalidationNotificationEventImpl(), listeners); + } } } @@ -2094,7 +2103,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (changed) { - fireEvent(new ChangeSubscriptionPoliciesEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners); + } } } @@ -2112,7 +2125,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (changed) { - fireEvent(new ChangeSubscriptionPoliciesEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners); + } } } @@ -2132,7 +2149,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView { strongReferencePolicy = adapterPolicy; adapterPolicyManager.reset(); - fireEvent(new ReferencePolicyEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new ReferencePolicyEventImpl(), listeners); + } } } @@ -2151,7 +2172,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (revisionPrefetchingPolicy != prefetchingPolicy) { revisionPrefetchingPolicy = prefetchingPolicy; - fireEvent(new RevisionPrefetchingPolicyEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new RevisionPrefetchingPolicyEventImpl(), listeners); + } } } @@ -2170,7 +2195,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (staleReferencePolicy != policy) { staleReferencePolicy = policy; - fireEvent(new StaleReferencePolicyEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new StaleReferencePolicyEventImpl(), listeners); + } } } @@ -2238,7 +2267,12 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (objects == null) { objects = newObjects; - fireEvent(new CacheReferenceTypeEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new CacheReferenceTypeEventImpl(), listeners); + } + return true; } @@ -2258,7 +2292,12 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView } oldObjects.clear(); - fireEvent(new CacheReferenceTypeEventImpl()); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new CacheReferenceTypeEventImpl(), listeners); + } + return true; } diff --git a/plugins/org.eclipse.net4j.buddies.chat/src/org/eclipse/net4j/buddies/internal/chat/Chat.java b/plugins/org.eclipse.net4j.buddies.chat/src/org/eclipse/net4j/buddies/internal/chat/Chat.java index 91612fd387..13fe6452ed 100644 --- a/plugins/org.eclipse.net4j.buddies.chat/src/org/eclipse/net4j/buddies/internal/chat/Chat.java +++ b/plugins/org.eclipse.net4j.buddies.chat/src/org/eclipse/net4j/buddies/internal/chat/Chat.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -14,6 +14,7 @@ import org.eclipse.net4j.buddies.chat.IChat; import org.eclipse.net4j.buddies.chat.IComment; import org.eclipse.net4j.buddies.common.IMessage; import org.eclipse.net4j.buddies.spi.common.Facility; +import org.eclipse.net4j.util.event.IListener; import java.util.ArrayList; import java.util.List; @@ -62,6 +63,10 @@ public class Chat extends Facility implements IChat comments.add(comment); } - fireEvent(new CommentEvent(this, comment)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new CommentEvent(this, comment), listeners); + } } } diff --git a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Buddy.java b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Buddy.java index 9e57211420..45d107502f 100644 --- a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Buddy.java +++ b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Buddy.java @@ -18,6 +18,7 @@ import org.eclipse.net4j.buddies.common.ISession; import org.eclipse.net4j.util.ObjectUtil; import org.eclipse.net4j.util.event.Event; import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; @@ -67,7 +68,11 @@ public abstract class Buddy extends MembershipContainer implements IBuddy { IEvent event = new BuddyStateEvent(this.state, state); this.state = state; - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } } } diff --git a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/BuddyContainer.java b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/BuddyContainer.java index 4e640b6379..09e6d3d488 100644 --- a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/BuddyContainer.java +++ b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/BuddyContainer.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -55,7 +55,12 @@ public class BuddyContainer extends Lifecycle implements IBuddyContainer, IListe if (!buddies.containsKey(userID)) { buddies.put(userID, buddy); - fireEvent(new SingleDeltaContainerEvent<IBuddy>(this, buddy, IContainerDelta.Kind.ADDED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<IBuddy>(this, buddy, IContainerDelta.Kind.ADDED), listeners); + } + buddy.addListener(this); return true; } @@ -75,7 +80,11 @@ public class BuddyContainer extends Lifecycle implements IBuddyContainer, IListe if (buddy != null) { buddy.removeListener(this); - fireEvent(new SingleDeltaContainerEvent<IBuddy>(this, buddy, IContainerDelta.Kind.REMOVED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<IBuddy>(this, buddy, IContainerDelta.Kind.REMOVED), listeners); + } } return buddy; diff --git a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Collaboration.java b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Collaboration.java index 4f1d6fef51..dffc5d7c52 100644 --- a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Collaboration.java +++ b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/Collaboration.java @@ -22,6 +22,7 @@ import org.eclipse.net4j.signal.SignalProtocol; import org.eclipse.net4j.util.ObjectUtil; import org.eclipse.net4j.util.event.Event; import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.core.runtime.Platform; @@ -149,7 +150,12 @@ public class Collaboration extends MembershipContainer implements ICollaboration if (!facilities.containsKey(type)) { facilities.put(type, facility); - fireEvent(new FacilityInstalledEvent(this, facility, remote)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new FacilityInstalledEvent(this, facility, remote), listeners); + } + facility.addListener(this); return true; } diff --git a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/CollaborationContainer.java b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/CollaborationContainer.java index db00d9052c..707a18cdf2 100644 --- a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/CollaborationContainer.java +++ b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/CollaborationContainer.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -58,7 +58,13 @@ public class CollaborationContainer extends Lifecycle implements ICollaborationC } } - fireEvent(new SingleDeltaContainerEvent<ICollaboration>(this, collaboration, IContainerDelta.Kind.ADDED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<ICollaboration>(this, collaboration, IContainerDelta.Kind.ADDED), + listeners); + } + collaboration.addListener(this); } @@ -73,7 +79,12 @@ public class CollaborationContainer extends Lifecycle implements ICollaborationC if (collaboration != null) { collaboration.removeListener(this); - fireEvent(new SingleDeltaContainerEvent<ICollaboration>(this, collaboration, IContainerDelta.Kind.REMOVED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<ICollaboration>(this, collaboration, IContainerDelta.Kind.REMOVED), + listeners); + } } return collaboration; diff --git a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/MembershipContainer.java b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/MembershipContainer.java index 9a25277e9c..1ca091b7f3 100644 --- a/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/MembershipContainer.java +++ b/plugins/org.eclipse.net4j.buddies.common/src/org/eclipse/net4j/buddies/internal/common/MembershipContainer.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -40,7 +40,12 @@ public class MembershipContainer extends Lifecycle implements IMembershipContain { if (memberships.putIfAbsent(membership, membership) == null) { - fireEvent(new SingleDeltaContainerEvent<IMembership>(this, membership, IContainerDelta.Kind.ADDED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<IMembership>(this, membership, IContainerDelta.Kind.ADDED), listeners); + } + membership.addListener(this); } } @@ -61,7 +66,11 @@ public class MembershipContainer extends Lifecycle implements IMembershipContain if (membership != null) { membership.removeListener(this); - fireEvent(new SingleDeltaContainerEvent<IMembership>(this, membership, IContainerDelta.Kind.REMOVED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<IMembership>(this, membership, IContainerDelta.Kind.REMOVED), listeners); + } } return membership; diff --git a/plugins/org.eclipse.net4j.buddies/src/org/eclipse/net4j/internal/buddies/SessionManager.java b/plugins/org.eclipse.net4j.buddies/src/org/eclipse/net4j/internal/buddies/SessionManager.java index f7579ff1dd..b64681252e 100644 --- a/plugins/org.eclipse.net4j.buddies/src/org/eclipse/net4j/internal/buddies/SessionManager.java +++ b/plugins/org.eclipse.net4j.buddies/src/org/eclipse/net4j/internal/buddies/SessionManager.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -62,7 +62,11 @@ public class SessionManager extends Lifecycle implements ISessionManager, IListe { IEvent event = new SessionManagerEvent(this.state, state, session); this.state = state; - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/widgets/SashComposite.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/widgets/SashComposite.java index 4c67fdce86..65e25b5d72 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/widgets/SashComposite.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/widgets/SashComposite.java @@ -162,7 +162,11 @@ public abstract class SashComposite extends Composite implements INotifier init(); layout(); - notifier.fireEvent(new OrientationChangedEvent(vertical)); + IListener[] listeners = notifier.getListeners(); + if (listeners != null) + { + notifier.fireEvent(new OrientationChangedEvent(vertical), listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/om/pref/Preferences.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/om/pref/Preferences.java index 126445b098..55a5ee1768 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/om/pref/Preferences.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/om/pref/Preferences.java @@ -4,13 +4,14 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ package org.eclipse.net4j.internal.util.om.pref; import org.eclipse.net4j.internal.util.bundle.AbstractBundle; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import org.eclipse.net4j.util.io.IORunnable; import org.eclipse.net4j.util.io.IORuntimeException; @@ -264,7 +265,11 @@ public class Preferences extends Notifier implements OMPreferences public <T> void fireChangeEvent(Preference<T> preference, T oldValue, T newValue) { dirty = true; - fireEvent(new PreferencesChangeEvent<T>(preference, oldValue, newValue)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new PreferencesChangeEvent<T>(preference, oldValue, newValue), listeners); + } } private <T> OMPreference<T> init(Preference<T> preference) diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/cache/CacheMonitor.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/cache/CacheMonitor.java index 19c5b9df6f..22dcd7de35 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/cache/CacheMonitor.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/cache/CacheMonitor.java @@ -14,6 +14,7 @@ import org.eclipse.net4j.internal.util.bundle.OM; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.concurrent.Worker; import org.eclipse.net4j.util.event.Event; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.om.trace.ContextTracer; import java.util.HashMap; @@ -200,7 +201,11 @@ public class CacheMonitor extends Worker implements ICacheMonitor if (newCondition != oldCondition) { condition = newCondition; - fireEvent(new CacheMonitorEvent(oldCondition, newCondition)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new CacheMonitorEvent(oldCondition, newCondition), listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/FastList.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/FastList.java new file mode 100644 index 0000000000..427eba2726 --- /dev/null +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/FastList.java @@ -0,0 +1,371 @@ +/** + * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.net4j.util.collection; + +import org.eclipse.core.runtime.Assert; + +/** + * @author Eike Stepper + * @since 3.0 + */ +public abstract class FastList<E> +{ + protected E[] elements; + + public FastList() + { + } + + public boolean isEmpty() + { + return elements == null; + } + + public E[] get() + { + return elements; + } + + public synchronized void add(E element) + { + if (elements == null) + { + E[] array = newArray(1); + array[0] = element; + elements = array; + firstElementAdded(); + } + else + { + int length = elements.length; + E[] array = newArray(length + 1); + System.arraycopy(elements, 0, array, 0, length); + array[length] = element; + elements = array; + } + } + + public synchronized boolean remove(E element) + { + if (elements != null) + { + int length = elements.length; + if (length == 1) + { + if (elements[0] == element) + { + elements = null; + lastElementRemoved(); + return true; + } + } + else + { + for (int i = 0; i < length; i++) + { + E e = elements[i]; + if (e == element) + { + E[] array = newArray(length - 1); + + if (i > 0) + { + System.arraycopy(elements, 0, array, 0, i); + } + + if (i + 1 < length - 1) + { + System.arraycopy(elements, i + 1, array, i, length - 1 - i); + } + + elements = array; + return true; + } + } + } + } + + return false; + } + + protected void firstElementAdded() + { + } + + protected void lastElementRemoved() + { + } + + protected abstract E[] newArray(int length); + + /** + * @author Eike Stepper + */ + public static class TestList extends FastList<Integer> + { + public int added; + + public int removed; + + public TestList() + { + } + + public Integer[] reset() + { + added = 0; + removed = 0; + return elements; + } + + @Override + protected Integer[] newArray(int length) + { + return new Integer[length]; + } + + @Override + protected void firstElementAdded() + { + ++added; + } + + @Override + protected void lastElementRemoved() + { + ++removed; + } + } + + public static void main(String[] args) throws Exception + { + testAddFirst(); + testAddSecond(); + testRemoveHead(); + testRemoveMiddle(); + testRemoveTail(); + testRemoveLast(); + testNotFoundInMany(); + testNotFoundInOne(); + testNotFoundInEmpty(); + } + + public static void testAddFirst() throws Exception + { + TestList list = new TestList(); + list.add(5); + + Integer[] result = list.get(); + Assert.isTrue(result != null); + Assert.isTrue(result.length == 1); + Assert.isTrue(list.elements.length == 1); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 1); + Assert.isTrue(list.removed == 0); + } + + public static void testAddSecond() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + + Integer[] result = list.get(); + Assert.isTrue(result != null); + Assert.isTrue(result.length == 2); + Assert.isTrue(list.elements.length == 2); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 1); + Assert.isTrue(list.removed == 0); + } + + public static void testRemoveHead() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + list.add(2); + list.add(9); + list.add(1); + list.add(4); + list.add(8); + + Integer[] old = list.reset(); + boolean removed = list.remove(5); + + Integer[] result = list.get(); + Assert.isTrue(removed); + Assert.isTrue(result != null); + Assert.isTrue(result != old); + Assert.isTrue(result.length == 6); + Assert.isTrue(list.elements.length == 6); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + Assert.isTrue(result[0] == 7); + Assert.isTrue(result[1] == 2); + Assert.isTrue(result[2] == 9); + Assert.isTrue(result[3] == 1); + Assert.isTrue(result[4] == 4); + Assert.isTrue(result[5] == 8); + } + + public static void testRemoveMiddle() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + list.add(2); + list.add(9); + list.add(1); + list.add(4); + list.add(8); + + Integer[] old = list.reset(); + boolean removed = list.remove(9); + + Integer[] result = list.get(); + Assert.isTrue(removed); + Assert.isTrue(result != null); + Assert.isTrue(result != old); + Assert.isTrue(result.length == 6); + Assert.isTrue(list.elements.length == 6); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + Assert.isTrue(result[0] == 5); + Assert.isTrue(result[1] == 7); + Assert.isTrue(result[2] == 2); + Assert.isTrue(result[3] == 1); + Assert.isTrue(result[4] == 4); + Assert.isTrue(result[5] == 8); + } + + public static void testRemoveTail() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + list.add(2); + list.add(9); + list.add(1); + list.add(4); + list.add(8); + + Integer[] old = list.reset(); + boolean removed = list.remove(8); + + Integer[] result = list.get(); + Assert.isTrue(removed); + Assert.isTrue(result != old); + Assert.isTrue(result != null); + Assert.isTrue(result.length == 6); + Assert.isTrue(list.elements.length == 6); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + Assert.isTrue(result[0] == 5); + Assert.isTrue(result[1] == 7); + Assert.isTrue(result[2] == 2); + Assert.isTrue(result[3] == 9); + Assert.isTrue(result[4] == 1); + Assert.isTrue(result[5] == 4); + } + + public static void testRemoveLast() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + + Integer[] old = list.reset(); + boolean removed1 = list.remove(7); + boolean removed2 = list.remove(5); + + Integer[] result = list.get(); + Assert.isTrue(removed1); + Assert.isTrue(removed2); + Assert.isTrue(result != old); + Assert.isTrue(result == null); + Assert.isTrue(list.elements == null); + Assert.isTrue(list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 1); + } + + public static void testNotFoundInMany() throws Exception + { + TestList list = new TestList(); + list.add(5); + list.add(7); + list.add(2); + list.add(9); + list.add(1); + list.add(4); + list.add(8); + + Integer[] old = list.reset(); + boolean removed = list.remove(10); + + Integer[] result = list.get(); + Assert.isTrue(!removed); + Assert.isTrue(result != null); + Assert.isTrue(result == old); + Assert.isTrue(result.length == 7); + Assert.isTrue(list.elements.length == 7); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + Assert.isTrue(result[0] == 5); + Assert.isTrue(result[1] == 7); + Assert.isTrue(result[2] == 2); + Assert.isTrue(result[3] == 9); + Assert.isTrue(result[4] == 1); + Assert.isTrue(result[5] == 4); + Assert.isTrue(result[6] == 8); + } + + public static void testNotFoundInOne() throws Exception + { + TestList list = new TestList(); + list.add(5); + + Integer[] old = list.reset(); + boolean removed = list.remove(10); + + Integer[] result = list.get(); + Assert.isTrue(!removed); + Assert.isTrue(result != null); + Assert.isTrue(result == old); + Assert.isTrue(result.length == 1); + Assert.isTrue(list.elements.length == 1); + Assert.isTrue(!list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + Assert.isTrue(result[0] == 5); + } + + public static void testNotFoundInEmpty() throws Exception + { + TestList list = new TestList(); + + Integer[] old = list.reset(); + boolean removed = list.remove(10); + + Integer[] result = list.get(); + Assert.isTrue(!removed); + Assert.isTrue(result == null); + Assert.isTrue(result == old); + Assert.isTrue(list.isEmpty()); + Assert.isTrue(list.added == 0); + Assert.isTrue(list.removed == 0); + } +} diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/History.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/History.java index 46632166a4..11e775e61c 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/History.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/collection/History.java @@ -10,6 +10,7 @@ */ package org.eclipse.net4j.util.collection; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import java.util.ArrayList; @@ -199,12 +200,16 @@ public class History<T> extends Notifier implements IHistory<T> private void fireChangedEvent() { - fireEvent(new IHistoryChangeEvent() + IListener[] listeners = getListeners(); + if (listeners != null) { - public IHistory<?> getSource() + fireEvent(new IHistoryChangeEvent() { - return History.this; - } - }); + public IHistory<?> getSource() + { + return History.this; + } + }, listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/LifecycleEventConverter.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/LifecycleEventConverter.java index 12b89a498c..ebbfdead31 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/LifecycleEventConverter.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/LifecycleEventConverter.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -70,8 +70,11 @@ public class LifecycleEventConverter<E> implements IListener E element = (E)e.getSource(); if (element != null) { - IContainerEvent<E> event = createContainerEvent((IContainer<E>)owner, element, kind); - owner.fireEvent(event); + IListener[] listeners = owner.getListeners(); + if (listeners != null) + { + owner.fireEvent(createContainerEvent((IContainer<E>)owner, element, kind), listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/AbstractDelegator.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/AbstractDelegator.java index 6600948bf1..ff0608f24b 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/AbstractDelegator.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/AbstractDelegator.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -15,6 +15,7 @@ import org.eclipse.net4j.util.container.IContainer; import org.eclipse.net4j.util.container.IContainerDelta; import org.eclipse.net4j.util.container.SingleDeltaContainerEvent; import org.eclipse.net4j.util.container.IContainerDelta.Kind; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import java.util.Collection; @@ -31,13 +32,21 @@ public abstract class AbstractDelegator<E> extends Notifier implements IContaine protected void fireAddedEvent(E o) { - fireEvent(new SingleDeltaContainerEvent<E>(this, o, IContainerDelta.Kind.ADDED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<E>(this, o, IContainerDelta.Kind.ADDED), listeners); + } } @SuppressWarnings("unchecked") protected void fireRemovedEvent(Object o) { - fireEvent(new SingleDeltaContainerEvent<E>(this, (E)o, IContainerDelta.Kind.REMOVED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new SingleDeltaContainerEvent<E>(this, (E)o, IContainerDelta.Kind.REMOVED), listeners); + } } @SuppressWarnings("unchecked") @@ -59,7 +68,12 @@ public abstract class AbstractDelegator<E> extends Notifier implements IContaine return false; } - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } + return true; } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerBlockingQueue.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerBlockingQueue.java index dad262c922..45663d10ac 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerBlockingQueue.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerBlockingQueue.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.container.delegate; import org.eclipse.net4j.util.container.ContainerEvent; import org.eclipse.net4j.util.container.IContainerDelta; +import org.eclipse.net4j.util.event.IListener; import java.util.Collection; import java.util.concurrent.BlockingQueue; @@ -39,8 +40,12 @@ public class ContainerBlockingQueue<E> extends ContainerQueue<E> implements ICon public int drainTo(Collection<? super E> c) { int drainTo = getDelegate().drainTo(c); - ContainerEvent<E> event = createEvent(c, IContainerDelta.Kind.REMOVED); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(createEvent(c, IContainerDelta.Kind.REMOVED), listeners); + } + return drainTo; } @@ -51,7 +56,12 @@ public class ContainerBlockingQueue<E> extends ContainerQueue<E> implements ICon { int drainTo = getDelegate().drainTo(c, maxElements); ContainerEvent<E> event = createEvent(c, IContainerDelta.Kind.REMOVED); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } + return drainTo; } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerCollection.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerCollection.java index 28d44d2218..4771d0af40 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerCollection.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerCollection.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.container.delegate; import org.eclipse.net4j.util.container.ContainerEvent; import org.eclipse.net4j.util.container.IContainerDelta; +import org.eclipse.net4j.util.event.IListener; import java.util.Collection; import java.util.Iterator; @@ -80,7 +81,11 @@ public class ContainerCollection<E> extends AbstractDelegator<E> implements ICon { ContainerEvent<E> event = createEvent(getDelegate(), IContainerDelta.Kind.REMOVED); getDelegate().clear(); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerList.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerList.java index 49026d7663..db05faa9ce 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerList.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerList.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.container.delegate; import org.eclipse.net4j.util.container.ContainerEvent; import org.eclipse.net4j.util.container.IContainerDelta; +import org.eclipse.net4j.util.event.IListener; import java.util.Collection; import java.util.List; @@ -115,7 +116,12 @@ public class ContainerList<E> extends ContainerCollection<E> implements IContain ContainerEvent<E> event = new ContainerEvent<E>(ContainerList.this); event.addDelta(removed, IContainerDelta.Kind.REMOVED); event.addDelta(element, IContainerDelta.Kind.ADDED); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } + return removed; } @@ -162,7 +168,12 @@ public class ContainerList<E> extends ContainerCollection<E> implements IContain ContainerEvent<E> event = new ContainerEvent<E>(ContainerList.this); event.addDelta(last, IContainerDelta.Kind.REMOVED); event.addDelta(o, IContainerDelta.Kind.ADDED); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } + last = o; } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerMap.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerMap.java index a59bb950c4..2942aa8c48 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerMap.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/container/delegate/ContainerMap.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -13,6 +13,7 @@ package org.eclipse.net4j.util.container.delegate; import org.eclipse.net4j.util.collection.MapEntry; import org.eclipse.net4j.util.container.ContainerEvent; import org.eclipse.net4j.util.container.IContainerDelta; +import org.eclipse.net4j.util.event.IListener; import java.util.Collection; import java.util.Iterator; @@ -45,7 +46,11 @@ public class ContainerMap<K, V> extends AbstractDelegator<Map.Entry<K, V>> imple { ContainerEvent<Map.Entry<K, V>> event = createEvent(getDelegate().entrySet(), IContainerDelta.Kind.REMOVED); getDelegate().clear(); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } } } @@ -62,7 +67,12 @@ public class ContainerMap<K, V> extends AbstractDelegator<Map.Entry<K, V>> imple } event.addDelta(new ContainerMapEntry<K, V>(key, value), IContainerDelta.Kind.ADDED); - fireEvent(event); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(event, listeners); + } + return removed; } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/ExecutorServiceNotifier.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/ExecutorServiceNotifier.java index df9ee16569..445457a858 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/ExecutorServiceNotifier.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/ExecutorServiceNotifier.java @@ -25,7 +25,7 @@ public class ExecutorServiceNotifier extends Notifier } @Override - public ExecutorService getNotificationExecutorService() + public ExecutorService getNotificationService() { return notificationExecutorService; } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/Notifier.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/Notifier.java index bdecf32fd1..9731a613e5 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/Notifier.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/event/Notifier.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation */ @@ -12,20 +12,36 @@ package org.eclipse.net4j.util.event; import org.eclipse.net4j.internal.util.bundle.OM; import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.collection.FastList; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ExecutorService; /** * @author Eike Stepper + * @since 3.0 */ public class Notifier implements INotifier { - /** - * TODO Optimize by storing an array - */ - private List<IListener> listeners = new ArrayList<IListener>(0); + private FastList<IListener> listeners = new FastList<IListener>() + { + @Override + protected IListener[] newArray(int length) + { + return new IListener[length]; + } + + @Override + protected void firstElementAdded() + { + firstListenerAdded(); + } + + @Override + protected void lastElementRemoved() + { + lastListenerRemoved(); + } + }; public Notifier() { @@ -34,107 +50,89 @@ public class Notifier implements INotifier public void addListener(IListener listener) { CheckUtil.checkArg(listener, "listener"); //$NON-NLS-1$ - boolean wasNotEmpty; - boolean isNotEmpty; - synchronized (listeners) - { - wasNotEmpty = !listeners.isEmpty(); - listeners.add(listener); - isNotEmpty = !listeners.isEmpty(); - } - - if (wasNotEmpty ^ isNotEmpty) - { - listenersEmptyChanged(!isNotEmpty); - } + listeners.add(listener); } public void removeListener(IListener listener) { - boolean wasEmpty; - boolean isEmpty; - synchronized (listeners) - { - wasEmpty = listeners.isEmpty(); - listeners.remove(listener); - isEmpty = listeners.isEmpty(); - } - - if (wasEmpty ^ isEmpty) - { - listenersEmptyChanged(isEmpty); - } + CheckUtil.checkArg(listener, "listener"); //$NON-NLS-1$ + listeners.remove(listener); } public boolean hasListeners() { - return !listeners.isEmpty(); + return listeners.get() != null; } public IListener[] getListeners() { - synchronized (listeners) - { - return listeners.toArray(new IListener[listeners.size()]); - } + return listeners.get(); } public void fireEvent(IEvent event) { - Runnable runnable = new FireEventRunnable(getListeners(), event); - ExecutorService executorService = getNotificationExecutorService(); - if (executorService == null) - { - runnable.run(); - } - else + fireEvent(event, getListeners()); + } + + /** + * @since 3.0 + */ + public void fireEvent(final IEvent event, final IListener[] listeners) + { + if (listeners != null) { - executorService.execute(runnable); + ExecutorService notificationService = getNotificationService(); + if (notificationService != null) + { + notificationService.execute(new Runnable() + { + public void run() + { + fireEventSafe(event, listeners); + } + }); + } + else + { + fireEventSafe(event, listeners); + } } } /** - * @since 2.0 + * @since 3.0 */ - protected ExecutorService getNotificationExecutorService() + protected ExecutorService getNotificationService() { return null; } /** - * @since 2.0 + * @since 3.0 */ - protected void listenersEmptyChanged(boolean empty) + protected void firstListenerAdded() { } /** - * @author Eike Stepper + * @since 3.0 */ - private static final class FireEventRunnable implements Runnable + protected void lastListenerRemoved() { - private IListener[] listeners; - - private IEvent event; - - public FireEventRunnable(IListener[] listeners, IEvent event) - { - this.listeners = listeners; - this.event = event; - } + } - public void run() + private static void fireEventSafe(IEvent event, IListener[] listeners) + { + for (int i = 0; i < listeners.length; i++) { - for (IListener listener : listeners) + try { - try - { - listener.notifyEvent(event); - } - catch (Exception ex) - { - OM.LOG.error(ex); - } + IListener listener = listeners[i]; + listener.notifyEvent(event); + } + catch (Exception ex) + { + OM.LOG.error(ex); } } } diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/fsm/FiniteStateMachine.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/fsm/FiniteStateMachine.java index 254c26eab2..f592b39e21 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/fsm/FiniteStateMachine.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/fsm/FiniteStateMachine.java @@ -12,6 +12,7 @@ package org.eclipse.net4j.util.fsm; import org.eclipse.net4j.internal.util.bundle.OM; import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.INotifier; import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -202,9 +203,10 @@ public abstract class FiniteStateMachine<STATE extends Enum<?>, EVENT extends En if (oldState != state) { setState(subject, state); - if (hasListeners()) + IListener[] listeners = getListeners(); + if (listeners != null) { - fireEvent(new StateChangedEvent(subject, oldState, state)); + fireEvent(new StateChangedEvent(subject, oldState, state), listeners); } return oldState; diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/lifecycle/Lifecycle.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/lifecycle/Lifecycle.java index e821417a12..a59e8a6cc4 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/lifecycle/Lifecycle.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/lifecycle/Lifecycle.java @@ -14,6 +14,7 @@ import org.eclipse.net4j.internal.util.bundle.OM; import org.eclipse.net4j.util.CheckUtil; import org.eclipse.net4j.util.ReflectUtil; import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.event.Notifier; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -59,7 +60,11 @@ public class Lifecycle extends Notifier implements ILifecycle lock(); lifecycleState = LifecycleState.ACTIVATING; - fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ABOUT_TO_ACTIVATE)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ABOUT_TO_ACTIVATE), listeners); + } doBeforeActivate(); doActivate(); @@ -108,12 +113,20 @@ public class Lifecycle extends Notifier implements ILifecycle lock(); lifecycleState = LifecycleState.DEACTIVATING; doBeforeDeactivate(); - fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ABOUT_TO_DEACTIVATE)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ABOUT_TO_DEACTIVATE), listeners); + } doDeactivate(); lifecycleState = LifecycleState.INACTIVE; unlock(); - fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.DEACTIVATED)); + if (listeners != null) + { + fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.DEACTIVATED), listeners); + } + return null; } @@ -211,7 +224,11 @@ public class Lifecycle extends Notifier implements ILifecycle { lifecycleState = LifecycleState.ACTIVE; unlock(); - fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ACTIVATED)); + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new LifecycleEvent(this, ILifecycleEvent.Kind.ACTIVATED), listeners); + } } else { diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java index 9a840d0992..f6b549f332 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/spi/net4j/Channel.java @@ -19,6 +19,7 @@ import org.eclipse.net4j.util.concurrent.NonBlockingIntCounter; import org.eclipse.net4j.util.concurrent.QueueWorkerWorkSerializer; import org.eclipse.net4j.util.concurrent.SynchronousWorkSerializer; import org.eclipse.net4j.util.event.Event; +import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.log.OMLogger; @@ -404,18 +405,20 @@ public class Channel extends Lifecycle implements InternalChannel private void added() { int queueSize = size.increment(); - if (hasListeners()) + IListener[] listeners = getListeners(); + if (listeners != null) { - fireEvent(new SendQueueEventImpl(Type.ENQUEUED, queueSize)); + fireEvent(new SendQueueEventImpl(Type.ENQUEUED, queueSize), listeners); } } private void removed() { int queueSize = size.decrement(); - if (hasListeners()) + IListener[] listeners = getListeners(); + if (listeners != null) { - fireEvent(new SendQueueEventImpl(Type.DEQUEUED, queueSize)); + fireEvent(new SendQueueEventImpl(Type.DEQUEUED, queueSize), listeners); } } } |