blob: b7eacfc5962f363d022465a246a175972ef4cf20 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012-2014 SAP SE.
* 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:
* SAP SE - initial API and implementation and/or initial documentation
*
*******************************************************************************/
package org.eclipse.ogee.designer;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.graphiti.features.context.impl.CustomContext;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.editor.DiagramBehavior;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ogee.designer.actions.ODataArtifactsCollapseAllAction;
import org.eclipse.ogee.designer.actions.ODataArtifactsExpandAllAction;
import org.eclipse.ogee.designer.actions.ODataShowUsageAction;
import org.eclipse.ogee.designer.features.ODataCollapsibleFeature;
import org.eclipse.ogee.designer.messages.Messages;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.IODataEditorConstants;
import org.eclipse.ogee.designer.utils.ODataArtifactSelectionUtil;
import org.eclipse.ogee.designer.utils.ODataLayoutUtil;
import org.eclipse.ogee.designer.utils.PropertyUtil;
import org.eclipse.ogee.designer.visualizer.ODataModelVisualizer;
import org.eclipse.ogee.model.api.IModelContext;
import org.eclipse.ogee.model.api.IValidator;
import org.eclipse.ogee.model.api.ModelAPIException;
import org.eclipse.ogee.model.odata.EDMXSet;
import org.eclipse.ogee.utils.logger.Logger;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
/**
* OData Model Graphical Editor.
*/
public class ODataEditor extends DiagramEditor implements IGotoMarker {
private IFile modelFile;
private boolean isReadOnly = false;
private IWorkbenchListener workbenchListener;
private ODataDomainModelChangeListener odataModelChangeListener;
private IAction expandAllAction;
private IAction collapseAllAction;
private IAction showUsageAction;
private GraphicalViewer graphicalViewer;
/**
* OData Editor ID
*/
public static final String EDITOR_ID = "org.eclipse.ogee.designer.ODataEditor"; //$NON-NLS-1$
@Override
public void init(IEditorSite site, final IEditorInput input)
throws PartInitException {
boolean isBlankModel = false;
try {
// Editor is invoked from Project Explorer.
if (input instanceof IFileEditorInput) {
this.setModelFile(((IFileEditorInput) input).getFile());
// OData file is read only
this.isReadOnly = ((IFileEditorInput) input).getFile()
.isReadOnly();
}
// Editor is invoked from IODataDiagramCreator#createDiagram() API.
else if (input instanceof ODataEditorInput) {
final URI uri = ((ODataEditorInput) input).getUri();
final String uriString = uri.trimFragment().toPlatformString(
true);
this.setModelFile(getModelFile(new Path(uriString)));
isBlankModel = ((ODataEditorInput) input).isBlankModel();
this.isReadOnly = ((ODataEditorInput) input).getDiagramInput()
.isReadOnlyMode();
}
// Editor is invoked when eclipse IDE is launched.
else if (input instanceof DiagramEditorInput) {
final URI uri = ((DiagramEditorInput) input).getUri();
final String uriString = uri.trimFragment().toPlatformString(
true);
this.setModelFile(getModelFile(new Path(uriString)));
// OData file is read only
this.isReadOnly = getModelFile(new Path(uriString))
.isReadOnly();
}
// invoke super's init(). Do not change the invocation position.
super.init(site, input);
// obtain the global context support instance from the workbench.
final IContextService contextService = (IContextService) PlatformUI
.getWorkbench().getService(IContextService.class);
if (contextService != null) {
// enable the context defined for OData Editor.
contextService
.activateContext(IODataEditorConstants.ODATA_EDITOR_CONTEXT_ID);
}
// for non-empty model input, visualize the model.
if (input instanceof ODataEditorInput && !isBlankModel) {
final ODataEditorInput editorInput = (ODataEditorInput) input;
final IProgressMonitor monitor = editorInput.getDiagramInput()
.getProgressMonitor();
final TransactionalEditingDomain editingDomain = this
.getEditingDomain();
editingDomain.getCommandStack().execute(
new RecordingCommand(editingDomain) {
@Override
protected void doExecute() {
/*
* ODataEditorService.updateProgressMonitor(
* Messages.PROGRESS_TASK_NAME7, 5, monitor); //
* completed 15%
*/
monitor.setTaskName(Messages.PROGRESS_TASK_NAME7);
monitor.worked(5);
final ODataModelVisualizer visualizer = new ODataModelVisualizer(
getDiagramTypeProvider());
visualizer.visualizeModel(editorInput);
/*
* ODataEditorService.updateProgressMonitor(null,
* 5, monitor); // completed 70%
*/
monitor.worked(5);
// Do not validate read only models.
if (!editorInput.getDiagramInput()
.isReadOnlyMode()) {
/*
* ODataEditorService.updateProgressMonitor(
* Messages.PROGRESS_TASK_NAME8, 0,
* monitor);
*/
monitor.setTaskName(Messages.PROGRESS_TASK_NAME8);
monitor.worked(0);
final EDMXSet edmxSet = editorInput
.getDiagramInput().getEDMXSet();
// Validate the edmxSet according to the
// OData 3.0 specification.
// For each constraint violation a
// corresponding problem marker is
// created.
if (edmxSet != null) {
final IValidator validator = IModelContext.INSTANCE
.createValidator();
validator.validate(edmxSet);
}
}
}
});
/*
* ODataEditorService.updateProgressMonitor(
* Messages.PROGRESS_TASK_NAME10, 0, monitor);
*/
monitor.setTaskName(Messages.PROGRESS_TASK_NAME10);
monitor.worked(0);
try {
final IFile file = getModelFile();
if (file != null) {
IModelContext.INSTANCE.saveModelFile(file);
}
} catch (ModelAPIException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
}
/*
* ODataEditorService.updateProgressMonitor(
* Messages.PROGRESS_TASK_NAME6, 10, monitor); // completed //
* 80%
*/
monitor.setTaskName(Messages.PROGRESS_TASK_NAME6);
monitor.worked(10);
}
// add a listener so we get notified if the workbench is shutting
// down.
// in this case dispose the temporary model files.
addWorkbenchListener();
} catch (PartInitException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
throw new PartInitException(new Status(IStatus.ERROR,
Activator.PLUGIN_ID, e.getMessage(), e));
} catch (Exception t) {
Logger.getLogger(Activator.PLUGIN_ID).logError(t);
throw new PartInitException(new Status(IStatus.ERROR,
Activator.PLUGIN_ID, t.getMessage(), t));
}
}
/**
* Creates DiagramBehavior Instance.
*/
@Override
protected DiagramBehavior createDiagramBehavior() {
return new ODataDiagramBehavior(this);
}
@Override
public String getContributorId() {
return super.getContributorId();
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class required) {
if (required == IGotoMarker.class) {
return this;
}
return super.getAdapter(required);
}
@Override
public void gotoMarker(IMarker marker) {
EObject bo = null;
try {
if (IODataEditorConstants.PROBLEM_MARKER_ID
.equals(marker.getType())) {
final String uriAttribute = marker.getAttribute(
IMarker.LOCATION, null);
if (uriAttribute != null) {
final URI uri = URI.createURI(uriAttribute);
EObject eObject = getDiagramBehavior().getResourceSet()
.getEObject(uri, true);
eObject = ArtifactUtil.getSelectableObject(eObject);
if (eObject != null) {
// peList -> list of selectable PictogramElement's.
final List<PictogramElement> peList = new ArrayList<PictogramElement>();
final List<PictogramElement> referencingPes = Graphiti
.getLinkService().getPictogramElements(
getDiagramTypeProvider().getDiagram(),
eObject);
// for selected object with the Top Container set, only
// add the PictogramElement with the Top Container
for (PictogramElement pe : referencingPes) {
bo = Graphiti
.getLinkService()
.getBusinessObjectForLinkedPictogramElement(
pe);
if (eObject.equals(bo)
&& PropertyUtil.isTopContainer(pe)) {
// add selectable Top Container Pictogram
// Element into one list -> peList
peList.add(pe);
break;
}
}
if (!referencingPes.isEmpty() && peList.isEmpty()) {
for (PictogramElement pe : referencingPes) {
bo = Graphiti
.getLinkService()
.getBusinessObjectForLinkedPictogramElement(
pe);
if (eObject.equals(bo)) {
// add selectable Pictogram Element into one
// list -> peList
peList.add(pe);
}
}
}
// Do the selection in the diagram (in case there is
// something to select)
PictogramElement[] pes = null;
if (peList.size() > 0) {
pes = peList.toArray(new PictogramElement[peList
.size()]);
}
if (pes != null && pes.length > 0) {
for (PictogramElement pe : pes) {
// expand the group corresponding to selected
// pictogram element.
this.expandGroup(pe);
}
// Do the selection in the diagram
selectPictogramElements(pes);
}
}
}
}
} catch (CoreException exception) {
Logger.getLogger(Activator.PLUGIN_ID).logError(exception);
}
}
@Override
public boolean isSaveAsAllowed() {
if (this.isReadOnly) {
return false;
}
return true;
}
@Override
public void doSave(IProgressMonitor monitor) {
super.doSave(monitor);
final EDMXSet edmxSet = getEDMXSet();
// Validate the edmxSet according to the OData 3.0 specification.
// For each constraint violation a corresponding problem marker is
// created.
if (edmxSet != null) {
final IValidator validator = IModelContext.INSTANCE
.createValidator();
validator.validate(edmxSet);
getDiagramBehavior().refresh();
// bug fix for Artifact name still in edit mode after save
// programatically call Escape key so as to lose focus of editor
if (getDiagramBehavior().isDirectEditingActive()) {
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
}
}
}
}
@Override
public void doSaveAs() {
handleSaveAs();
final EDMXSet edmxSet = getEDMXSet();
// Validate the edmxSet according to the OData 3.0 specification.
// For each constraint violation a corresponding problem marker is
// created.
if (edmxSet != null) {
final IValidator validator = IModelContext.INSTANCE
.createValidator();
validator.validate(edmxSet);
getDiagramBehavior().refresh();
}
}
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
// As GEF doesn't understands multi-page editors,
// invoke updateActions() in case the active editor is an
// instance of MultiPageEditorPart.
final IEditorPart editor = getSite().getPage().getActiveEditor();
if (editor instanceof MultiPageEditorPart) {
// Update the selectionActions list when the editor is selected
// as a page of a MultiPageEditorPart.
updateActions(getSelectionActions());
}
this.handleSelectionChanged(part, selection);
}
@Override
public boolean isDirty() {
if (this.isReadOnly) {
return false;
}
return super.isDirty();
}
/**
* registered listener has to be removed before dispose of editor.
*/
@Override
public void dispose() {
super.dispose();
if (this.modelFile != null
&& IODataEditorConstants.TEMPFILE_EXTENSION
.equals(this.modelFile.getFileExtension())) {
disposeTempFile(this.modelFile);
} else {
final TransactionalEditingDomain editingDomain = this
.getEditingDomain();
if (editingDomain != null) {
editingDomain
.removeResourceSetListener(this.odataModelChangeListener);
this.odataModelChangeListener = null;
}
}
// Remove the added actions from action registry & dispose.
if (this.expandAllAction != null) {
getActionRegistry().removeAction(this.expandAllAction);
this.expandAllAction = null;
}
if (this.collapseAllAction != null) {
getActionRegistry().removeAction(this.collapseAllAction);
this.collapseAllAction = null;
}
if (this.showUsageAction != null) {
getActionRegistry().removeAction(this.showUsageAction);
this.showUsageAction = null;
}
getActionRegistry().dispose();
this.modelFile = null;
this.graphicalViewer = null;
this.removeWorkbenchListener();
this.odataModelChangeListener = null;
}
/**
* @return IFile - model file
*/
public IFile getModelFile() {
return this.modelFile;
}
/**
* @param file
* - instance of IFile
*/
public void setModelFile(final IFile file) {
this.modelFile = file;
}
/**
* @return boolean - true, if read only.
*/
public boolean isReadOnly() {
return this.isReadOnly;
}
/**
* @param readOnlyFlag
* - set true, if read only.
*/
public void setReadOnly(final boolean readOnlyFlag) {
this.isReadOnly = readOnlyFlag;
}
@Override
protected void setInput(IEditorInput input) {
super.setInput(input);
}
private static IFile getModelFile(IPath fullPath) {
return ResourcesPlugin.getWorkspace().getRoot()
.getFile(fullPath.makeAbsolute());
}
// The following method is redefined as the configuration provider is not
// yet part of the Graphiti API in 0.9.
// TODO Fix it as we switch to Graphiti 0.10.
/*
* The following method is redefined in order to disable all external
* droppings into the diagram. (non-Javadoc)
*
* @see
* org.eclipse.graphiti.ui.editor.DiagramEditor#createGraphicalViewer(org
* .eclipse.swt.widgets.Composite)
*/
@Override
protected void createGraphicalViewer(Composite parent) {
// In order to disable all external droppings into the diagram, the
// customized viewer "ODataScrollingGraphicalViewer" is implemented
// in which the object transfer drop listener is filtered out on adding.
this.graphicalViewer = new ODataScrollingGraphicalViewer(this);
this.graphicalViewer.createControl(parent);
setGraphicalViewer(this.graphicalViewer);
configureGraphicalViewer();
hookGraphicalViewer();
initializeGraphicalViewer();
}
@Override
public ActionRegistry getActionRegistry() {
return super.getActionRegistry();
}
@Override
protected void initializeActionRegistry() {
super.initializeActionRegistry();
// Register an "expand all" action to expand all OData artifacts from
// graphical editor tool bar.
this.expandAllAction = new ODataArtifactsExpandAllAction(this);
this.expandAllAction.setEnabled(true);
getActionRegistry().registerAction(this.expandAllAction);
// Register a "collapse all" action to collapse all OData artifacts from
// graphical editor tool bar.
this.collapseAllAction = new ODataArtifactsCollapseAllAction(this);
this.collapseAllAction.setEnabled(true);
getActionRegistry().registerAction(this.collapseAllAction);
// Register a "show/hide all usages" action to show/hide usages of all
// types from graphical editor tool bar.
this.showUsageAction = new ODataShowUsageAction(this);
this.showUsageAction.setEnabled(true);
if (PropertyUtil.isShowAllUsage(this.getDiagramTypeProvider()
.getDiagram())) {
this.showUsageAction.setChecked(true);
} else {
this.showUsageAction.setChecked(false);
}
getActionRegistry().registerAction(this.showUsageAction);
}
/**
* Delete the temporary model file & the project.
*
* @param file
* - the temporary diagram file.
*/
protected static void disposeTempFile(final IFile tempFile) {
try {
if (tempFile != null && tempFile.exists()) {
final IProject project = tempFile.getProject();
tempFile.delete(true, null);
if (project != null && project.exists()) {
project.delete(true, null);
}
}
} catch (CoreException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
}
}
/**
* Handles a selection changed event that is triggered by any selection
* source, e.g. a browser with "Link to Editor" enabled.<br>
* Checks if the currently active editor is a {@link MultiPageEditorPart}
* with an opened diagram editor inside, tries to find any
* {@link PictogramElement} for the objects in the selection and selects
* them in the diagram.<br>
* Note that in case of the {@link CommonNavigator} as event source, its
* editor linking mechanism must be enabled.
*
* @param part
* the source {@link IWorkbenchPart} that triggered the event
* @param selection
* the new selection (mostly a {@link IStructuredSelection}
* instance.
*/
private void handleSelectionChanged(final IWorkbenchPart part,
final ISelection selection) {
EObject bo = null;
EObject selectableObj = null;
// If not the active editor, ignore selection changed.
boolean editorIsActive = getSite().getPage().isPartVisible(this);
if (!editorIsActive) {
// Check if we are a page of the active multi page editor
final IEditorPart activeEditor = getSite().getPage()
.getActiveEditor();
if (activeEditor != null) {
if (activeEditor instanceof MultiPageEditorPart) {
final Object selectedPage = ((MultiPageEditorPart) activeEditor)
.getAdapter(DiagramEditor.class);
if (selectedPage instanceof DiagramEditor) {
// Editor is active and diagram sub-editor is its active
// page
editorIsActive = true;
}
}
}
}
if (editorIsActive) {
// this is where we should check the selection source (part)
// for CNF view the link flag must be obeyed
// this would however require a dependency to
// org.eclipse.ui.navigator
if (part instanceof CommonNavigator) {
if (!((CommonNavigator) part).isLinkingEnabled()) {
return;
}
}
if (selection instanceof IStructuredSelection) {
final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
// Collect all Pictogram Elements for all selected domain
// objects into one list -> peList
final List<PictogramElement> peList = new ArrayList<PictogramElement>();
for (Iterator<?> iterator = structuredSelection.iterator(); iterator
.hasNext();) {
final Object object = iterator.next();
if (object instanceof EObject) {
selectableObj = ArtifactUtil
.getSelectableObject((EObject) object);
if (selectableObj != null) {
// Find the Pictogram Elements for the given domain
// object via the standard link service
final List<PictogramElement> referencingPes = Graphiti
.getLinkService().getPictogramElements(
getDiagramTypeProvider()
.getDiagram(),
selectableObj);
// for selected object with the Top Container set,
// add only the PictogramElement with the Top
// Container.
for (PictogramElement pe : referencingPes) {
bo = Graphiti
.getLinkService()
.getBusinessObjectForLinkedPictogramElement(
pe);
if (selectableObj.equals(bo)
&& PropertyUtil.isTopContainer(pe)) {
// add selectable Top Container Pictogram
// Element into one list -> peList
peList.add(pe);
break;
}
}
if (!referencingPes.isEmpty() && peList.isEmpty()) {
for (PictogramElement pe : referencingPes) {
bo = Graphiti
.getLinkService()
.getBusinessObjectForLinkedPictogramElement(
pe);
if (selectableObj.equals(bo)) {
// add selectable Pictogram Element into
// one list -> peList
peList.add(pe);
}
}
}
}
} else {
// For non-EMF domain objects use the registered
// notification service for finding
PictogramElement[] relatedPictogramElements = getDiagramTypeProvider()
.getNotificationService()
.calculateRelatedPictogramElements(
new Object[] { object });
for (int i = 0; i < relatedPictogramElements.length; i++) {
peList.add(relatedPictogramElements[i]);
}
}
}
// Do the selection in the diagram (in case there is something
// to select)
PictogramElement[] pes = null;
if (peList.size() > 0) {
pes = peList.toArray(new PictogramElement[peList.size()]);
}
if (pes != null && pes.length > 0) {
for (PictogramElement pe : pes) {
// expand the group corresponding to selected
// pictogram element.
this.expandGroup(pe);
}
// Do the selection in the diagram.
selectPictogramElements(pes);
}
//below code is enable the artifact selection extention
PictogramElement[] selectedPictogramElements = getSelectedPictogramElements();
EObject businessObject = (EObject) getDiagramTypeProvider().getFeatureProvider().getBusinessObjectForPictogramElement(selectedPictogramElements[0]);
ODataArtifactSelectionUtil.notifyRegisteredSubscribers(selectedPictogramElements[0], businessObject , ODataArtifactSelectionUtil.SelectionStatus.SELECTED);
}
}
}
/*
* Get EDMXSet from OData service model file.
*/
private EDMXSet getEDMXSet() {
EDMXSet edmxSet = null;
if (this.getModelFile() != null) {
final URI uri = URI.createPlatformResourceURI(this.getModelFile()
.getFullPath().toString(), true);
final EList<EObject> resourceContents = getDiagramBehavior()
.getResourceSet().getResource(uri, true).getContents();
for (EObject resourceContent : resourceContents) {
if (resourceContent instanceof EDMXSet) {
edmxSet = (EDMXSet) resourceContent;
break;
}
}
}
return edmxSet;
}
/*
* The following method will expand the collapsed group for the selected
* pictogram element.
*/
private void expandGroup(final PictogramElement pe) {
if (pe != null && pe instanceof ContainerShape) {
final Shape expandSection = ODataLayoutUtil
.getSectionTitle((ContainerShape) pe);
if (expandSection != null) {
final TransactionalEditingDomain editingDomain = this
.getEditingDomain();
editingDomain.getCommandStack().execute(
new RecordingCommand(editingDomain) {
@Override
public void doExecute() {
final ODataCollapsibleFeature collapsableFeature = new ODataCollapsibleFeature(
getDiagramTypeProvider()
.getFeatureProvider());
final CustomContext context = new CustomContext();
context.setPictogramElements(new PictogramElement[] { expandSection });
collapsableFeature.execute(context);
}
});
}
}
}
/*
* The following method disposes the temporary model files on eclipse
* shutdown.
*/
private void addWorkbenchListener() {
if (this.workbenchListener == null) {
this.workbenchListener = new IWorkbenchListener() {
@Override
public boolean preShutdown(IWorkbench workbench, boolean forced) {
if (getModelFile() != null
&& getModelFile().exists()
&& IODataEditorConstants.TEMPFILE_EXTENSION
.equals(getModelFile().getFileExtension())) {
final IWorkbenchPage page = getSite().getPage();
final IEditorPart editorPart = ResourceUtil.findEditor(
page, getModelFile());
if (editorPart != null) {
page.closeEditor(editorPart, false);
}
disposeTempFile(getModelFile());
}
return true;
}
@Override
public void postShutdown(IWorkbench workbench) {
// do nothing
}
};
PlatformUI.getWorkbench().addWorkbenchListener(
this.workbenchListener);
}
}
private void removeWorkbenchListener() {
if (this.workbenchListener != null) {
PlatformUI.getWorkbench().removeWorkbenchListener(
this.workbenchListener);
this.workbenchListener = null;
}
}
private void handleSaveAs() {
IFile oldFile = getModelFile();
SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
saveAsDialog.setOriginalFile(oldFile);
saveAsDialog.create();
if (saveAsDialog.open() == Window.CANCEL) {
return;
}
IPath newFilePath = saveAsDialog.getResult();
if (newFilePath == null) {
return;
}
IFile newFile = ResourcesPlugin.getWorkspace().getRoot()
.getFile(newFilePath);
IWorkbenchPage page = getSite().getPage();
try {
// Save the current(old) file
doSave(null);
// if new file exists, close its editor (if open) and delete the
// existing file
if (newFile.exists()) {
IEditorPart editorPart = ResourceUtil.findEditor(page, newFile);
if (editorPart != null) {
page.closeEditor(editorPart, false);
}
newFile.delete(true, null);
}
// make a copy
oldFile.copy(newFilePath, true, null);
} catch (CoreException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
return;
}
// open new editor
try {
page.openEditor(new FileEditorInput(newFile), ODataEditor.EDITOR_ID);
} catch (PartInitException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
return;
}
// and close the old editor
IEditorPart editorPart = ResourceUtil.findEditor(page, oldFile);
if (editorPart != null) {
page.closeEditor(editorPart, false);
}
try {
newFile.refreshLocal(IResource.DEPTH_ZERO, null);
} catch (CoreException e) {
Logger.getLogger(Activator.PLUGIN_ID).logError(e);
return;
}
}
}