/**
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright (C) 2007 Ronny Brandt (Ronny_Brandt@web.de). *
* All rights reserved. *
* *
* This work was done as a project at the Chair for Software Technology, *
* Dresden University Of Technology, Germany (http://st.inf.tu-dresden.de). *
* It is understood that any modification not identified as such is not *
* covered by the preceding statement. *
* *
* This work is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Library General Public License as published *
* by the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This work is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public *
* License for more details. *
* *
* You should have received a copy of the GNU Library General Public License *
* along with this library; if not, you can view it online at *
* http://www.fsf.org/licensing/licenses/gpl.html. *
* *
* To submit a bug report, send a comment, or get the latest news on this *
* project, please visit the website: http://dresden-ocl.sourceforge.net. *
* For more information on OCL and related projects visit the OCL Portal: *
* http://st.inf.tu-dresden.de/ocl *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
package org.dresdenocl.modelbus.ui.internal.views;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;
import org.dresdenocl.model.IModel;
import org.dresdenocl.model.IModelRegistry;
import org.dresdenocl.model.event.IModelRegistryListener;
import org.dresdenocl.model.event.ModelRegistryEvent;
import org.dresdenocl.modelbus.IModelBusConstants;
import org.dresdenocl.modelbus.ModelBusPlugin;
import org.dresdenocl.modelbus.ui.ModelBusUIPlugin;
import org.dresdenocl.modelbus.ui.internal.views.util.ModelInstanceSelectionAction;
import org.dresdenocl.modelbus.ui.internal.views.util.ModelObjectContentProvider;
import org.dresdenocl.modelbus.ui.internal.views.util.ModelObjectFilter;
import org.dresdenocl.modelbus.ui.internal.views.util.ModelObjectLabelProvider;
import org.dresdenocl.modelinstance.IModelInstance;
import org.dresdenocl.modelinstance.IModelInstanceRegistry;
import org.dresdenocl.modelinstance.event.IModelInstanceRegistryListener;
import org.dresdenocl.modelinstance.event.ModelInstanceRegistryEvent;
import org.dresdenocl.modelinstancetype.types.IModelInstanceElement;
/**
* <p>
* A {@link ModelInstancesView} displaying the active model instance.
* </p>
*
* @author Ronny Brandt
*/
public class ModelInstancesView extends ViewPart implements
IModelInstanceRegistryListener, IModelRegistryListener,
ISelectionListener {
/** The Constant ID of this class. */
public static final String ID = IModelBusConstants.MODEL_INSTANCES_VIEW_ID;
/**
* Icon to remove an {@link IModelInstance} from the
* {@link IModelInstanceRegistry}.
*/
public static String IMAGE_CLOSE_MODEL_INSTANCE = "icons/delete.gif";
/**
* Action to the tool bar to remove the currently selected
* {@link IModelInstance}.
*/
private Action myActionRemoveModelInstance;
/** The menu of the {@link ModelInstancesView}. */
private IMenuManager myMenu;
/**
* The {@link ModelInstanceSelectionAction}s according to the {@link IModel}
* .
*/
private Map<IModel, Map<IModelInstance, ModelInstanceSelectionAction>> myModelInstanceSelectionActions;
/**
* TODO Claas: Disabled filter because it is more confusing then helpful
* here.
*
* The actual filter to show {@link IModelInstanceElement}s.
*/
private ModelObjectFilter myModelObjectFilter = new ModelObjectFilter();
/** The selected {@link ModelInstanceSelectionAction}. */
private Map<IModel, ModelInstanceSelectionAction> mySelectedAction;
/** The {@link TreeViewer} to show the {@link IModelInstance}. */
private TreeViewer myViewer;
/**
* <p>
* Creates a new {@link ModelInstancesView}.
* </p>
*/
public ModelInstancesView() {
super();
this.myModelInstanceSelectionActions = new HashMap<IModel, Map<IModelInstance, ModelInstanceSelectionAction>>();
/* Register the view as model and model instance listener. */
ModelBusPlugin.getModelRegistry().addModelRegistryListener(this);
ModelBusPlugin.getModelInstanceRegistry()
.addModelInstanceRegistryListener(this);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
public void dispose() {
/* Remove this view as listener of related plug-ins. */
ModelBusPlugin.getModelRegistry().removeModelRegistryListener(this);
ModelBusPlugin.getModelInstanceRegistry()
.removeModelInstanceRegistryListener(this);
((ISelectionService) getSite().getService(ISelectionService.class))
.removeSelectionListener(this);
}
/*
* (non-Javadoc)
*
* @seeorg.dresdenocl.modelbus.event.IModelRegistryListener#
* activeModelChanged
* (org.dresdenocl.modelbus.event.ModelRegistryEvent)
*/
public void activeModelChanged(ModelRegistryEvent e) {
final IModel model = e.getAffectedModel();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
rebuildMenu(model);
setActiveModelInstance(ModelBusPlugin
.getModelInstanceRegistry()
.getActiveModelInstance(model));
}
});
}
/*
* (non-Javadoc)
*
* @seeorg.dresdenocl.modelbus.event.IModelInstanceRegistryListener#
* activeModelInstanceChanged
* (org.dresdenocl.modelbus.event.ModelInstanceRegistryEvent)
*/
public void activeModelInstanceChanged(ModelInstanceRegistryEvent event) {
final IModelInstance modelInstance = event.getAffectedModelInstance();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
setActiveModelInstance(modelInstance);
}
});
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets
* .Composite)
*/
public void createPartControl(Composite aParent) {
this.myViewer = new TreeViewer(aParent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
this.myViewer.setContentProvider(new ModelObjectContentProvider());
this.myViewer.setLabelProvider(new ModelObjectLabelProvider());
this.myViewer.setInput(this.getViewSite());
this.initMenu();
this.getViewSite().setSelectionProvider(this.myViewer);
this.getViewSite().getPage().addSelectionListener(this);
}
/*
* (non-Javadoc)
*
* @see
* org.dresdenocl.modelbus.event.IModelRegistryListener#modelAdded
* (org.dresdenocl.modelbus.event.ModelRegistryEvent)
*/
public void modelAdded(ModelRegistryEvent event) {
final IModel model = event.getAffectedModel();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
rebuildMenu(model);
setActiveModelInstance(ModelBusPlugin
.getModelInstanceRegistry()
.getActiveModelInstance(model));
}
});
}
public void modelRemoved(ModelRegistryEvent event) {
final IModel model = event.getAffectedModel();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
if (myModelInstanceSelectionActions != null) {
myModelInstanceSelectionActions.remove(model);
}
// no else.
}
});
}
/*
* (non-Javadoc)
*
* @seeorg.dresdenocl.modelbus.event.IModelInstanceRegistryListener#
* modelInstanceAdded
* (org.dresdenocl.modelbus.event.ModelInstanceRegistryEvent)
*/
public void modelInstanceAdded(ModelInstanceRegistryEvent event) {
final IModelInstance modelInstance = event.getAffectedModelInstance();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
addModelInstanceSelectionAction(modelInstance);
}
});
}
/*
* (non-Javadoc)
*
* @seeorg.dresdenocl.modelbus.event.IModelInstanceRegistryListener#
* modelInstanceRemoved
* (org.dresdenocl.modelbus.event.ModelInstanceRegistryEvent)
*/
public void modelInstanceRemoved(ModelInstanceRegistryEvent event) {
final IModelInstance modelInstance = event.getAffectedModelInstance();
/* Execute in a GUI thread to avoid IllegalThreadExceptions. */
ModelBusUIPlugin.getDefault().getWorkbench().getDisplay()
.asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
removeModelInstanceSelectionAction(modelInstance);
}
});
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.
* IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
this.myModelObjectFilter.clearFilter();
/*
* TODO Claas: Disabled filter because it is more confusing then helpful
* here.
*/
// /* Check if the given part is a ModelsView. */
// if (part != null && part instanceof ModelsView) {
//
// /* Check if the given selection is a TreeSelection. */
// if (selection != null && selection instanceof TreeSelection) {
//
// TreeSelection aTreeSelection;
// Iterator<?> aSelectionIt;
//
// /* Remove the old and create a new ModelObjectFilter. */
// this.myViewer.removeFilter(this.myModelObjectFilter);
// this.myModelObjectFilter.clearFilter();
//
// aTreeSelection = (TreeSelection) selection;
// aSelectionIt = aTreeSelection.iterator();
//
// /* Iterate over the elements of the selection. */
// while (aSelectionIt.hasNext()) {
//
// Object anObject;
//
// anObject = aSelectionIt.next();
//
// this.myModelObjectFilter.addFilter(anObject);
// }
// // end while.
//
// this.myViewer.addFilter(this.myModelObjectFilter);
//
// this.myViewer.refresh();
// }
// // no else.
// }
// // no else.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
public void setFocus() {
this.myViewer.getControl().setFocus();
}
/**
* <p>
* Adds an {@link ModelInstanceSelectionAction} for a given
* {@link IModelInstance}. The {@link ModelInstanceSelectionAction} is used
* to select the IModelInstance to be shown in this view.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} of the
* {@link ModelInstanceSelectionAction}.
*
* @return the model instance selection action
*/
private ModelInstanceSelectionAction addModelInstanceSelectionAction(
IModelInstance modelInstance) {
ModelInstanceSelectionAction result;
Map<IModelInstance, ModelInstanceSelectionAction> aModelsActions;
result = null;
aModelsActions = this.myModelInstanceSelectionActions.get(modelInstance
.getModel());
/* Get the action or initialize it. */
if (aModelsActions != null) {
result = aModelsActions.get(modelInstance);
} else {
aModelsActions = new HashMap<IModelInstance, ModelInstanceSelectionAction>();
}
if (result == null) {
result = new ModelInstanceSelectionAction(modelInstance.getModel(),
modelInstance);
aModelsActions.put(modelInstance, result);
this.myModelInstanceSelectionActions.put(modelInstance.getModel(),
aModelsActions);
if (ModelBusPlugin.getModelRegistry().getActiveModel() == modelInstance
.getModel()) {
getMenu().add(result);
}
// no else.
this.getViewSite().getActionBars().updateActionBars();
}
// no else.
return result;
}
/**
* <p>
* Returns the {@link IMenuManager} of this {@link ModelInstancesView}.
* </p>
*
* @return The {@link IMenuManager} of this {@link ModelInstancesView}.
*/
private IMenuManager getMenu() {
/* Eventually initialize the menu manager. */
if (this.myMenu == null) {
this.myMenu = getViewSite().getActionBars().getMenuManager();
}
// no else.
return this.myMenu;
}
/**
* <p>
* Initializes the drop-down menu of the view with all
* {@link IModelInstance}s currently registered for the active
* {@link IModel}.
* </p>
*/
private void initMenu() {
IModel[] allModels;
Iterator<IModel> modelIt;
allModels = ModelBusPlugin.getModelRegistry().getModels();
modelIt = Arrays.asList(allModels).iterator();
/* Iterate through the models and collect all model instances. */
while (modelIt.hasNext()) {
IModel aModel;
aModel = modelIt.next();
if (aModel != null) {
IModelInstance[] modelsInstances;
modelsInstances = ModelBusPlugin.getModelInstanceRegistry()
.getModelInstances(aModel);
for (int i = 0; i < modelsInstances.length; i++) {
this.addModelInstanceSelectionAction(modelsInstances[i]);
}
}
// no else.
}
/*
* Add an action to the tool bar to remove the currently selected model
* instance.
*/
myActionRemoveModelInstance = new Action() {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
public void run() {
removeSelectedModelInstance();
}
};
myActionRemoveModelInstance
.setToolTipText("Closes the currently selected model instance.");
myActionRemoveModelInstance.setText("Close Model Instance");
myActionRemoveModelInstance.setImageDescriptor(ModelBusUIPlugin
.getImageDescriptor(IMAGE_CLOSE_MODEL_INSTANCE));
myActionRemoveModelInstance
.setEnabled(ModelBusPlugin.getModelInstanceRegistry()
.getActiveModelInstance(
ModelBusPlugin.getModelRegistry()
.getActiveModel()) != null);
this.getViewSite().getActionBars().getToolBarManager()
.add(myActionRemoveModelInstance);
/*
* Update the currently active model instance.
*/
updateActiveModelInstance();
}
/**
* <p>
* If there is an active {@link IModelInstance} the viewer will be updated
* to show it properly.
* </p>
*/
private void updateActiveModelInstance() {
IModel activeModel;
IModelInstance activeModelInstance;
activeModel = ModelBusPlugin.getModelRegistry().getActiveModel();
activeModelInstance = ModelBusPlugin.getModelInstanceRegistry()
.getActiveModelInstance(activeModel);
if (activeModelInstance != null) {
this.setActiveModelInstance(activeModelInstance);
}
}
/**
* <p>
* Rebuilds the menu of this {@link ModelInstancesView}.
* </p>
*
* @param affectedModel
* The affected {@link IModel} for which the menu shall be
* rebuilt.
*/
private void rebuildMenu(IModel affectedModel) {
Map<IModelInstance, ModelInstanceSelectionAction> aModelsSelectionActions;
this.getMenu().removeAll();
aModelsSelectionActions = this.myModelInstanceSelectionActions
.get(affectedModel);
/*
* If the given model has any model instances to select, add them to the
* menu as options.
*/
if (aModelsSelectionActions != null) {
Collection<ModelInstanceSelectionAction> allActions;
allActions = aModelsSelectionActions.values();
if (allActions != null) {
for (ModelInstanceSelectionAction anAction : allActions) {
this.getMenu().add(anAction);
}
// end for.
}
// no else.
}
// no else.
}
/**
* <p>
* Removes an {@link ModelInstanceSelectionAction} for a given
* {@link IModelInstance}.
* </p>
*
* @param modelInstance
* The {@link IModelInstance} of the
* {@link ModelInstanceSelectionAction}.
*
* @return The ModelInstanceSelectionAction that has been removed or
* <code>null</code> if no {@link ModelInstanceSelectionAction} has
* been removed.
*/
private ModelInstanceSelectionAction removeModelInstanceSelectionAction(
IModelInstance modelInstance) {
ModelInstanceSelectionAction result;
result = null;
Map<IModelInstance, ModelInstanceSelectionAction> modelsActions;
modelsActions = this.myModelInstanceSelectionActions.get(modelInstance
.getModel());
/* Check if the model has actions at all. */
if (modelsActions != null) {
result = modelsActions.remove(modelInstance);
if (result != null) {
this.myModelInstanceSelectionActions.put(
modelInstance.getModel(), modelsActions);
if (ModelBusPlugin.getModelRegistry().getActiveModel() == modelInstance
.getModel()) {
getMenu().remove(result.getId());
this.getViewSite().getActionBars().updateActionBars();
}
// no else.
}
// no else.
}
// no else.
return result;
}
/**
* <p>
* Helper method to remove the currently selected {@link IModelInstance}
* from the {@link ModelBusPlugin}.
* </p>
*/
private void removeSelectedModelInstance() {
IModelRegistry modelRegistry;
modelRegistry = ModelBusPlugin.getModelRegistry();
IModelInstanceRegistry modelInstanceRegistry;
modelInstanceRegistry = ModelBusPlugin.getModelInstanceRegistry();
IModelInstance activeModelInstance;
activeModelInstance = modelInstanceRegistry
.getActiveModelInstance(modelRegistry.getActiveModel());
if (activeModelInstance != null) {
modelInstanceRegistry.removeModelInstance(activeModelInstance);
}
// no else.
}
/**
* <p>
* Sets the active {@link IModelInstance}.
* </p>
*
* @param affectedModelInstance
* The affected {@link IModelInstance}.
*/
private void setActiveModelInstance(IModelInstance affectedModelInstance) {
/* Check if the model instance is not null. */
if (affectedModelInstance != null) {
IModel affectedModel;
affectedModel = affectedModelInstance.getModel();
ModelInstanceSelectionAction aSelectionAction;
Map<IModelInstance, ModelInstanceSelectionAction> aModelsSelectionActions;
/* Get the selection actions of the affected model. */
aSelectionAction = null;
aModelsSelectionActions = this.myModelInstanceSelectionActions
.get(affectedModel);
if (aModelsSelectionActions != null) {
aSelectionAction = aModelsSelectionActions
.get(affectedModelInstance);
}
// no else.
/* Check if the affected model is the active model. */
if (affectedModel == ModelBusPlugin.getModelRegistry()
.getActiveModel()) {
ModelInstanceSelectionAction theLastSelectionAction;
/* Get the last selection action. */
if (this.mySelectedAction != null) {
theLastSelectionAction = this.mySelectedAction
.get(affectedModel);
}
else {
theLastSelectionAction = null;
}
/* Eventually store the new selection action as new last one. */
if (aSelectionAction != null) {
if (theLastSelectionAction != null) {
theLastSelectionAction.setChecked(false);
}
aSelectionAction.setChecked(true);
if (this.mySelectedAction == null) {
this.mySelectedAction = new HashMap<IModel, ModelInstanceSelectionAction>();
}
// no else.
this.mySelectedAction.put(affectedModel, aSelectionAction);
}
else {
String msg;
msg = "No model instance selection action has been created ";
msg += "for model instance '";
msg += affectedModelInstance.getDisplayName() + "'";
throw new IllegalStateException(msg);
}
if (myViewer.getInput() == null
&& affectedModelInstance != null
|| myViewer.getInput() != null
&& myViewer.getInput() != affectedModelInstance) {
setInput(affectedModelInstance);
}
}
// no else.
this.myActionRemoveModelInstance.setEnabled(true);
}
/* Else the tree viewer gets a null input. */
else {
this.myViewer.setInput(null);
this.myActionRemoveModelInstance.setEnabled(false);
}
}
/**
* <p>
* Sets a given {@link IModelInstance} as new input.
* </p>
*
* @param affectedModelInstance
* The new input which shall be set.
*/
private void setInput(IModelInstance affectedModelInstance) {
this.myViewer.setInput(affectedModelInstance);
this.myViewer.refresh();
}
}