blob: 721625baba180050063014d3d3786661bc923c16 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2012, 2016 CEA LIST, Christian W. Damus, and others.
*
* 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:
* Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
* Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr
* Christian W. Damus - bug 485220
*
*****************************************************************************/
package org.eclipse.papyrus.designer.languages.java.jdt.texteditor.handler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.papyrus.designer.languages.common.extensionpoints.ILangCodegen;
import org.eclipse.papyrus.designer.languages.common.extensionpoints.LanguageCodegen;
import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.Activator;
import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.TextEditorConstants;
import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor;
import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncJDTtoModel;
import org.eclipse.papyrus.designer.languages.java.jdt.texteditor.sync.SyncModelToJDT;
import org.eclipse.papyrus.infra.core.resource.NotFoundException;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
import org.eclipse.papyrus.infra.emf.gmf.command.CheckedOperationHistory;
import org.eclipse.papyrus.infra.ui.util.ServiceUtilsForHandlers;
import org.eclipse.papyrus.uml.diagram.common.handlers.CmdHandler;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.UMLPackage;
/**
* The handler creates a new JDT editor
*/
public class SyncJDTEditorHandler extends CmdHandler {
private static final String EDITOR_ID = "org.eclipse.papyrus.designer.languages.java.jdt.texteditor.editor.SyncJDTEditor"; //$NON-NLS-1$
public SyncJDTEditorHandler() {
}
/**
* @see org.eclipse.core.commands.AbstractHandler#isEnabled()
*
* @return true, if enabled
*/
@Override
public boolean isEnabled() {
updateSelectedEObject();
// Filter Classes (including Behaviors, since Behavior inherits from Class), Operation and Transition
if (selectedEObject instanceof Class ||
selectedEObject instanceof Operation ||
selectedEObject instanceof Transition) {
URI uri = selectedEObject.eResource().getURI();
// URI must have at least two segments (must be in a project)
return uri.segmentCount() >= 2;
}
return false;
}
/**
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*
* @param event
* an execution event
* @return the execution result
* @throws ExecutionException
*/
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
try {
final ServicesRegistry serviceRegistry = ServiceUtilsForHandlers.getInstance().getServiceRegistry(event);
TransactionalEditingDomain domain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
// Create the transactional command
AbstractEMFOperation command = new AbstractEMFOperation(domain, "Create JDT editor") { //$NON-NLS-1$
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
try {
SyncJDTEditorHandler.this.doExecute(serviceRegistry);
} catch (ServiceException e) {
Activator.log.error(e);
return Status.CANCEL_STATUS;
} catch (NotFoundException e) {
Activator.log.error(e);
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
};
// Execute the command
CheckedOperationHistory.getInstance().execute(command, new NullProgressMonitor(), null);
} catch (ExecutionException e) {
Activator.log.error("Can't create a JDT editor", e); //$NON-NLS-1$
} catch (ServiceException e) {
Activator.log.error("Service exception during creation of CDT editor", e); //$NON-NLS-1$
}
return null;
}
/**
* Do the execution of the command.
*
* @param serviceRegistry
* @throws ServiceException
* @throws NotFoundException
*/
public void doExecute(final ServicesRegistry serviceRegistry) throws ServiceException, NotFoundException {
Classifier classifierToEdit = getClassifierToEdit();
// Fixed ID, since synchronization only works for standard C++ code generator
final ILangCodegen codegen =
LanguageCodegen.getGenerator(TextEditorConstants.JAVA, null);
if (codegen == null) {
return;
}
if (selectedEObject instanceof Transition) {
Transition transition = (Transition) selectedEObject;
if (transition.getEffect() == null) {
transition.createEffect("effectOf" + transition.getName(), UMLPackage.eINSTANCE.getOpaqueBehavior()); //$NON-NLS-1$
}
}
// make sure that target project gets generated
codegen.getTargetProject(classifierToEdit, true);
IFile srcFile = SyncModelToJDT.syncModelToCDT(classifierToEdit, LanguageCodegen.getID(codegen));
if (srcFile == null) {
return;
}
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
// IEditorPart editorPart = page.openEditor(new FileEditorInput(srcFile), "org.eclipse.cdt.ui.editor.CEditor");
IEditorInput input = new FileEditorInput(srcFile);
IEditorPart editorPart = page.openEditor(input, EDITOR_ID);
if (editorPart instanceof SyncJDTEditor) {
// TODO: use editorPart.setInitializationData(cfig, propertyName, data);
URI uri = selectedEObject.eResource().getURI();
SyncJDTtoModel syncCpp =
new SyncJDTtoModel(input, classifierToEdit, URI.decode(uri.segment(1)), LanguageCodegen.getID(codegen));
((SyncJDTEditor) editorPart).setEditorData(serviceRegistry, syncCpp);
}
} catch (PartInitException e) {
Activator.log.error(e);
}
// move page to the RIGHT
// if (rootModel instanceof TabFolder) {
// // root = tabFolder, i.e. there is a single folder
// ISashWindowsContainer sashContainer = ServiceUtils.getInstance().getService(ISashWindowsContainer.class, serviceRegistry);
// int index = lookupIndex((TabFolder) rootModel, editorModelFinal);
// if (index != -1) {
// sashContentProvider.createFolder(sashContainer.getSelectedTabFolderModel(), index, sashContainer.getSelectedTabFolderModel(), SWT.RIGHT);
// }
// }
}
});
}
/**
* The classifier to edit - corresponding to the selected object.
*
* @return
*/
protected Classifier getClassifierToEdit() {
if (selectedEObject instanceof Operation) {
return ((Operation) selectedEObject).getFeaturingClassifiers().get(0);
} else if (selectedEObject instanceof Transition) {
return ((Transition) selectedEObject).getContainer().getStateMachine().getContext();
} else if (selectedEObject instanceof Behavior) {
Element owner = (Behavior) selectedEObject;
while (owner != null) {
owner = owner.getOwner();
if ((owner instanceof Classifier) && !(owner instanceof Behavior)) {
return (Classifier) owner;
}
}
return null;
} else if (selectedEObject instanceof Classifier) {
// must be class or datatype
return (Classifier) selectedEObject;
}
return null;
}
}