blob: 044e3ee21663c7afcd28db70a817086a335bfbca [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 xored software, Inc. 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:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.ui.environment;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.dltk.core.environment.EnvironmentChangedListener;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IEnvironmentChangedListener;
import org.eclipse.swt.widgets.Display;
import org.omg.CORBA.Environment;
/**
* This class collects {@link IEnvironment}s from {@link EnvironmentManager} and
* fires notification on UI thread if environments are changed.
*
* At the moment if works only for initial retrieve of environments. It requires
* some time to initialize RSE, so to prevent delays and possible deadlocks we
* should not wait until RSE initialization is completed, this class is used to
* fire the event after RSE initialization is completed.
*/
public class EnvironmentContainer {
private boolean initialized = false;
private final Map<String, IEnvironment> environments = new HashMap<>();
private List<IEnvironment> environmentList = Collections.emptyList();
private IEnvironmentChangedListener listener = null;
/**
* Initialize the environments maintained by this object. The subsequent
* calls of this method are ignored.
*/
public void initialize() {
if (!initialized) {
initialized = true;
synchronized (environments) {
initEnvironments();
installChangeListener();
}
}
}
private static class EnvironmentComparator
implements Comparator<IEnvironment> {
@Override
public int compare(final IEnvironment e1, final IEnvironment e2) {
if (e1.isLocal() != e2.isLocal()) {
return e1.isLocal() ? -1 : +1;
}
return e1.getName().compareToIgnoreCase(e2.getName());
}
}
private void initEnvironments() {
environments.clear();
final IEnvironment[] envs = EnvironmentManager.getEnvironments();
Arrays.sort(envs, new EnvironmentComparator());
environmentList = Arrays.asList(envs);
for (int i = 0; i < envs.length; ++i) {
final IEnvironment environment = envs[i];
environments.put(environment.getId(), environment);
}
}
private void installChangeListener() {
if (listener == null) {
listener = new EnvironmentChangedListener() {
@Override
public void environmentsModified() {
synchronized (environments) {
initEnvironments();
}
Display.getDefault()
.asyncExec(() -> fireChangeNotifications());
}
};
EnvironmentManager.addEnvironmentChangedListener(listener);
}
}
private void uninstallChangeListener() {
if (listener != null) {
EnvironmentManager.removeEnvironmentChangedListener(listener);
listener = null;
}
}
/**
* Returns the list of {@link IEnvironment}s
*
* @return
*/
public List<IEnvironment> getEnvironments() {
return environmentList;
}
/**
* Returns the identifiers of {@link Environment}s managed by this object
*
* @return
*/
public String[] getEnvironmentIds() {
final List<IEnvironment> list = environmentList;
final String[] ids = new String[list.size()];
for (int i = 0; i < ids.length; ++i) {
ids[i] = list.get(i).getId();
}
return ids;
}
/**
* @param environmentId
* @return
*/
public IEnvironment get(String environmentId) {
return environments.get(environmentId);
}
/**
* Returns the name of the environment with the specified id
*
* @param environmentId
* @return
*/
public String getName(String environmentId) {
final IEnvironment environment = environments.get(environmentId);
if (environment != null) {
return environment.getName();
} else {
return "(" + environmentId + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* Release resources occupied by this object
*/
public void dispose() {
uninstallChangeListener();
changeListeners.clear();
environments.clear();
environmentList = null;
initialized = false;
}
private final ListenerList<Runnable> changeListeners = new ListenerList<>();
/**
* Registers the specified change listener to be called when available
* environments are changed. Specified event handler is called on the UI
* thread.
*
* @param runnable
*/
public void addChangeListener(Runnable runnable) {
changeListeners.add(runnable);
}
protected void fireChangeNotifications() {
for (Runnable listener : changeListeners) {
listener.run();
}
}
}