/*
* Carrot2 project.
*
* Copyright (C) 2002-2016, Dawid Weiss, Stanisław Osiński.
* All rights reserved.
*
* Refer to the full license file "carrot2.LICENSE"
* in the root folder of the repository checkout or at:
* http://www.carrot2.org/carrot2.LICENSE
*/
package org.carrot2.workbench.core.helpers;
import java.util.ArrayList;
import java.util.HashMap;
import org.carrot2.workbench.editors.IAttributeEventProvider;
import org.carrot2.workbench.editors.IAttributeListener;
import org.eclipse.core.commands.operations.OperationStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.swt.graphics.Resource;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.carrot2.shaded.guava.common.collect.Lists;
/**
* A collection of disposable resources (of multiple types that do not share a common
* interface). The dispose bin can also register various kinds of listeners and unregister
* them automatically at {@link #dispose()}.
*/
public final class DisposeBin
{
private static abstract class Disposer<T>
{
protected final T t;
Disposer(T t)
{
this.t = t;
}
public abstract void dispose();
};
private static class ResourceDisposer extends Disposer<Resource>
{
public ResourceDisposer(Resource r)
{
super(r);
}
public void dispose()
{
t.dispose();
}
};
private static class FormToolkitDisposer extends Disposer<FormToolkit>
{
public FormToolkitDisposer(FormToolkit t)
{
super(t);
}
public void dispose()
{
t.dispose();
}
};
private static class WidgetDisposer extends Disposer<Widget>
{
public WidgetDisposer(Widget t)
{
super(t);
}
public void dispose()
{
t.dispose();
}
};
private static class ActionDisposer extends Disposer<IWorkbenchAction>
{
public ActionDisposer(IWorkbenchAction t)
{
super(t);
}
public void dispose()
{
t.dispose();
}
};
private static class ListenerPair
{
public final Object registrar;
public final Object listener;
public ListenerPair(Object registrar, Object listener)
{
this.registrar = registrar;
this.listener = listener;
}
}
/*
*
*/
private final HashMap<Object, Disposer<?>> resources = new HashMap<Object, Disposer<?>>();
/*
*
*/
private final ArrayList<ListenerPair> listeners = Lists.newArrayList();
/*
*
*/
private final Plugin plugin;
public DisposeBin()
{
this(null);
}
public DisposeBin(Plugin plugin)
{
this.plugin = plugin;
}
public void add(Resource... resources)
{
for (Resource r : resources)
{
this.resources.put(r, new ResourceDisposer(r));
}
}
public void add(FormToolkit toolkit)
{
this.resources.put(toolkit, new FormToolkitDisposer(toolkit));
}
public void add(Widget w)
{
this.resources.put(w, new WidgetDisposer(w));
}
public void add(IWorkbenchAction action)
{
this.resources.put(action, new ActionDisposer(action));
}
public void dispose()
{
for (Disposer<?> disposer : resources.values())
{
try
{
disposer.dispose();
}
catch (Throwable e)
{
if (plugin != null)
{
IStatus status = new OperationStatus(IStatus.ERROR, plugin
.getBundle().getSymbolicName(), -1, "Resource disposal failed.",
e);
plugin.getLog().log(status);
}
}
}
resources.clear();
for (ListenerPair p : listeners)
{
try
{
if (p.registrar instanceof IPreferenceStore)
{
((IPreferenceStore) p.registrar)
.removePropertyChangeListener((IPropertyChangeListener) p.listener);
}
else if (p.registrar instanceof IAttributeEventProvider)
{
((IAttributeEventProvider) p.registrar)
.removeAttributeListener((IAttributeListener) p.listener);
}
else if (p.registrar instanceof IPostSelectionProvider)
{
((IPostSelectionProvider) p.registrar)
.removePostSelectionChangedListener((ISelectionChangedListener) p.listener);
}
else
{
throw new RuntimeException("Unhandled registrar: " + p.registrar);
}
}
catch (Throwable t)
{
if (plugin != null)
{
IStatus status = new OperationStatus(IStatus.ERROR, plugin
.getBundle().getSymbolicName(), -1, "Listener disposal failed.",
t);
plugin.getLog().log(status);
}
}
}
listeners.clear();
}
/*
*
*/
public void registerPropertyChangeListener(IPreferenceStore provider,
IPropertyChangeListener l)
{
provider.addPropertyChangeListener(l);
listeners.add(new ListenerPair(provider, l));
}
/*
*
*/
public void registerAttributeChangeListener(IAttributeEventProvider provider,
IAttributeListener l)
{
provider.addAttributeListener(l);
listeners.add(new ListenerPair(provider, l));
}
/*
*
*/
public void registerPostSelectionChangedListener(IPostSelectionProvider searchEditor,
ISelectionChangedListener l)
{
searchEditor.addPostSelectionChangedListener(l);
}
}