Eclipse-PyUML/pyUml/src/pyUML/backend/UMLToolsHelperMethods.java

312 lines
12 KiB
Java
Executable File

package pyUML.backend;
import java.io.IOException;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.uml2.diagram.clazz.edit.parts.PackageEditPart;
import org.eclipse.uml2.diagram.clazz.part.Messages;
import org.eclipse.uml2.diagram.clazz.part.UMLDiagramEditor;
import org.eclipse.uml2.diagram.clazz.part.UMLDiagramEditorPlugin;
import org.eclipse.uml2.diagram.clazz.part.UMLDiagramEditorUtil;
import org.eclipse.uml2.diagram.clazz.part.UMLVisualIDRegistry;
import pyUML.listeners.LiveValidationListener;
import pyUML.listeners.ViewChangeListener;
import pyUML.views.EditView;
import pyUML.views.EditViewWizard;
/**
* This class contains methods for reading and writing eclipse
* UML models and for model handling
*/
public class UMLToolsHelperMethods {
/**
* Loads an eclipse UML2 model
*
* @param umlFileName a String containing the filename of the eclipse uml2 diagram
* @return the model root as EObject, null if an exception occured
*/
public static EObject loadUMLDiagram(String umlFileName) {
try {
Resource resource = new ResourceSetImpl().getResource(URI.createFileURI(umlFileName), true);
return resource.getContents().get(0);
/*for (EObject content : resource.getContents()) {
if (content instanceof Model)
return content;
}*/
//return null;
} catch (WrappedException ex) {
MessageDialog.openError(null,ex.getMessage(),"Unable to load model: " + umlFileName+"\n"+ex.getMessage());
return null;
}
}
/**
* opens a eclipse uml2tools UML diagram in the editor
* Will edit the diagram file, if a wrong path to a UML model is set
* (Unfortunately, UML diagrams save absolute paths of the corresponding
* UML file)
* @param project the current project
* @param diagramFile the fileName in the pyUml directory
* @param putToFront if the editor is already opened, with putToFront==true
* the editor is given the focus, with putToFront==false nothing is done
* @param umlModelName The name of the corresponding UML model to this model
* This is needed to ensure the diagram has a correct UML file path set
* @return the IEitorPat of the newly opened Diagram, null on Error
* @throws PartInitException
*/
public static IEditorPart openDiagram(IProject project, IFile diagramFile, String umlModelFileName, boolean putToFront) {
// see, if UML model path is set correctly
String absoluteUmlPath = project.getLocation().append(GlobalConstants.getPyUmlDir())
.append(umlModelFileName).toOSString();
String[] diagramFileContent = EclipseHelperMethods.iFileToString(diagramFile).split("\n");
for (int i =0; i< diagramFileContent.length; i++) {
String line = diagramFileContent[i];
Pattern pattern = Pattern.compile("(\\s*<element\\s*xmi:type=\"uml:Model\" href=\"file:)([^#]*)(#.*)");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
line = matcher.group(1) + absoluteUmlPath + matcher.group(3);
if (! diagramFileContent[i].equals(line)) {
diagramFileContent[i] = line;
EclipseHelperMethods.StringToIFile(diagramFile,
JavaHelperMethods.join(diagramFileContent, "\n"));
}
break;
}
}
IWorkbenchPage page =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
// if putToFront == false, return if editor is already opened
if (putToFront == false)
for (IEditorReference editor : page.getEditorReferences())
if (editor.getTitle().equals(diagramFile.getName()))
return editor.getEditor(false);
try{
IEditorPart ed = IDE.openEditor(page, diagramFile, UMLDiagramEditor.ID, false);
if (! diagramFile.toString().matches(".*"+project.getName()+GlobalConstants.getDiagramExtension())) {
ed.addPropertyListener(new ViewChangeListener(project));
}
ed.addPropertyListener(LiveValidationListener.getListenerSingleton());
LiveValidationListener.startLiveValidationInBackground();
/*
UMLDiagramEditor umlEd = (UMLDiagramEditor) ed;
umlEd.getDiagram().eResource().load(JavaHelperMethods.stringToStream(PyUMLProfile.getProfileString()), null);
umlEd.refresh();*/
return ed;
} catch (PartInitException e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Updates an opened Diagram, if it is already opened
* @param project the current project
* @param diagramFile the IFile of the diagram to refresh
* @param keepFocus if true, workbench focus (currently opened document) is kept open.
* @return true, if a diagram was found and updated
*/
public static IEditorPart refreshDiagramEditor(IProject project, IFile diagramFile, boolean keepFocus){
IWorkbenchPage page =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
// save active Editor to keep focus
IEditorPart activeEditor = page.getActiveEditor();
//activeEditor.getEditorSite().getId();
String activeEditorName = null;
if (activeEditor != null)
activeEditorName = activeEditor.getTitle();
// look for editor to update
IEditorReference editor = EclipseHelperMethods.firstOpenEditorByName(diagramFile.getName());
if (editor == null)
return null;
// close and open editor again
page.closeEditor(editor.getEditor(true), true);
try{
IEditorPart newEditor = IDE.openEditor(page, diagramFile, UMLDiagramEditor.ID, true);
if (! diagramFile.toString().matches(".*"+project.getName()+GlobalConstants.getDiagramExtension())) {
newEditor.addPropertyListener(new ViewChangeListener(project));
}
EclipseHelperMethods.saveAllOpenEditors();
// activate old active editor
if (keepFocus && activeEditor != null && (! newEditor.getTitle().equals(activeEditorName)))
page.activate(activeEditor);
return newEditor;
} catch (PartInitException e) {
e.printStackTrace();
return null;
}
catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* creates a graphical eclipse UML2TOOLS UML model diagram out of
* a Eclipse UML2 File.
*/
public static void createModelDiagram(EObject modelObject, IFile newDiagramFile) {
org.eclipse.emf.transaction.TransactionalEditingDomain editingDomain =
GMFEditingDomainFactory.INSTANCE.createEditingDomain();
List<IFile> affectedFiles = new Vector<IFile>();
final org.eclipse.uml2.uml.Package model
= (org.eclipse.uml2.uml.Package) modelObject;
URI diagramModelURI = URI.createPlatformResourceURI(newDiagramFile.getFullPath().toString(), true);
ResourceSet resourceSet = editingDomain.getResourceSet();
final Resource diagramResource = resourceSet.createResource(diagramModelURI);
affectedFiles.add(newDiagramFile);
// create diagram from model
AbstractTransactionalCommand command = new AbstractTransactionalCommand(editingDomain, Messages.UMLNewDiagramFileWizard_InitDiagramCommand, affectedFiles) {
public CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) {
int diagramVID = UMLVisualIDRegistry.getDiagramVisualID(model);
if (diagramVID != PackageEditPart.VISUAL_ID) {
return CommandResult.newErrorCommandResult(Messages.UMLNewDiagramFileWizard_IncorrectRootError);
}
Diagram diagram = ViewService.createDiagram(model, PackageEditPart.MODEL_ID, UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
diagramResource.getContents().add(diagram);
return CommandResult.newOKCommandResult();
}
};
// save the created diagram file
try {
OperationHistoryFactory.getOperationHistory().execute(command, new NullProgressMonitor(), null);
diagramResource.save(UMLDiagramEditorUtil.getSaveOptions());
} catch (org.eclipse.core.commands.ExecutionException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
// change full path file name to relative path
String diagramFileContent = EclipseHelperMethods.iFileToString(newDiagramFile);//.split("\n");
Pattern pattern = Pattern.compile( "(.*<element xmi:type=\"uml:Model\" href=\")file:([^#]*)(.*)");
Matcher matcher = pattern.matcher(diagramFileContent);
if (! matcher.find()){
return;
}
// write the new method definition line
String newDiagramLine = matcher.group(1) + model.getName()+".uml" + matcher.group(3);
// replace line
String newDiagramFileContent = "";
String[] fileContentLines = diagramFileContent.split("\n");
for (int i=0; i<fileContentLines.length; i++) {
if (fileContentLines[i].equals(matcher.group(0)))
newDiagramFileContent += newDiagramLine + "\n";
else
newDiagramFileContent += fileContentLines[i] + "\n";
}
EclipseHelperMethods.StringToIFile(newDiagramFile, newDiagramFileContent);
}
/**
* As a UML diagram is not updated automatically, when .uml file changed,
* we need to manually reload the diagram
* @param project
* @param exceptViewName A name of a view to be excluded from refresh.
* This is useful if a view change is the source of the refreshes.
* Can be null.
* @param onlyIfViewsNotLocked if false, the update will be done any time.
* if false, it will be only done if views are not locked.
*/
public static void updateModelAndViewPages(IProject project) {
// refresh all pyUML.views
IFolder pyUmlDir = project.getFolder(GlobalConstants.getPyUmlDir());
// keep active editor name to activate it afterwards
String activeEditorName = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().getActiveEditor().getTitle();
try {
for (IResource entry :pyUmlDir.members()) {
if (entry instanceof IFile) {
IFile file = (IFile) entry;
if (file.getName().matches("^.*"+GlobalConstants.getViewConfExtension()+"$")) {
String viewDiagramName = updateViewModel(project, file);
refreshDiagramEditor(project,
project.getFile(new org.eclipse.core.runtime.Path(GlobalConstants.getPyUmlDir()).append(viewDiagramName).toOSString())
, true);
}
}
}
// set focus to formerly opened editor page
IEditorReference formerlyOpenedEditor = EclipseHelperMethods.firstOpenEditorByName(activeEditorName);
if (formerlyOpenedEditor != null)
formerlyOpenedEditor.getEditor(true).setFocus();
} catch (CoreException e) {e.printStackTrace();}
//ViewChangeListener.setListenersEnabled(lockBeforeExecution);
}
/**
* Updates the model underlying model of a view by the main model
* @param project The current project
* @param file The View conf file
* @return
*/
public static String updateViewModel(IProject project, IFile file) {
String viewName = file.getName().replace(GlobalConstants.getViewConfExtension(), "");
EditView view = new EditView(project, file, viewName, false);
EditViewWizard wiz = view.getEditViewWizard();
wiz.addPages();
wiz.getPartsPage().addPackagedXmiIds();
wiz.performFinish(false);
String viewDiagramName = viewName+GlobalConstants.getDiagramExtension();
return viewDiagramName;
}
}