| /******************************************************************************* |
| * Copyright (c) 2009, 2018 xored software, Inc. and others. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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(); |
| } |
| 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(); |
| } |
| } |
| |
| } |