blob: 8d884e1c4ad4bd3dd2e452756a7a160434373b77 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2005, 2014 IBM Corporation, Ericsson
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM - Initial API and implementation
* Bernd Hufmann - Updated for TMF
**********************************************************************/
package org.eclipse.tracecompass.tmf.ui.views.uml2sd.load;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDView;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* Manager class for the UML2SD extension point.
*
* @version 1.0
* @author sveyrier
* @author Bernd Hufmann
*/
public class LoadersManager {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
/** Namespace of the extension point */
private static final String EXT_NAMESPACE = "org.eclipse.linuxtools.tmf.ui"; //$NON-NLS-1$
/** The loader tag for the extension point */
private static final String LOADER_TAG = "uml2SDLoader"; //$NON-NLS-1$
/** The loader prefix */
private static final String LOADER_PREFIX = LOADER_TAG + "."; //$NON-NLS-1$
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
/**
* The LoadersManager singleton instance.
*/
private static LoadersManager fLoadersManager;
/**
* Map for caching information (view ID to loader class)
*/
private Map<String, IUml2SDLoader> fViewLoaderMap = new HashMap<>();
/**
* Map for caching information (view ID to list of configuration elements)
*/
private Map<String, ArrayList<IConfigurationElement>> fViewLoadersList = new HashMap<>();
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* This should not be used by the clients
*/
protected LoadersManager() {
}
// ------------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------------
/**
* A static method to get the manager instance.
*
* @return the manager instance
*/
public static synchronized LoadersManager getInstance() {
if (fLoadersManager == null) {
fLoadersManager = new LoadersManager();
}
return fLoadersManager;
}
/**
* Creates a loader instance and associate it to the view. It requires
* that the loader-view-association was created by an eclipse extension.
*
* @param className The name of the class to create an instance from
* @param view The UML2 Sequence Diagram view instance
* @return The created loader
*/
public IUml2SDLoader createLoader(String className, SDView view) {
// Safety check
if (view == null) {
return null;
}
String viewId = view.getViewSite().getId();
// Get loaders from all extensions for given view
List<IConfigurationElement> loaderElements = getLoaderConfigurationElements(viewId);
IConfigurationElement ce = getLoaderConfigurationElement(className, loaderElements);
if (ce != null) {
// Assign a loader instance to this view
createLoaderForView(viewId, ce);
IUml2SDLoader loader = fViewLoaderMap.get(viewId);
if (loader != null) {
loader.setViewer(view);
return loader;
}
}
return null;
}
/**
* Sets the loader to null for this view, a kind of clean-up while disposing.
*
* @param viewId the id of the view
*/
public void resetLoader(String viewId) {
IUml2SDLoader loader = fViewLoaderMap.get(viewId);
if (loader != null) {
loader.dispose();
}
fViewLoaderMap.put(viewId, null);
}
/**
* Returns the loader in use in given Sequence Diagram View
*
* @param viewId The Sequence Diagram viewId.
* @return the current loader if any - null otherwise
*/
public IUml2SDLoader getCurrentLoader(String viewId) {
return getCurrentLoader(viewId, null);
}
/**
* Returns the loader in use in this Sequence Diagram View
*
* @param viewId The Sequence Diagram viewId
* @param view The Sequence Diagram view (if known). Use null to reference the primary SD View.
* @return the current loader if any - null otherwise
*/
public IUml2SDLoader getCurrentLoader(String viewId, SDView view) {
if (viewId == null) {
return null;
}
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
// During Eclipse shutdown the active workbench window is null
if (window == null) {
return null;
}
IWorkbenchPage persp = window.getActivePage();
SDView sdView = view;
try {
// Search the view corresponding to the viewId
if (sdView == null) {
IViewReference viewref = persp.findViewReference(viewId);
if (viewref != null) {
sdView = (SDView) viewref.getView(false);
}
if (sdView == null) {
// no corresponding view exists -> return null for the loader
return null;
}
}
// Return the loader corresponding to that view (if any)
IUml2SDLoader loader = fViewLoaderMap.get(viewId);
if (loader == null) {
createLastLoaderIfAny(viewId);
loader = fViewLoaderMap.get(viewId);
}
return loader;
} catch (Exception e) {
Activator.getDefault().logError("Error getting loader class", e); //$NON-NLS-1$
}
return null;
}
/**
* Returns the loader class name that have been saved last time.
*
* @param viewId The view this loader belongs to
* @return the class name of the saved loader
*/
public String getSavedLoader(String viewId) {
IPreferenceStore p = Activator.getDefault().getPreferenceStore();
return p.getString(LOADER_PREFIX + viewId);
}
/**
* Saves the last loader in order to reload it on next session.
*
* @param id
* Standalone ID of the loader
* @param id2
* Suffix ID of the loader
*/
public void saveLastLoader(String id, String id2) {
IPreferenceStore p = Activator.getDefault().getPreferenceStore();
p.setValue(LOADER_PREFIX + id2, id);
}
/**
* Changes the current unique loader to the given secondary viewId.
*
* @param loader The current loader
* @param id the view secondary id or null
*/
private void setCurrentLoader(IUml2SDLoader loader, String id) {
if (id == null) {
return;
}
// Get the loader in use
IUml2SDLoader currentLoader = fViewLoaderMap.get(id);
if ((currentLoader != null) && (currentLoader != loader)) {
if (loader != null) {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
// During Eclipse shutdown the active workbench window is null
if (window == null) {
return;
}
IWorkbenchPage persp = window.getActivePage();
try {
// Search view corresponding to the viewId
SDView sdview = null;
IViewReference viewref = persp.findViewReference(id);
if (viewref != null) {
sdview = (SDView) viewref.getView(false);
}
// Make everything clean for the new loader
if (sdview != null) {
sdview.resetProviders();
}
} catch (Exception e) {
Activator.getDefault().logError("Error setting current loader class", e); //$NON-NLS-1$
}
}
// The old loader is going to be kicked
currentLoader.dispose();
}
// Replace the current loader by the new one in the map
fViewLoaderMap.put(id, loader);
// Store this loader in the preferences to be able to restore it when the workbench will be re-launched
if (loader != null) {
saveLastLoader(loader.getClass().getName(), id);
}
}
/**
* Creates the last loader and saves it. If not last is not available, it creates
* and saves the default loader, else no loader is created.
*
* @param viewId The view ID.
*/
private void createLastLoaderIfAny(String viewId) {
// Get saved loader from preferences
String loaderName = getSavedLoader(viewId);
// Get loaders from all extensions for given view
List<IConfigurationElement> loaderElements = getLoaderConfigurationElements(viewId);
IConfigurationElement ce = getLoaderConfigurationElement(loaderName, loaderElements);
if (ce == null) {
ce = getDefaultLoader(loaderElements);
}
if (ce != null) {
createLoaderForView(viewId, ce);
}
}
/**
* Gets a list of loader configuration elements from the extension point registry for a given view.
* @param viewId The view ID
* @return List of extension point configuration elements.
*/
private List<IConfigurationElement> getLoaderConfigurationElements(String viewId) {
List<IConfigurationElement> list = fViewLoadersList.get(viewId);
if (list != null) {
return list;
}
ArrayList<IConfigurationElement> ret = new ArrayList<>();
IExtensionPoint iep = Platform.getExtensionRegistry().getExtensionPoint(EXT_NAMESPACE, LOADER_TAG);
if (iep == null) {
return ret;
}
IExtension[] ie = iep.getExtensions();
if (ie == null) {
return ret;
}
for (int i = 0; i < ie.length; i++) {
IConfigurationElement c[] = ie[i].getConfigurationElements();
for (int j = 0; j < c.length; j++) {
if (viewId.equals(c[j].getAttribute("view"))) { //$NON-NLS-1$
ret.add(c[j]);
}
}
}
fViewLoadersList.put(viewId, ret);
return ret;
}
/**
* Returns the loader configuration element for given loader class name and for the given
* list of configuration elements, if available else null.
*
* @param loaderClassName The loader class name.
* @param loaderElements The list of loader configuration elements
* @return Extension point configuration element
*/
private static IConfigurationElement getLoaderConfigurationElement(
String loaderClassName, List<IConfigurationElement> loaderElements) {
if (loaderClassName != null && loaderClassName.length() > 0) {
// Find configuration element corresponding to the saved loader
for (Iterator<IConfigurationElement> i = loaderElements.iterator(); i.hasNext();) {
IConfigurationElement ce = i.next();
if (ce.getAttribute("class").equals(loaderClassName)) { //$NON-NLS-1$
return ce;
}
}
}
return null;
}
/**
* Returns the loader configuration element for the given list of configuration elements, if available else null.
* Note that if multiple default loaders are defined it selects the first one
* @param loaderElements The list of loader configuration elements
* @return The default extension point configuration element.
*/
private static IConfigurationElement getDefaultLoader(
List<IConfigurationElement> loaderElements) {
// Look for a default loader
for (Iterator<IConfigurationElement> i = loaderElements.iterator(); i.hasNext();) {
IConfigurationElement ce = i.next();
if (Boolean.valueOf(ce.getAttribute("default")).booleanValue()) { //$NON-NLS-1$
return ce;
}
}
return null;
}
/**
* Creates an instance of the loader class for a given extension point configuration element and
* also sets it as current loader for the given view.
*
* @param viewId The view ID.
* @param ce The extension point configuration element
*/
private void createLoaderForView(String viewId, IConfigurationElement ce) {
try {
Object obj = ce.createExecutableExtension("class"); //$NON-NLS-1$
IUml2SDLoader l = (IUml2SDLoader) obj;
if (viewId != null) {
setCurrentLoader(l, viewId);
}
} catch (CoreException e4) {
Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e4); //$NON-NLS-1$
} catch (Exception e5) {
Activator.getDefault().logError("Error 'uml2SDLoader' Extension point", e5); //$NON-NLS-1$
}
}
}