blob: b9f8ba577d1684a72659d7927fdfee3fe0594db1 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2016 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.clipboard.core;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.examples.extlibrary.Book;
import org.eclipse.emf.examples.extlibrary.Library;
import org.eclipse.emf.examples.extlibrary.Writer;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.gmf.runtime.emf.clipboard.core.ClipboardUtil;
import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory;
import org.osgi.framework.Bundle;
/**
* Sets up a test framework for clipboard tests.
*
* @author Christian Vogt (cvogt)
*/
public abstract class BaseClipboardTest extends TestCase {
static final Bundle CLIPBOARD_TESTS_BUNDLE =
Platform.getBundle("org.eclipse.gmf.tests.runtime.emf.clipboard.core"); //$NON-NLS-1$
protected static final String PROJECT_NAME = "clipboardTests"; //$NON-NLS-1$
protected static final String RESOURCE_NAME = "/" + PROJECT_NAME + "/logres.extlibrary"; //$NON-NLS-1$//$NON-NLS-2$
private Transaction tx;
private ChangeDescription lastChange;
protected TransactionalEditingDomain domain;
protected IProject project;
protected Resource testResource;
//
// Model structure created by setUp():
//
// Library root1 (== root1)
// +- Writer level1 writer (== level1writer)
// +- Book level1 book (== level1book)
// +- Library level1 (== level1)
// | +- Writer level1-2 writer (== level12writer)
// | +- Book level1-2 book (== level12book)
// | +- Library level1-2 (== level12)
// Library root2 (== root2)
// +- Writer level2 writer (== level2writer)
// +- Book level2 book (== level2book)
// Library root3 (== root3)
//
protected Library root1;
protected Writer level1writer;
protected Book level1book;
protected Library level1;
protected Writer level12writer;
protected Book level12book;
protected Library level12;
protected Library root2;
protected Writer level2writer;
protected Book level2book;
protected Library root3;
/**
* Constructor.
*
* @param name
*/
public BaseClipboardTest(String name) {
super(name);
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
project = ResourcesPlugin.getWorkspace().getRoot().getProject(PROJECT_NAME);
if (!project.exists()) {
project.create(null);
}
project.open(null);
domain = GMFEditingDomainFactory.getInstance().createEditingDomain();
tx = ((InternalTransactionalEditingDomain) domain).startTransaction(false, null);
try {
Resource originalRes = domain.getResourceSet().getResource(
URI.createURI(
CLIPBOARD_TESTS_BUNDLE.getEntry(
"/test_models/clipboard_test.extlibrary") //$NON-NLS-1$
.toString()), true);
originalRes.setURI(URI.createPlatformResourceURI(RESOURCE_NAME, false));
originalRes.save(Collections.EMPTY_MAP);
testResource = originalRes;
// see above for model info
root1 = (Library)testResource.getContents().get(0);
level1writer = (Writer)root1.getWriters().get(0);
level1book = (Book)root1.getBooks().get(0);
level1 = (Library)root1.getBranches().get(0);
level12writer = (Writer)level1.getWriters().get(0);
level12book = (Book)level1.getBooks().get(0);
level12 = (Library)level1.getBranches().get(0);
root2 = (Library)testResource.getContents().get(1);
level2writer = (Writer)root2.getWriters().get(0);
level2book = (Book)root2.getBooks().get(0);
root3 = (Library)testResource.getContents().get(2);
} catch (IOException e) {
fail("Failed to load test model: " + e.getLocalizedMessage()); //$NON-NLS-1$
}
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
root1 = null;
level1writer = null;
level1book = null;
level1 = null;
level12writer = null;
level12book = null;
level12 = null;
root2 = null;
level2writer = null;
level2book = null;
root3 = null;
if (testResource != null) {
if (testResource.isLoaded()) {
testResource.unload();
}
if (testResource.getResourceSet() != null) {
testResource.getResourceSet().getResources().remove(testResource);
}
testResource = null;
}
if ((project != null) && project.exists()) {
project.delete(true, true, null);
}
project = null;
domain = null;
}
/**
* Copy elements to a the clipboard.
*
* @param eObjects a collection of {@link EObject}s to be serialized
* @param hints a mapping of hints (defined as constants on this class), or
* <code>null</code> to provide no hints
*
* @return the serial form of the <code>eObjects</code>
*/
protected String copy(Collection objects, Map hints) {
try {
return ClipboardUtil.copyElementsToString(
objects, hints, new NullProgressMonitor());
} catch (Exception ex) {
fail("Failed to copy elements to string."); //$NON-NLS-1$
}
return null;
}
/**
* Deerializes elements from a string (obtained from the system clipboard)
* and pastes them into the specified target element.
*
* @param string the string containing the elements to be pasted
* @param target the element into which the new elements are to be
* pasted (must be of type EObject or Resource)
* @param hints a mapping of hints (defined as constants on this class), or
* <code>null</code> to provide no hints
*
* @return the newly pasted {@link EObject}s
*/
protected Collection paste(final String str, final Object target, final Map hints) {
assert (target instanceof Resource || target instanceof EObject);
Collection result = null;
Transaction pasteTx = null;
try {
pasteTx = ((InternalTransactionalEditingDomain) domain).startTransaction(false, null);
} catch (Exception e) {
fail("Failed to paste elements from string: " + e.getLocalizedMessage()); //$NON-NLS-1$
}
try {
if (target instanceof Resource) {
result = ClipboardUtil.pasteElementsFromString(
str, (Resource)target, hints, new NullProgressMonitor());
} else {
// else it must be an EObject
result = ClipboardUtil.pasteElementsFromString(
str, (EObject)target, hints, new NullProgressMonitor());
}
} catch (Exception ex) {
fail("Failed to paste elements from string."); //$NON-NLS-1$
} finally {
try {
pasteTx.commit();
} catch (RollbackException e) {
fail("Failed to paste elements from string: " + e.getLocalizedMessage()); //$NON-NLS-1$
}
}
return result;
}
/**
* Must be called first in every test method that needs to run in a write
* action. If we are not in a write action, we return <code>false</code>.
* However, in this case, we do also re-execute the original test method
* inside of a new write action, in which nested execution this method will
* return <code>true</code>. Therefore, the entire test method should be
* in an <code>if</code> block conditional on this result. Following this
* <code>if</code> block, it is safe to access the undo interval created
* during the test via the {@link #getLastUndo()} method in an
* <code>else</code> block.
* <p>
* Example:
* </p>
* <pre>
* if (writing()) {
* // ... do stuff in a write action ...
* }
* </pre>
*
* @return whether we are in a write action or not
*
* @see #getLastUndo()
*/
protected boolean writing() {
boolean result = (tx != null);
if (!result) {
try {
tx = ((InternalTransactionalEditingDomain) domain).startTransaction(false, null);
} catch (Exception e) {
fail("Could not start transaction: " + e.getLocalizedMessage()); //$NON-NLS-1$
}
try {
runTest();
} catch (AssertionFailedError e) {
tx.rollback();
throw e;
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
fail("Unexpected exception: " + e.getLocalizedMessage()); //$NON-NLS-1$
} catch (Throwable t) {
tx.rollback();
throw (Error) t;
} finally {
if (tx.isActive()) {
try {
tx.commit();
} catch (RollbackException e) {
fail("Transaction rolled back: " + e.getLocalizedMessage()); //$NON-NLS-1$
}
}
}
lastChange = tx.getChangeDescription();
}
return result;
}
/**
* Gets the change description created by the test within its
* <pre>
* if (writing()) {
* // ... do stuff in a write action ...
* } else {
* ChangeDescription change = getLastChange();
*
* // ... do stuff with the change description ...
* }
* </pre>
* block.
*
* @return the test's change description
*
* @see #writing()
*/
protected ChangeDescription getLastChange() {
return lastChange;
}
}