/** * Copyright (c) 2013-2016 Angelo ZERR. * 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: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.eclipse.ide.internal.core; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionDelta; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IRegistryChangeEvent; import org.eclipse.core.runtime.IRegistryChangeListener; import org.eclipse.core.runtime.Platform; import tern.eclipse.ide.core.ITernProjectLifecycleListener; import tern.eclipse.ide.core.ITernProjectLifecycleListener.LifecycleEventType; import tern.eclipse.ide.core.ITernProjectLifecycleListenerProvider; import tern.eclipse.ide.core.ITernProjectLifecycleManager; import tern.eclipse.ide.core.TernCorePlugin; import tern.eclipse.ide.internal.core.resources.IDETernProject; /** * Tern project lifecycle manager implementation. * */ public class TernProjectLifecycleManager implements ITernProjectLifecycleManager, IRegistryChangeListener { private static final String EXTENSION_TERN_PROJECT_LIFECYCLE_LISTENERS = "ternProjectLifecycleListeners"; private static final TernProjectLifecycleManager INSTANCE = new TernProjectLifecycleManager(); public static TernProjectLifecycleManager getManager() { return INSTANCE; } private List<ITernProjectLifecycleListener> listeners; private boolean registryListenerIntialized; public TernProjectLifecycleManager() { this.listeners = null; this.registryListenerIntialized = false; } /** * Load the tern server types. */ private synchronized void loadListeners() { if (listeners != null) return; Trace.trace(Trace.EXTENSION_POINT, "->- Loading .ternProjectLifecycleListeners extension point ->-"); IExtensionRegistry registry = Platform.getExtensionRegistry(); IConfigurationElement[] cf = registry.getConfigurationElementsFor( TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_PROJECT_LIFECYCLE_LISTENERS); List<ITernProjectLifecycleListener> list = new ArrayList<ITernProjectLifecycleListener>( cf.length); addListeners(cf, list); addRegistryListenerIfNeeded(); listeners = list; Trace.trace(Trace.EXTENSION_POINT, "-<- Done loading .ternProjectLifecycleListeners extension point -<-"); } private void addRegistryListenerIfNeeded() { if (registryListenerIntialized) return; IExtensionRegistry registry = Platform.getExtensionRegistry(); registry.addRegistryChangeListener(this, TernCorePlugin.PLUGIN_ID); registryListenerIntialized = true; } @Override public void registryChanged(final IRegistryChangeEvent event) { IExtensionDelta[] deltas = event.getExtensionDeltas( TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_PROJECT_LIFECYCLE_LISTENERS); if (deltas != null) { for (IExtensionDelta delta : deltas) handleDelta(delta); } } protected void handleDelta(IExtensionDelta delta) { IConfigurationElement[] cf = delta.getExtension() .getConfigurationElements(); if (delta.getKind() == IExtensionDelta.ADDED) { List<ITernProjectLifecycleListener> list = new ArrayList<ITernProjectLifecycleListener>(); addListeners(cf, list); this.listeners = list; } } private void addListeners(IConfigurationElement[] cf, List<ITernProjectLifecycleListener> list) { ITernProjectLifecycleListener listener = null; for (IConfigurationElement ce : cf) { try { listener = ((ITernProjectLifecycleListenerProvider) ce .createExecutableExtension("class")).getListener(); list.add(listener); } catch (CoreException e) { Trace.trace(Trace.SEVERE, "Error while adding tern project lifecycle listeners", e); } } } @Override public void addTernProjectLifeCycleListener( ITernProjectLifecycleListener listener) { loadListeners(); synchronized (listener) { listeners.add(listener); } } @Override public void removeTernProjectLifeCycleListener( ITernProjectLifecycleListener listener) { loadListeners(); synchronized (listeners) { listeners.remove(listener); } } /** * Fire listener. * * @param project * @param state */ public void fireTernProjectLifeCycleListenerChanged(IDETernProject project, LifecycleEventType state) { loadListeners(); synchronized (listeners) { for (ITernProjectLifecycleListener listener : listeners) { listener.handleEvent(project, state); } } } }