234 lines
7.0 KiB
Java
Executable File
234 lines
7.0 KiB
Java
Executable File
package pyUML.actions;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import org.eclipse.core.resources.IProject;
|
|
import org.eclipse.core.runtime.IPath;
|
|
import org.eclipse.core.runtime.IProgressMonitor;
|
|
import org.eclipse.emf.ecore.EObject;
|
|
import org.eclipse.jface.action.IAction;
|
|
import org.eclipse.jface.dialogs.MessageDialog;
|
|
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
|
|
import org.eclipse.jface.operation.IRunnableWithProgress;
|
|
import org.eclipse.jface.viewers.ISelection;
|
|
import org.eclipse.jface.viewers.TreeSelection;
|
|
import org.eclipse.ui.IObjectActionDelegate;
|
|
import org.eclipse.ui.IWorkbenchPart;
|
|
import org.eclipse.uml2.uml.Classifier;
|
|
import org.eclipse.uml2.uml.Model;
|
|
import org.eclipse.uml2.uml.resource.UMLResource;
|
|
|
|
|
|
import pyUML.backend.EclipseHelperMethods;
|
|
import pyUML.backend.GlobalConstants;
|
|
import pyUML.backend.JavaHelperMethods;
|
|
import pyUML.backend.UMLToolsHelperMethods;
|
|
import pyUML.exceptions.PyUMLCancelledException;
|
|
import pyUML.exceptions.PyUMLParseException;
|
|
import pyUML.pythonTree.PythonTreeRoot;
|
|
|
|
public class SyncCodeAction implements IObjectActionDelegate, IRunnableWithProgress{
|
|
|
|
private IProject project;
|
|
private PythonTreeRoot pythonRoot = null;
|
|
|
|
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
|
|
// Auto-generated method stub
|
|
|
|
}
|
|
|
|
/**
|
|
* Run this action manually with a Progress Monitor.
|
|
* If the monitor is null, it will be created
|
|
* A PythonTreeRoot object can be given so that
|
|
* The code will not be re-analyzed for better performance.
|
|
* @param project The synchronized project
|
|
* @param root The PythonTreeRoot created before (optional)
|
|
* @param monitor A progress monitor
|
|
*/
|
|
public static void run(IProject project, PythonTreeRoot root, IProgressMonitor monitor) {
|
|
SyncCodeAction createCode = new SyncCodeAction();
|
|
createCode.setProject(project);
|
|
createCode.setRoot(root);
|
|
|
|
if (monitor == null) {
|
|
ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);
|
|
try {
|
|
dialog.run(false, true, createCode);
|
|
} catch (InterruptedException e) {e.printStackTrace();}
|
|
catch (InvocationTargetException e) {e.printStackTrace();}
|
|
} else {
|
|
createCode.doSync(monitor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* run this action (
|
|
*/
|
|
public void run(IAction action) {
|
|
ProgressMonitorDialog monitor = new ProgressMonitorDialog(null);
|
|
|
|
try {
|
|
monitor.run(false, true, this);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Do a synchronize run. This is the central method.
|
|
* It is called in automatic or manual mode
|
|
* @param monitor a ProgressMonitor
|
|
*/
|
|
public void doSync(IProgressMonitor monitor) {
|
|
// read project
|
|
IPath projectPath = project.getLocation();
|
|
String umlFileName=projectPath.
|
|
append(GlobalConstants.getPyUmlDir()).
|
|
append(project.getName()+".uml").toOSString();
|
|
|
|
String umlSavedFileName=projectPath.
|
|
append(GlobalConstants.getPyUmlDir()).
|
|
append(project.getName()+"-backup.uml").toOSString();
|
|
|
|
|
|
File savedModel = new File(umlSavedFileName);
|
|
File modelToCopy = new File(umlFileName);
|
|
|
|
// read newest Model
|
|
EObject diagramRoot = UMLToolsHelperMethods.loadUMLDiagram(umlFileName);
|
|
|
|
// read backuped Model if it exists
|
|
// to be able to see what changed between models
|
|
EObject diagramRootBackup = null;
|
|
if (savedModel.exists())
|
|
diagramRootBackup = UMLToolsHelperMethods.loadUMLDiagram(umlSavedFileName);
|
|
|
|
Model model = (Model) diagramRoot;
|
|
|
|
// get model -> xmi-id dictionary
|
|
UMLResource res = (UMLResource) model.eResource();
|
|
Map<EObject, String> modelXmiDict = res.getEObjectToIDMap();
|
|
|
|
// do the same for the backupModel:
|
|
// get model -> xmi-id dictionary
|
|
|
|
Map<String, EObject> xmiModelDictOld = new HashMap<String, EObject>();
|
|
int classCount = 0; // count classes for progression bar
|
|
if (diagramRootBackup != null) {
|
|
UMLResource resBack = (UMLResource) ((Model)diagramRootBackup).eResource();
|
|
Map<EObject, String> modelXmiDictOld = resBack.getEObjectToIDMap();
|
|
|
|
// create reverse dict, so that xmi_id can be the key
|
|
for (EObject modelObject : modelXmiDictOld.keySet()) {
|
|
String xmi_id = modelXmiDictOld.get(modelObject);
|
|
xmiModelDictOld.put(xmi_id, modelObject);
|
|
if (modelObject instanceof Classifier)
|
|
classCount++;
|
|
}
|
|
}
|
|
|
|
// create PythonTree from PythonCode
|
|
if (this.pythonRoot == null)
|
|
try {
|
|
this.pythonRoot = new PythonTreeRoot(this.project, true, monitor);
|
|
}
|
|
catch (PyUMLCancelledException e) {
|
|
MessageDialog.openWarning(null, "Operation cancelled",
|
|
"The Operation was cancelled by the user");
|
|
return;
|
|
}
|
|
catch (PyUMLParseException e) {
|
|
MessageDialog.openError(null, "Error parsing project code",
|
|
"There was an error parsing the python code of the current\n" +
|
|
"project.\n" +
|
|
"PyUML can not work as long as there are errors in the project code!\n" +
|
|
"Please resolve the error and try again!\n\n" +
|
|
"Error message was:\n\n"+
|
|
e.getMessage());
|
|
return;
|
|
}
|
|
|
|
|
|
// ######## Synchronize the Code ############################
|
|
monitor.beginTask("Synchronize the Python Code", IProgressMonitor.UNKNOWN);
|
|
try {
|
|
pythonRoot.synchronizeCode(model, modelXmiDict, xmiModelDictOld, monitor, classCount);
|
|
}
|
|
catch (PyUMLCancelledException e) {
|
|
MessageDialog.openWarning(null, "Operation cancelled",
|
|
"The Operation was cancelled by the user");
|
|
return;
|
|
} catch (Throwable t) {
|
|
t.printStackTrace();
|
|
MessageDialog.openError(null,"Error synchronizing Code!",
|
|
t.getClass().getName() + " while synchronizing Code!: \n\n"
|
|
+ t.getMessage());
|
|
}
|
|
|
|
|
|
// ##########################################################
|
|
|
|
|
|
// backup model -> copy new current model over old one
|
|
try{
|
|
JavaHelperMethods.copy(modelToCopy, savedModel);
|
|
EclipseHelperMethods.updateFile(savedModel.getAbsolutePath(), this.project);
|
|
} catch (IOException ex) {
|
|
MessageDialog.openError(null,ex.getMessage(),"Unable to copy model file to: " + umlSavedFileName
|
|
+"\nCode creation may not work properly!");
|
|
}
|
|
monitor.done();
|
|
}
|
|
|
|
/**
|
|
* Called by Eclipse. If a project is selected, it is saved
|
|
*/
|
|
public void selectionChanged(IAction action, ISelection selection) {
|
|
if (selection instanceof TreeSelection) {
|
|
TreeSelection ts = (TreeSelection) selection;
|
|
Object selectedElement = ts.getFirstElement();
|
|
if (selectedElement instanceof IProject) {
|
|
IProject project = (IProject) selectedElement;
|
|
this.project = project;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Get the used project
|
|
* @return
|
|
*/
|
|
public IProject getProject() {
|
|
return project;
|
|
}
|
|
|
|
/**
|
|
* Manually set the project to use
|
|
* @param project
|
|
*/
|
|
public void setProject(IProject project) {
|
|
this.project = project;
|
|
}
|
|
|
|
/**
|
|
* Manually set a PythonTreeRoot to use (if given,
|
|
* it will not be created again)
|
|
* @param root
|
|
*/
|
|
public void setRoot(PythonTreeRoot root) {
|
|
this.pythonRoot = root;
|
|
}
|
|
|
|
|
|
public void run(IProgressMonitor monitor) throws InvocationTargetException,
|
|
InterruptedException {
|
|
doSync(monitor);
|
|
}
|
|
}
|