/**
* 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.Iterator;
import java.util.List;
import org.eclipse.core.resources.IProject;
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.ITernServerPreferencesListener;
import tern.eclipse.ide.core.ITernServerType;
import tern.eclipse.ide.core.ITernServerTypeManager;
import tern.eclipse.ide.core.TernCorePlugin;
/**
* Manager of tern server type loaded by the extension point "ternServerTypes"
*
*/
public class TernServerTypeManager implements ITernServerTypeManager,
IRegistryChangeListener {
private static final String EXTENSION_TERN_SERVER_TYPES = "ternServerTypes";
private static final TernServerTypeManager INSTANCE = new TernServerTypeManager();
// cached copy of all tern server type
private List<ITernServerType> ternServerTypes;
private boolean registryListenerIntialized;
private final List<ITernServerPreferencesListener> listeners;
public static TernServerTypeManager getManager() {
return INSTANCE;
}
public TernServerTypeManager() {
this.registryListenerIntialized = false;
this.listeners = new ArrayList<ITernServerPreferencesListener>();
}
@Override
public void registryChanged(final IRegistryChangeEvent event) {
IExtensionDelta[] deltas = event.getExtensionDeltas(
TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_SERVER_TYPES);
if (deltas != null) {
for (IExtensionDelta delta : deltas)
handleTernServerTypeDelta(delta);
}
}
@Override
public ITernServerType[] getTernServerTypes() {
if (ternServerTypes == null)
loadTernServerTypes();
ITernServerType[] st = new ITernServerType[ternServerTypes.size()];
ternServerTypes.toArray(st);
return st;
}
@Override
public ITernServerType findTernServerType(String id) {
if (id == null)
throw new IllegalArgumentException();
if (ternServerTypes == null)
loadTernServerTypes();
Iterator<ITernServerType> iterator = ternServerTypes.iterator();
while (iterator.hasNext()) {
ITernServerType serverType = (ITernServerType) iterator.next();
if (id.equals(serverType.getId()))
return serverType;
}
return null;
}
/**
* Load the tern server types.
*/
private synchronized void loadTernServerTypes() {
if (ternServerTypes != null)
return;
Trace.trace(Trace.EXTENSION_POINT,
"->- Loading .ternServerTypes extension point ->-");
IExtensionRegistry registry = Platform.getExtensionRegistry();
IConfigurationElement[] cf = registry.getConfigurationElementsFor(
TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_SERVER_TYPES);
List<ITernServerType> list = new ArrayList<ITernServerType>(cf.length);
addTernServerTypes(cf, list);
addRegistryListenerIfNeeded();
ternServerTypes = list;
Trace.trace(Trace.EXTENSION_POINT,
"-<- Done loading .ternServerTypes extension point -<-");
}
/**
* Load the tern server types.
*/
private synchronized void addTernServerTypes(IConfigurationElement[] cf,
List<ITernServerType> list) {
for (IConfigurationElement ce : cf) {
try {
list.add(new TernServerType(ce));
Trace.trace(Trace.EXTENSION_POINT,
" Loaded serverType: " + ce.getAttribute("id"));
} catch (Throwable t) {
Trace.trace(
Trace.SEVERE,
" Could not load serverType: " + ce.getAttribute("id"),
t);
}
}
}
protected void handleTernServerTypeDelta(IExtensionDelta delta) {
if (ternServerTypes == null) // not loaded yet
return;
IConfigurationElement[] cf = delta.getExtension()
.getConfigurationElements();
List<ITernServerType> list = new ArrayList<ITernServerType>(
ternServerTypes);
if (delta.getKind() == IExtensionDelta.ADDED) {
addTernServerTypes(cf, list);
} else {
int size = list.size();
TernServerType[] st = new TernServerType[size];
list.toArray(st);
int size2 = cf.length;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size2; j++) {
if (st[i].getId().equals(cf[j].getAttribute("id"))) {
st[i].dispose();
list.remove(st[i]);
}
}
}
}
ternServerTypes = list;
}
private void addRegistryListenerIfNeeded() {
if (registryListenerIntialized)
return;
IExtensionRegistry registry = Platform.getExtensionRegistry();
registry.addRegistryChangeListener(this, TernCorePlugin.PLUGIN_ID);
registryListenerIntialized = true;
}
public void initialize() {
}
public void destroy() {
if (ternServerTypes == null) // not loaded yet
return;
List<ITernServerType> types = new ArrayList<ITernServerType>(
ternServerTypes);
for (ITernServerType type : types) {
type.dispose();
ternServerTypes.remove(type);
}
Platform.getExtensionRegistry().removeRegistryChangeListener(this);
}
@Override
public void refresh() {
if (ternServerTypes == null) // not loaded yet
return;
for (ITernServerType type : ternServerTypes) {
type.dispose();
}
}
@Override
public void addServerPreferencesListener(
ITernServerPreferencesListener listener) {
synchronized (listener) {
listeners.add(listener);
}
}
@Override
public void removeServerPreferencesListener(
ITernServerPreferencesListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
@Override
public void fireServerPreferencesChanged(IProject project) {
synchronized (listeners) {
for (ITernServerPreferencesListener listener : listeners) {
listener.serverPreferencesChanged(project);
}
}
}
}