Bug 426397 - Provide an eclipse editor based on OrionEditorControl

Implemented revert feature.

Change-Id: I382ae1d57f3599b18e3625b916616a07cf7ba433
Signed-off-by: Leo Denault <ldena023@uottawa.ca>
diff --git a/bundles/org.eclipse.e4.tools.orion.text.editor/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.tools.orion.text.editor/META-INF/MANIFEST.MF
index 31dc62f..21c3a9c 100644
--- a/bundles/org.eclipse.e4.tools.orion.text.editor/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.e4.tools.orion.text.editor/META-INF/MANIFEST.MF
@@ -12,4 +12,5 @@
  org.eclipse.ui.ide;bundle-version="3.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.e4.tools.orion.text.editor
+Export-Package: org.eclipse.e4.tools.orion.text.editor,
+ org.eclipse.e4.tools.orion.text.editor.handlers
diff --git a/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditor.java b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditor.java
index fa88e77..beb1750 100755
--- a/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditor.java
+++ b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditor.java
@@ -28,14 +28,17 @@
 import org.eclipse.e4.tools.orion.editor.builder.js.JSBuilder;
 import org.eclipse.e4.tools.orion.editor.swt.IDirtyListener;
 import org.eclipse.e4.tools.orion.editor.swt.OrionEditorControl;
+import org.eclipse.e4.tools.orion.text.editor.handlers.RevertOrionEditorHandler;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.EditorPart;
 import org.eclipse.ui.part.FileEditorInput;
 
@@ -105,11 +108,7 @@
 			}
 		} catch (Exception e) {
 			success = false;
-			Activator
-					.getDefault()
-					.getLog()
-					.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
-							"Failed to save file", e));
+			logError("Failed to save file", e);
 		}
 
 		if (success) {
@@ -133,6 +132,12 @@
 		setInput(input);
 		setPartName(input.getName());
 
+		// Set up the revert file handler
+		IHandlerService handlerService = (IHandlerService) site
+				.getService(IHandlerService.class);
+		handlerService.activateHandler(IWorkbenchCommandConstants.FILE_REVERT,
+				new RevertOrionEditorHandler(this));
+
 		FileEditorInput fileInput = ((FileEditorInput) input);
 		if (fileInput != null) {
 			source = fileInput.getFile();
@@ -173,11 +178,7 @@
 			control.addDirtyListener(this);
 			control.setText(text);
 		} catch (Exception e) {
-			Activator
-					.getDefault()
-					.getLog()
-					.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
-							"Failed to load file", e));
+			logError("Failed to load file", e);
 		}
 	}
 
@@ -245,6 +246,28 @@
 		firePropertyChange(ISaveablePart.PROP_DIRTY);
 	}
 
+	public void revert() {
+		if (control != null) {
+			if (source == null) {
+				control.setText("");
+			} else {
+				try {
+					control.setText(loadFile(source.getContents(), 1024));
+					control.setDirty(false);
+				} catch (Exception e) {
+					logError("Failed to revert file", e);
+				}
+			}
+		}
+	}
+
+	private void logError(String message, Exception e) {
+		Activator
+				.getDefault()
+				.getLog()
+				.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e));
+	}
+
 	private IStatusLineManager getStatusLineManager() {
 		return getEditorSite().getActionBars().getStatusLineManager();
 	}
diff --git a/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditorActionBarContributor.java b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditorActionBarContributor.java
index 8128f1a..b8406bc 100644
--- a/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditorActionBarContributor.java
+++ b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/OrionEditorActionBarContributor.java
@@ -10,27 +10,8 @@
  *******************************************************************************/
 package org.eclipse.e4.tools.orion.text.editor;
 
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorActionBarContributor;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.part.EditorActionBarContributor;
 
-public class OrionEditorActionBarContributor implements
-		IEditorActionBarContributor {
-
-	@Override
-	public void init(IActionBars bars, IWorkbenchPage page) {
-		// Intentionally empty.
-	}
-
-	@Override
-	public void setActiveEditor(IEditorPart targetEditor) {
-		// Intentionally empty.
-	}
-
-	@Override
-	public void dispose() {
-		// Intentionally empty.
-	}
-
+public class OrionEditorActionBarContributor extends EditorActionBarContributor {
+	// Intentionally empty
 }
diff --git a/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/handlers/RevertOrionEditorHandler.java b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/handlers/RevertOrionEditorHandler.java
new file mode 100644
index 0000000..ac45e66
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.orion.text.editor/src/org/eclipse/e4/tools/orion/text/editor/handlers/RevertOrionEditorHandler.java
@@ -0,0 +1,33 @@
+package org.eclipse.e4.tools.orion.text.editor.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.e4.tools.orion.text.editor.OrionEditor;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.ISaveablePart;
+
+public class RevertOrionEditorHandler extends AbstractHandler implements
+		IPropertyListener {
+
+	private OrionEditor editor;
+
+	public RevertOrionEditorHandler(OrionEditor editor) {
+		this.editor = editor;
+		setBaseEnabled(editor.isDirty());
+		editor.addPropertyListener(this);
+	}
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		editor.revert();
+		return null;
+	}
+
+	@Override
+	public void propertyChanged(Object source, int propId) {
+		if (editor.equals(source) && propId == ISaveablePart.PROP_DIRTY) {
+			setBaseEnabled(editor.isDirty());
+		}
+	}
+}
diff --git a/tests/org.eclipse.e4.tools.orion.text.editor.test/META-INF/MANIFEST.MF b/tests/org.eclipse.e4.tools.orion.text.editor.test/META-INF/MANIFEST.MF
index 223421f..dc34ca4 100755
--- a/tests/org.eclipse.e4.tools.orion.text.editor.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.e4.tools.orion.text.editor.test/META-INF/MANIFEST.MF
@@ -10,7 +10,8 @@
  org.eclipse.core.resources;bundle-version="3.9.0",
  org.eclipse.ui.ide;bundle-version="3.10.0",
  org.eclipse.e4.tools.orion.text.editor;bundle-version="0.16.0",
- org.eclipse.e4.tools.orion.editor;bundle-version="0.15.0"
+ org.eclipse.e4.tools.orion.editor;bundle-version="0.15.0",
+ org.mockito;bundle-version="1.8.4"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Import-Package: org.eclipse.ui.tests.harness.util
diff --git a/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTest.java b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTest.java
index d6b7246..0487256 100644
--- a/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTest.java
+++ b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTest.java
@@ -248,4 +248,21 @@
 			fail("The PartInitException should be caught internally.");
 		}
 	}
+
+	public void testRevertFile() throws Throwable {
+		proj = FileUtil.createProject("testOpenEditor");
+		String fileContents = "#simple {display: inline-block;}";
+
+		IFile file = FileUtil.createFile("test.css", proj);
+		InputStream in = new ByteArrayInputStream(
+				fileContents.getBytes("UTF-8"));
+		file.setContents(in, IFile.NONE, null);
+		IEditorPart editor = openEditor(file);
+
+		OrionEditor orionEditor = (OrionEditor) editor;
+		orionEditor.setContents(".newCss {display: none;}");
+		assertTrue(orionEditor.isDirty());
+		orionEditor.revert();
+		assertEquals(fileContents, orionEditor.getContents());
+	}
 }
diff --git a/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTestSuite.java b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTestSuite.java
index 6e0d1d8..d470b2c 100644
--- a/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTestSuite.java
+++ b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/OrionEditorTestSuite.java
@@ -18,9 +18,10 @@
 
 	public static Test suite() {
 		TestSuite suite = new TestSuite(OrionEditorTestSuite.class.getName());
-		//$JUnit-BEGIN$
+		// $JUnit-BEGIN$
 		suite.addTestSuite(OrionEditorTest.class);
-		//$JUnit-END$
+		suite.addTestSuite(RevertOrionEditorHandlerTest.class);
+		// $JUnit-END$
 		return suite;
 	}
 }
diff --git a/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/RevertOrionEditorHandlerTest.java b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/RevertOrionEditorHandlerTest.java
new file mode 100644
index 0000000..a1acab3
--- /dev/null
+++ b/tests/org.eclipse.e4.tools.orion.text.editor.test/src/org/eclipse/e4/tools/orion/text/editor/test/RevertOrionEditorHandlerTest.java
@@ -0,0 +1,69 @@
+package org.eclipse.e4.tools.orion.text.editor.test;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import junit.framework.TestCase;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.e4.tools.orion.text.editor.OrionEditor;
+import org.eclipse.e4.tools.orion.text.editor.handlers.RevertOrionEditorHandler;
+import org.eclipse.ui.ISaveablePart;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class RevertOrionEditorHandlerTest extends TestCase {
+
+	private RevertOrionEditorHandler handler;
+
+	@Mock
+	private OrionEditor mockEditor;
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		MockitoAnnotations.initMocks(this);
+		when(mockEditor.isDirty()).thenReturn(false);
+		handler = new RevertOrionEditorHandler(mockEditor);
+	}
+
+	public void testExecuteCallsOrionEditorRevert() throws ExecutionException {
+		handler = new RevertOrionEditorHandler(mockEditor);
+		assertNull(handler.execute(null));
+		verify(mockEditor).revert();
+	}
+
+	public void testIsEnabledReturnsFalseUponConstructionIfOrionEditorIsNotDirty() {
+		assertFalse(handler.isEnabled());
+	}
+
+	public void testIsEnabledReturnsTrueUponConstructionIfOrionEditorIsDirty() {
+		when(mockEditor.isDirty()).thenReturn(true);
+		handler = new RevertOrionEditorHandler(mockEditor);
+		assertTrue(handler.isEnabled());
+	}
+
+	public void testIsEnabledReturnsTrueWhenEditorBecomesDirty() {
+		when(mockEditor.isDirty()).thenReturn(true);
+		handler.propertyChanged(mockEditor, ISaveablePart.PROP_DIRTY);
+		assertTrue(handler.isEnabled());
+	}
+
+	public void testIsEnabledReturnsFalseWhenEditorIsNotDirty() {
+		when(mockEditor.isDirty()).thenReturn(false);
+		handler.propertyChanged(mockEditor, ISaveablePart.PROP_DIRTY);
+		assertFalse(handler.isEnabled());
+	}
+
+	public void testIsEnabledReturnsSameValueWhenPropertyChangedSourceNotEditor() {
+		assertFalse(handler.isEnabled());
+		handler.propertyChanged(null, ISaveablePart.PROP_DIRTY);
+		assertFalse(handler.isEnabled());
+
+	}
+
+	public void testIsEnabledReturnsSameValueWhenPropertyChangedIdNotDirtyProperty() {
+		assertFalse(handler.isEnabled());
+		handler.propertyChanged(mockEditor, 0);
+		assertFalse(handler.isEnabled());
+	}
+}