1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
15 * @author Toni Kalajainen
17 package org.simantics.utils.datastructures.disposable;
19 import java.lang.reflect.Method;
21 import org.simantics.utils.threads.IThreadWorkQueue;
22 import org.simantics.utils.threads.SyncListenerList;
25 * Base implementation of IDisposable. The subclass must implement doDispose()
26 * method. It invoked at once in first dispose call. Subsequent calls to dispose
27 * throws an AssertionError.
29 * assertNotDisposed() ensures that the object has not beed disposed. If so,
30 * AssertionError is thrown. assertNotDisposed() should be installed in all
31 * public methods of subclass.
33 * Object is disposed in finalize, if dispose has not been invoked explicitely.
35 public abstract class AbstractDisposable implements IDisposable {
37 SyncListenerList<IDisposeListener> disposeListeners = null;
39 private DisposeState disposeStatus = DisposeState.Alive;
41 protected void assertNotDisposed() {
43 throw new AssertionError(this + " is disposed.");
47 public DisposeState getDisposeState() {
51 public boolean isDisposed() {
52 return disposeStatus == DisposeState.Disposed;
55 public boolean isAlive() {
56 return disposeStatus == DisposeState.Alive;
60 public void dispose() {
63 if (disposeStatus == DisposeState.Disposing)
66 disposeStatus = DisposeState.Disposing;
75 disposeStatus = DisposeState.Disposed;
81 * Disposes if not disposed
83 public void safeDispose() {
86 if (disposeStatus != DisposeState.Alive)
88 disposeStatus = DisposeState.Disposing;
97 disposeStatus = DisposeState.Disposed;
103 * Do dispose procedures. This method is invoked at most once.
105 protected abstract void doDispose();
107 protected boolean hasDisposeListeners() {
108 return disposeListeners!=null && !disposeListeners.isEmpty();
111 private final static Method onDisposed = SyncListenerList.getMethod(IDisposeListener.class, "onDisposed");
113 private void fireDisposed() {
114 if (disposeListeners==null) return;
115 disposeListeners.fireEventSync(onDisposed, this);
118 @SuppressWarnings("unused")
119 private void fireDisposedAsync() {
120 if (disposeListeners==null) return;
121 disposeListeners.fireEventAsync(onDisposed, this);
125 public void addDisposeListener(IDisposeListener listener) {
126 lazyGetListenerList().add(listener);
130 public void addDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {
131 lazyGetListenerList().add(thread, listener);
135 public void removeDisposeListener(IDisposeListener listener) {
136 if (disposeListeners==null) return;
137 disposeListeners.remove(listener);
141 public void removeDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) {
142 if (disposeListeners==null) return;
143 disposeListeners.remove(thread, listener);
146 private synchronized SyncListenerList<IDisposeListener> lazyGetListenerList()
148 if (disposeListeners==null)
149 disposeListeners = new SyncListenerList<IDisposeListener>(IDisposeListener.class);
150 return disposeListeners;
155 protected void finalize() throws Throwable {