package damp.ekeko.snippets.gui;
import java.net.URI;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import clojure.lang.IFn;
import damp.ekeko.snippets.EkekoSnippetsPlugin;
import damp.ekeko.snippets.data.TemplateGroup;
public class TransformationEditor extends MultiPageEditorPart {
public static IFn FN_SERIALIZE_TRANSFORMATION;
public static IFn FN_DESERIALIZE_TRANSFORMATION;
public static IFn FN_MAKE_TRANSFORMATION;
public static IFn FN_TRANSFORMATION_LHS;
public static IFn FN_TRANSFORMATION_RHS;
//returns a fresh clojure representation of a transformation
//of which the lhs/rhs corresponds to the nested editors
//might have to be changed to a mutable Java class later on
//(analogous to TemplateGroup)
public Object getTransformation() {
TemplateGroup lhsGroup = subjectsEditor.getGroup();
Object cljLHSGroup = lhsGroup.getGroup();
TemplateGroup rhsGroup = rewritesEditor.getGroup();
Object cljRHSGroup = rhsGroup.getGroup();
return FN_MAKE_TRANSFORMATION.invoke(cljLHSGroup, cljRHSGroup);
}
public Object getLHSOfTransformation(Object cljTransformation) {
return FN_TRANSFORMATION_LHS.invoke(cljTransformation);
}
public Object getRHSOfTransformation(Object cljTransformation) {
return FN_TRANSFORMATION_RHS.invoke(cljTransformation);
}
public static void serializeClojureTransformation(Object transformation, String fullPathToFile) {
FN_SERIALIZE_TRANSFORMATION.invoke(fullPathToFile, transformation);
}
public static Object deserializeClojureTransformation(String fullPathToFile) {
return FN_DESERIALIZE_TRANSFORMATION.invoke(fullPathToFile);
}
public static final String ID = "damp.ekeko.snippets.gui.TransformationEditor"; //$NON-NLS-1$
private SubjectsTemplateEditor subjectsEditor;
private int subjectsEditorPageIndex;
private RewritesTemplateEditor rewritesEditor;
private int rewritesEditorPageIndex;
private TemplateGroup lhsTemplateGroup;
private TemplateGroup rhsTemplateGroup;
private TransformationOverviewEditor overviewEditor;
private int overviewEditorPageIndex;
public void initSubInputsFromTransformationFile(String fullPath) {
Object cljTransformation = deserializeClojureTransformation(fullPath);
Object cljLHS = getLHSOfTransformation(cljTransformation);
Object cljRHS = getRHSOfTransformation(cljTransformation);
lhsTemplateGroup = TemplateGroup.newFromClojureGroup(cljLHS);
rhsTemplateGroup = TemplateGroup.newFromClojureGroup(cljRHS);
//still null at this moment
//subjectsEditor.setGroup(lhsTemplateGroup);
//rewritesEditor.setGroup(rhsTemplateGroup);
}
@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
setSite(site);
updateInput(input);
}
private void updateInput(IEditorInput input) throws PartInitException {
setPartName(input.getName());
lhsTemplateGroup = TemplateGroup.newFromGroupName("LHS");
rhsTemplateGroup = TemplateGroup.newFromGroupName("RHS");
if(input instanceof FileStoreEditorInput
|| input instanceof FileEditorInput) {
String pathToFile = "";
if(input instanceof FileStoreEditorInput) {
//outside workspace
FileStoreEditorInput fileInput = (FileStoreEditorInput) input;
URI uri = fileInput.getURI();
pathToFile = uri.getPath();
} else
if(input instanceof FileEditorInput) {
//within workspace
FileEditorInput fileInput = (FileEditorInput) input;
IFile ifile = fileInput.getFile();
pathToFile = ifile.getLocation().toString();
} else {
setInput(new TransformationEditorInput());
return;
}
TransformationEditorInput actualInput = new TransformationEditorInput();
actualInput.setPathToPersistentFile(pathToFile);
setInput(actualInput);
try {
initSubInputsFromTransformationFile(pathToFile);
} catch (Exception e) {
e.printStackTrace();
}
return;
}
if(input instanceof TransformationEditorInput) {
ClojureFileEditorInput actualInput = (ClojureFileEditorInput) input;
if(actualInput.associatedPersistentFileExists()) {
try {
initSubInputsFromTransformationFile(actualInput.getPathToPersistentFile());
} catch (Exception e) {
e.printStackTrace();
}
}
setInput(input);
return;
}
throw new PartInitException("Unexpected input for TransformationEditor: " + input.toString());
}
protected void onExecuteTransformation() {
// CompareUI.openCompareDialog(input);
// TODO Auto-generated method stub
TemplateGroup.transformBySnippetGroups(subjectsEditor.getGroup().getGroup(), rewritesEditor.getGroup().getGroup());
}
@Override
protected void createPages() {
try {
createOverviewPage();
createSubjectsPage();
createRewritesPage();
//overviewEditor.setFocus();
} catch (PartInitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public TransformationEditorInput getTransformationEditorInput() {
return (TransformationEditorInput) getEditorInput();
}
public TemplateEditor getSubjectsEditor() {
return subjectsEditor;
}
public TemplateEditor getRewritesEditor() {
return rewritesEditor;
}
public TemplateEditorInput getSubjectsEditorInput() {
return getTransformationEditorInput().getSubjectsEditorInput();
}
public TemplateEditorInput getRewritesEditorInput() {
return getTransformationEditorInput().getRewritesEditorInput();
}
private void createRewritesPage() throws PartInitException {
rewritesEditor = new RewritesTemplateEditor();
rewritesEditorPageIndex = addPage(rewritesEditor, getRewritesEditorInput());
rewritesEditor.setGroup(rhsTemplateGroup);
setPageText(rewritesEditorPageIndex, "Replacement Templates");
setPageImage(rewritesEditorPageIndex, EkekoSnippetsPlugin.IMG_TRANSFORMATION);
rewritesEditor.setTransformationEditor(this);
}
private void createSubjectsPage() throws PartInitException {
subjectsEditor = new SubjectsTemplateEditor();
subjectsEditorPageIndex = addPage(subjectsEditor, getSubjectsEditorInput());
subjectsEditor.setGroup(lhsTemplateGroup);
setPageText(subjectsEditorPageIndex, "Search Templates");
setPageImage(subjectsEditorPageIndex, EkekoSnippetsPlugin.IMG_TEMPLATE);
}
private void createOverviewPage() throws PartInitException {
overviewEditor = new TransformationOverviewEditor();
overviewEditorPageIndex = addPage(overviewEditor, null);
setPageText(overviewEditorPageIndex, "Overview");
setPageImage(overviewEditorPageIndex, EkekoSnippetsPlugin.IMG_TEMPLATE);
overviewEditor.setTransformationEditor(this);
}
@Override
public void doSave(IProgressMonitor monitor) {
IEditorInput input = getEditorInput();
if(!(input instanceof TransformationEditorInput))
return;
String absoluteFilePathString;
ClojureFileEditorInput teinput = (ClojureFileEditorInput) input;
if(!teinput.isAssociatedWithPersistentFile()) {
FileDialog fileDialog = new FileDialog(getSite().getShell(), SWT.SAVE);
fileDialog.setFilterExtensions(new String[] { "*.ekx" });
fileDialog.setFilterNames(new String[] { "Ekeko/X transformation file (*.ekx)" });
absoluteFilePathString = fileDialog.open();
if(absoluteFilePathString == null)
return;
teinput.setPathToPersistentFile(absoluteFilePathString);
} else {
absoluteFilePathString = teinput.getPathToPersistentFile();
}
try {
Object transformation = getTransformation();
serializeClojureTransformation(transformation, absoluteFilePathString);
subjectsEditor.becomeClean();
rewritesEditor.becomeClean();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void doSaveAs() {
IEditorInput input = getEditorInput();
if(!(input instanceof TransformationEditorInput))
return;
TransformationEditorInput newInput = new TransformationEditorInput();
setInput(newInput); //fires no prop change, only sets field
try {
doSave(new NullProgressMonitor()); //serializes to new file
updateInput(newInput); //deserializes from file
} catch (Exception e) {
e.printStackTrace();
setInput(input);
}
}
@Override
public boolean isSaveAsAllowed() {
return true;
}
@Override
protected void handlePropertyChange(int propertyId) {
if(propertyId == PROP_DIRTY) {
//one of the nested editors has become dirty
//could update our clojure representation of the corresponding transformation
//for now, simply recreating this representation on demand
}
super.handlePropertyChange(propertyId);
}
public void setPreviouslyActiveEditor(IEditorPart activeEditor) {
subjectsEditor.setPreviouslyActiveEditor(activeEditor);
rewritesEditor.setPreviouslyActiveEditor(activeEditor);
}
}