blob: ba730d5905b7d8a2adb0224d6c993b4ca39f148b [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S. and other
* 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:
* Thales Corporate Services S.A.S - initial API and implementation
* XiaoRu Chen, Soyatec
*
* </copyright>
*/
package org.eclipse.egf.pattern.ui.editors.templateEditor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.egf.core.EGFCorePlugin;
import org.eclipse.egf.core.fcore.IPlatformFcore;
import org.eclipse.egf.core.platform.pde.IPlatformBundle;
import org.eclipse.egf.model.fcore.FcorePackage;
import org.eclipse.egf.model.pattern.Pattern;
import org.eclipse.egf.model.pattern.PatternMethod;
import org.eclipse.egf.pattern.engine.PatternHelper;
import org.eclipse.egf.pattern.ui.Activator;
import org.eclipse.egf.pattern.ui.Messages;
import org.eclipse.egf.pattern.ui.editors.PatternEditorInput;
import org.eclipse.egf.pattern.ui.editors.PatternMethodEditorInput;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.text.Position;
import org.eclipse.pde.core.IBaseModel;
import org.eclipse.pde.core.plugin.IPluginBase;
import org.eclipse.pde.core.plugin.IPluginExtension;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.WorkbenchPage;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
/**
* @author XiaoRu Chen - Soyatec
*
*/
public abstract class AbstractTemplateEditor extends MultiPageEditorPart {
private String projectName = "___templateproject";
protected IEditorPart openEditor;
protected Map<String, Position> startPositions = new HashMap<String, Position>();
protected WorkbenchPage templateActivePage;
protected Map<String, TextEditor> editorMap = new HashMap<String, TextEditor>();
protected List<TextEditor> editorList = new ArrayList<TextEditor>();
private static final String JET_TRANSFORM_POINT_ID = "org.eclipse.jet.transform";
private static final String PLUGIN_EDITOR_ID = "org.eclipse.pde.ui.manifestEditor";
// The adapter is for refreshing the editor title while the name of pattern
// has been changed.
AdapterImpl patternAdapter = new AdapterImpl() {
public void notifyChanged(Notification msg) {
if (FcorePackage.Literals.NAMED_MODEL_ELEMENT__NAME.equals(msg.getFeature())) {
setPartName((String) msg.getNewValue());
} else if (msg.getFeature() instanceof EReference) {
EReference ref = (EReference) msg.getFeature();
if ("methods".equals(ref.getName())) {
refreshTemplateEditor(msg);
}
}
}
};
AdapterImpl methodAdapter = new AdapterImpl() {
public void notifyChanged(Notification msg) {
if (FcorePackage.Literals.NAMED_MODEL_ELEMENT__NAME.equals(msg.getFeature())) {
executeMethodEditorRename();
}
}
};
public AbstractTemplateEditor() {
super();
}
protected abstract void initProblems();
protected abstract void divideByMethods();
public abstract void setActivePage(String methodId);
public void doSave(IProgressMonitor monitor) {
for (int i = 0; i < getPageCount(); i++)
getEditor(i).doSave(monitor);
}
public void doSaveAs() {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc) Method declared on IEditorPart
*/
public void gotoMarker(IMarker marker) {
setActivePage(0);
IDE.gotoMarker(getEditor(0), marker);
}
/**
* The <code>MultiPageEditorExample</code> implementation of this method
* checks that the input is an instance of <code>IFileEditorInput</code>.
*/
public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
if (!(editorInput instanceof PatternEditorInput))
throw new PartInitException(Messages.Editor_wrong_input);
super.init(site, editorInput);
}
/*
* (non-Javadoc) Method declared on IEditorPart.
*/
public boolean isSaveAsAllowed() {
return false;
}
public Pattern getPattern() {
PatternEditorInput input = (PatternEditorInput) getEditorInput();
if (input == null)
throw new IllegalStateException();
return input.getPattern();
}
public IEditorPart initEditor(IFile templateFile) throws CoreException {
try {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
templateActivePage = new WorkbenchPage((WorkbenchWindow) activeWorkbenchWindow, null);
if (templateActivePage == null || templateFile == null)
return null;
// TO ensure the JetEditor is used instead of the default one.
return templateActivePage.openEditor(new FileEditorInput(templateFile), getDelegateEditorID(), false);
} catch (PartInitException e) {
Activator.getDefault().logError(e);
}
return null;
}
protected abstract String getDelegateEditorID();
protected IFile setPublicTemplateEditor(Pattern pattern, EList<PatternMethod> methods, String fileExtention) {
IFile templateFile = null;
try {
Resource eResource = pattern.eResource();
IPlatformFcore platformFcore = EGFCorePlugin.getPlatformFcore(eResource);
IPlatformBundle platformBundle = platformFcore.getPlatformBundle();
IProject project = platformBundle.getProject();
NullProgressMonitor monitor = new NullProgressMonitor();
String tempProjectName = "." + project.getName() + projectName;
IProject templateProject = ResourcesPlugin.getWorkspace().getRoot().getProject(tempProjectName);
if (!templateProject.exists()) {
// Delete project content in disk.
getTemplateProject(templateProject, tempProjectName, monitor);
templateProject.delete(true, true, monitor);
// Create new template project.
getTemplateProject(templateProject, tempProjectName, monitor);
ConvertPluginProjectOperation convert = new ConvertPluginProjectOperation(templateProject, platformBundle);
convert.execute(monitor);
}
IFolder src = templateProject.getFolder("src");
if (!src.exists()) {
src.create(true, false, null);
}
// Filter the template project extensions.
filterUselessExtension(templateProject, monitor);
templateFile = src.getFile(fileExtention);
if (!templateFile.exists()) {
templateFile.create(new ByteArrayInputStream(new byte[0]), true, null);
} else {
templateFile.setContents(new ByteArrayInputStream(new byte[0]), true, false, null);
}
PatternMethod footMethod = null;
for (PatternMethod method : methods) {
if (method.equals(pattern.getFooterMethod())) {
footMethod = method;
continue;
}
visitMethod(project, method, templateFile, true);
}
visitMethod(project, footMethod, templateFile, false);
openEditor = initEditor(templateFile);
} catch (Exception e) {
// Ignore
}
return templateFile;
}
private void visitMethod(IProject project, PatternMethod method, IFile templateFile, boolean seprator) throws CoreException, IOException {
IFile file = project.getFile(method.getPatternFilePath().path());
if (!file.exists()) {
file.create(new ByteArrayInputStream(new byte[0]), true, null);
}
templateFile.appendContents(file.getContents(), false, false, null);
if (seprator) {
templateFile.appendContents(new StringBufferInputStream("\n"), true, false, null);
}
int startPosition = TemplateEditorUtility.getStartPosition(startPositions);
int length = TemplateEditorUtility.getSourceLength(file.getContents());
Position position = new Position(startPosition, length);
startPositions.put(method.getName(), position);
}
/**
* While pattern has been changed, refresh the editor title.
*/
protected void addPatternChangeAdapter(final Pattern pattern) {
if (pattern != null && !pattern.eAdapters().contains(patternAdapter)) {
pattern.eAdapters().add(patternAdapter);
EList<PatternMethod> methods = pattern.getMethods();
for (PatternMethod method : methods) {
addMethodChangeAdapter(method);
}
}
}
/**
* While method has been changed, refresh the editor title.
*/
protected void addMethodChangeAdapter(PatternMethod method) {
if (method != null && !method.eAdapters().contains(methodAdapter)) {
method.eAdapters().add(methodAdapter);
}
}
/**
* Remove the Adapter add for refreshing the editor title
*/
protected void removePatternChangeAdapter() {
Pattern pattern = getPattern();
if (pattern != null && pattern.eAdapters().contains(patternAdapter)) {
pattern.eAdapters().remove(patternAdapter);
}
if (pattern != null) {
EList<PatternMethod> methods = pattern.getMethods();
for (PatternMethod method : methods) {
removeMethodChangeAdapter(method);
}
}
}
/**
* Remove the Adapter add for refreshing the editor title
*/
protected void removeMethodChangeAdapter(PatternMethod method) {
if (method != null && method.eAdapters().contains(methodAdapter)) {
method.eAdapters().remove(methodAdapter);
}
}
public WorkbenchPage getTemplateActivePage() {
return templateActivePage;
}
/**
* Refresh the template editor while user change the content of pattern's
* methods.
*/
private void refreshTemplateEditor(Notification msg) {
Object newValue = msg.getNewValue();
Object oldValue = msg.getOldValue();
int eventType = msg.getEventType();
if ((newValue != null && newValue instanceof PatternMethod) || (newValue == null && oldValue instanceof PatternMethod)) {
switch (eventType) {
case Notification.ADD:
executeMethodEditorAdd((PatternMethod) newValue);
break;
case Notification.REMOVE:
executeMethodEditorRemove((PatternMethod) oldValue);
break;
case Notification.MOVE:
executeMethodEditorsReorder((PatternMethod) newValue, oldValue);
break;
default:
return;
}
}
}
private void executeMethodEditorRename() {
for (TextEditor editor : editorList) {
PatternMethod patternMethod = ((PatternMethodEditorInput) editor.getEditorInput()).getPatternMethod();
if (patternMethod != null) {
int index = getIndexOfMethodEditor(editor);
if (index != -1)
setPageText(index, patternMethod.getName());
}
}
}
private void executeMethodEditorRemove(PatternMethod deleteMethod) {
for (int i = 0; i < this.getPageCount(); i++) {
IEditorPart currentEditor = this.getEditor(i);
IEditorInput editorInput = currentEditor.getEditorInput();
if (editorInput instanceof PatternMethodEditorInput) {
PatternMethod patternMethod = ((PatternMethodEditorInput) editorInput).getPatternMethod();
if (patternMethod == null) {
removePage(i);
removeEditor(currentEditor);
}
}
}
}
private void removeEditor(IEditorPart editor) {
editorList.remove(editor);
Set<Entry<String, TextEditor>> entrySet = editorMap.entrySet();
for (Entry<String, TextEditor> entry : entrySet) {
if (entry.getValue().equals(editor)) {
editorMap.remove(entry.getKey());
return;
}
}
}
protected void executeMethodEditorAdd(PatternMethod addMethod) {
addMethodChangeAdapter(addMethod);
}
protected void addEditor(TextEditor editor, PatternMethod method) {
try {
PatternMethodEditorInput input = new PatternMethodEditorInput(method.eResource(), method.getID());
int index = addPage(editor, input);
setPageText(index, method.getName());
editorMap.put(method.getID(), editor);
editorList.add(editor);
} catch (PartInitException e) {
Activator.getDefault().logError(e);
}
}
protected void setPatternFilePath(PatternMethod addMethod) {
URI computeFileURI = PatternHelper.Filename.computeFileURI(addMethod);
addMethod.setPatternFilePath(computeFileURI);
}
protected void executeMethodEditorsReorder(PatternMethod moveMethod, Object oldValue) {
int newIndex = getPattern().getMethods().indexOf(moveMethod);
if (oldValue instanceof Integer) {
int oldIndex = (Integer) oldValue;
String id = moveMethod.getID();
TextEditor textEditor = editorMap.get(id);
if (textEditor.isDirty()) {
textEditor.doSave(null);
}
removePage(oldIndex);
editorMap.remove(id);
editorList.remove(textEditor);
try {
TextEditor newEditor = createNewEditor();
PatternMethodEditorInput input = new PatternMethodEditorInput(moveMethod.eResource(), id);
addPage(newIndex, newEditor, input);
editorMap.put(id, newEditor);
editorList.add(newIndex, newEditor);
} catch (PartInitException e) {
Activator.getDefault().logError(e);
}
setPageText(newIndex, moveMethod.getName());
}
}
protected int getIndexOfMethodEditor(TextEditor editor) {
int index = -1;
for (int i = 0; i < this.getPageCount(); i++) {
IEditorPart currentEditor = this.getEditor(i);
if (editor.equals(currentEditor)) {
index = i;
break;
}
}
return index;
}
public void filterUselessExtension(IProject project, NullProgressMonitor monitor) {
IFile plugInFile = project.getFile(ConvertPluginProjectOperation.F_PLUGIN);
if (plugInFile.exists()) {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
try {
WorkbenchPage templateActivePage = new WorkbenchPage((WorkbenchWindow) activeWorkbenchWindow, null);
IEditorPart part = IDE.openEditor(templateActivePage, plugInFile, PLUGIN_EDITOR_ID);
if (part instanceof ManifestEditor) {
ManifestEditor editor = (ManifestEditor) part;
IBaseModel base = editor.getAggregateModel();
if (base instanceof IBundlePluginModelBase) {
IBundlePluginModelBase bundlePluginModel = (IBundlePluginModelBase) base;
IPluginBase pluginBase = bundlePluginModel.getPluginBase();
IPluginModelBase pluginModel = pluginBase.getPluginModel();
IPluginExtension[] extensions = pluginModel.getPluginBase().getExtensions();
for (IPluginExtension currentExtension : extensions) {
String point = currentExtension.getPoint();
if (!JET_TRANSFORM_POINT_ID.equals(point)) {
try {
pluginModel.getPluginBase().remove(currentExtension);
} catch (CoreException e) {
Activator.getDefault().logError(e);
}
}
}
part.doSave(monitor);
}
}
part.dispose();
} catch (WorkbenchException e) {
Activator.getDefault().logError(e);
}
}
}
public Map<String, TextEditor> getEditorMap() {
return editorMap;
}
public List<TextEditor> getEditorList() {
return editorList;
}
protected abstract TextEditor createNewEditor();
private void getTemplateProject(IProject templateProject, String tempProjectName, NullProgressMonitor monitor) {
IJavaProject javaProject = TemplateEditorUtility.createJavaProject(tempProjectName, monitor);
templateProject = javaProject.getProject();
}
@Override
public void dispose() {
removePatternChangeAdapter();
super.dispose();
}
}