| /****************************************************************************** |
| * Copyright (c) 2006 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| ****************************************************************************/ |
| |
| package org.eclipse.gmf.tests.runtime.emf.ui.action; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.InputStream; |
| import java.util.Collections; |
| |
| import junit.framework.TestCase; |
| |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.commands.operations.IOperationHistory; |
| import org.eclipse.core.commands.operations.IUndoContext; |
| import org.eclipse.core.commands.operations.OperationHistoryFactory; |
| import org.eclipse.core.commands.operations.UndoContext; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourceAttributes; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.gmf.runtime.common.core.command.AbstractCommand; |
| import org.eclipse.gmf.runtime.common.core.command.CommandResult; |
| import org.eclipse.gmf.runtime.common.core.command.FileModificationValidator; |
| import org.eclipse.gmf.runtime.common.core.internal.command.BaseModificationValidator; |
| import org.eclipse.gmf.runtime.emf.ui.action.AbstractModelActionHandler; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartSite; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.operations.UndoActionHandler; |
| |
| /** |
| * Tests the AbstractModelActionHandler. |
| * |
| * @author ldamus |
| */ |
| public class AbstractModelActionHandlerTest extends TestCase { |
| |
| private IProject project; |
| |
| private IFile file; |
| |
| private IOperationHistory history; |
| |
| private TransactionalEditingDomain editingDomain; |
| |
| private IWorkbenchPart part; |
| |
| private IWorkbenchPartSite site; |
| |
| protected void setUp() throws Exception { |
| |
| super.setUp(); |
| |
| // avoid UI prompting from validator |
| FileModificationValidator |
| .setModificationValidator(new BaseModificationValidator()); |
| |
| part = PlatformUI.getWorkbench().getActiveWorkbenchWindow() |
| .getActivePage().getActivePart(); |
| |
| site = part.getSite(); |
| |
| editingDomain = TransactionalEditingDomain.Factory.INSTANCE |
| .createEditingDomain(); |
| history = OperationHistoryFactory.getOperationHistory(); |
| |
| try { |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| project = root.getProject("FileModificationApproverTest"); //$NON-NLS-1$ |
| |
| project.create(null); |
| project.open(null); |
| |
| file = project.getFile("AbstractModelActionHandlerTest.txt"); //$NON-NLS-1$ |
| InputStream contents = new ByteArrayInputStream(new byte[0]); |
| |
| file.create(contents, false, new NullProgressMonitor()); |
| |
| } catch (CoreException e) { |
| fail(e); |
| } |
| } |
| |
| protected void tearDown() throws Exception { |
| |
| super.tearDown(); |
| |
| file.delete(true, new NullProgressMonitor()); |
| project.close(new NullProgressMonitor()); |
| project.delete(true, true, new NullProgressMonitor()); |
| project = null; |
| file = null; |
| site = null; |
| } |
| |
| private void fail(Exception e) { |
| e.printStackTrace(); |
| fail("Should not have thrown: " + e.getLocalizedMessage()); //$NON-NLS-1$ |
| } |
| |
| private void setReadOnly(boolean b) { |
| try { |
| ResourceAttributes resourceAttributes = file |
| .getResourceAttributes(); |
| resourceAttributes.setReadOnly(b); |
| file.setResourceAttributes(resourceAttributes); |
| |
| } catch (CoreException e) { |
| fail(e); |
| } |
| } |
| |
| /** |
| * Tests that validation is done for file modification when commands that |
| * change the model are executed through an AbstractModelActionHandler. |
| */ |
| public void test_fileModificationValidation_155418() { |
| |
| TestModelActionHandler action = new TestModelActionHandler(part); |
| |
| // create an undo action handler for the undo context so that we can |
| // test that the history is flushed correctly |
| UndoActionHandler undoAction = new UndoActionHandler(site, action |
| .getUndoContext()); |
| undoAction.setPruneHistory(true); |
| |
| // execute fails when file is read-only |
| setReadOnly(true); |
| action.run(new NullProgressMonitor()); |
| assertFalse(action.getCommand().isExecuted()); |
| assertFalse(history.canUndo(action.getUndoContext())); |
| |
| // execute succeeds when file is read-write |
| setReadOnly(false); |
| action.run(new NullProgressMonitor()); |
| assertTrue(action.getCommandStatus().isOK()); |
| assertTrue(action.getCommand().isExecuted()); |
| assertTrue(history.canUndo(action.getUndoContext())); |
| |
| // undo fails and history flushed when file is read-only |
| setReadOnly(true); |
| try { |
| history.undo(action.getUndoContext(), new NullProgressMonitor(), |
| null); |
| } catch (ExecutionException e) { |
| fail(e); |
| } |
| assertFalse(action.getCommand().isUndone()); |
| |
| // give the undo action a chance to run it's async exec to flush the |
| // history |
| Display display = PlatformUI.getWorkbench().getDisplay(); |
| while (display.readAndDispatch()) { |
| // spin |
| } |
| |
| assertFalse(history.canUndo(action.getUndoContext())); |
| |
| undoAction.dispose(); |
| } |
| |
| // test fixtures |
| |
| private class TestModelActionHandler extends AbstractModelActionHandler { |
| |
| private TestCommand command; |
| |
| private IUndoContext undoContext; |
| |
| public TestModelActionHandler(IWorkbenchPart part) { |
| super(part); |
| setText("TestModelActionHandler"); //$NON-NLS-1$ |
| } |
| |
| protected TransactionalEditingDomain getEditingDomain() { |
| return editingDomain; |
| } |
| |
| protected void doRun(IProgressMonitor progressMonitor) { |
| execute(getCommand(), progressMonitor, null); |
| } |
| |
| public TestCommand getCommand() { |
| if (command == null) { |
| command = new TestCommand(); |
| command.addContext(getUndoContext()); |
| } |
| return command; |
| } |
| |
| public IUndoContext getUndoContext() { |
| if (undoContext == null) { |
| undoContext = new UndoContext(); |
| } |
| return undoContext; |
| } |
| |
| public IStatus getCommandStatus() { |
| return super.getStatus(); |
| } |
| |
| public void refresh() { |
| // do nothing |
| } |
| } |
| |
| private class TestCommand extends AbstractCommand { |
| |
| private boolean executed = false; |
| |
| private boolean undone = false; |
| |
| private boolean redone = false; |
| |
| public TestCommand() { |
| super("AbstractModelActionHandlerTest", //$NON-NLS-1$ |
| Collections.singletonList(file)); |
| } |
| |
| protected CommandResult doExecuteWithResult( |
| IProgressMonitor progressMonitor, IAdaptable info) |
| throws ExecutionException { |
| this.executed = true; |
| return CommandResult.newOKCommandResult(); |
| } |
| |
| protected CommandResult doRedoWithResult( |
| IProgressMonitor progressMonitor, IAdaptable info) |
| throws ExecutionException { |
| this.undone = true; |
| return CommandResult.newOKCommandResult(); |
| } |
| |
| protected CommandResult doUndoWithResult( |
| IProgressMonitor progressMonitor, IAdaptable info) |
| throws ExecutionException { |
| this.redone = true; |
| return CommandResult.newOKCommandResult(); |
| } |
| |
| public boolean isExecuted() { |
| return executed; |
| } |
| |
| public boolean isUndone() { |
| return undone; |
| } |
| |
| public boolean isRedone() { |
| return redone; |
| } |
| } |
| } |