/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* 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:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.test.ui.v2.resources;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.internal.PartSite;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.wst.sse.sieditor.test.util.ResourceUtils;
import org.eclipse.wst.sse.sieditor.test.util.SIEditorBaseTest;
import org.eclipse.wst.sse.sieditor.test.util.ThreadUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.eclipse.wst.sse.sieditor.command.emf.wsdl.AddServiceInterfaceCommand;
import org.eclipse.wst.sse.sieditor.command.emf.xsd.AddSimpleTypeCommand;
import org.eclipse.wst.sse.sieditor.core.common.Logger;
import org.eclipse.wst.sse.sieditor.model.api.IWsdlModelRoot;
import org.eclipse.wst.sse.sieditor.model.api.IXSDModelRoot;
import org.eclipse.wst.sse.sieditor.model.utils.StatusUtils;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IServiceInterface;
import org.eclipse.wst.sse.sieditor.model.xsd.api.IType;
import org.eclipse.wst.sse.sieditor.ui.AbstractEditorWithSourcePage;
import org.eclipse.wst.sse.sieditor.ui.DataTypesEditor;
import org.eclipse.wst.sse.sieditor.ui.ServiceInterfaceEditor;
@SuppressWarnings("nls")
public class TestModelRevertToSaved extends SIEditorBaseTest {
AbstractEditorWithSourcePage editor = null;
@BeforeClass
public static void setUpBefore() {
StatusUtils.isUnderJunitExecution = true;
}
@AfterClass
public static void tearDownAfter() {
StatusUtils.isUnderJunitExecution = false;
}
@Override
@Before
public void setUp() throws Exception {
super.setUp();
}
@Override
@After
public void tearDown() throws Exception {
if (editor != null) {
editor.close(false);
}
super.tearDown();
// Flush threads that wait UI thread for execution
ThreadUtils.waitOutOfUI(100);
}
@Test
public void testDTEUnderlyingFileContentsChangedWhenEditorIsSaved() throws Throwable {
final String TEST_SIMPLETYPE_NAME = "TestSimpleType";
final IFile file = ResourceUtils.copyFileIntoTestProject("pub/xsd/example.xsd", Document_FOLDER_NAME, this.getProject(),
"example.xsd");
refreshProjectNFile(file);
final String oldContents = ResourceUtils.getContents(file, "UTF-8");
final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final FileEditorInput eInput = new FileEditorInput(file);
final IWorkbenchPage workbenchActivePage = window.getActivePage();
editor = (DataTypesEditor) workbenchActivePage.openEditor(eInput, DataTypesEditor.EDITOR_ID);
assertFalse(editor.isDirty());
final IXSDModelRoot modelRoot = (IXSDModelRoot) editor.getModelRoot();
IType testType[] = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNull(testType);
final AddSimpleTypeCommand addSimpleType = new AddSimpleTypeCommand(modelRoot, modelRoot.getSchema(), TEST_SIMPLETYPE_NAME);
modelRoot.getEnv().execute(addSimpleType);
testType = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNotNull(testType[0]);
// assert initial editor state
assertTrue(editor.isDirty());
editor.doSave(null);
assertFalse(editor.isDirty());
testType = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNotNull(testType[0]);
// return the old file's contents
final long refreshDialogCalls = StatusUtils.getShowDialogWithResult_calls_calls();
// set file contents from not UI thread, so any resource change
// listeners can react
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
ResourceUtils.setContents(file, oldContents);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
};
ModalContext.run(runnable, true, new NullProgressMonitor(), PlatformUI.getWorkbench().getDisplay());
// wait for the refresh editors job
//waitForResourceChangeListener();
// Assert the initial editor's state
// dialog is not shown because the editor was not dirty
assertEquals(refreshDialogCalls, StatusUtils.getShowDialogWithResult_calls_calls());
assertFalse(editor.isDirty());
testType = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNull(testType);
}
@Test
public void testDTEUnderlyingFileContentsChangedWhenEditorIsNotSaved() throws Throwable {
final String TEST_SIMPLETYPE_NAME = "TestSimpleType";
final IFile file = ResourceUtils.copyFileIntoTestProject("pub/xsd/example.xsd", Document_FOLDER_NAME, this.getProject(),
"example.xsd");
refreshProjectNFile(file);
final String oldContents = ResourceUtils.getContents(file, "UTF-8");
final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final FileEditorInput eInput = new FileEditorInput(file);
final IWorkbenchPage workbenchActivePage = window.getActivePage();
final IWorkbenchPart initialActivePart = window.getActivePage().getActivePart();
editor = (DataTypesEditor) workbenchActivePage.openEditor(eInput, DataTypesEditor.EDITOR_ID);
show(editor);
assertFalse(editor.isDirty());
final IXSDModelRoot modelRoot = (IXSDModelRoot) editor.getModelRoot();
IType testType[] = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNull(testType);
final AddSimpleTypeCommand addSimpleType = new AddSimpleTypeCommand(modelRoot, modelRoot.getSchema(), TEST_SIMPLETYPE_NAME);
modelRoot.getEnv().execute(addSimpleType);
testType = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNotNull(testType[0]);
// assert initial editor state
assertTrue(editor.isDirty());
// return the old file's contents
final long refreshDialogCalls = StatusUtils.getShowDialogWithResult_calls_calls();
// set file contents from not UI thread, so any resource change
// listeners can react
workbenchActivePage.activate(initialActivePart);
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
ResourceUtils.setContents(file, oldContents);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
};
ModalContext.run(runnable, true, new NullProgressMonitor(), PlatformUI.getWorkbench().getDisplay());
// wait for the refresh editors job
//waitForResourceChangeListener();
//switch back to the DTE page
window.getActivePage().activate(editor.getEditorSite().getPart());
// Assert that the user is asked before reload editor contents
assertTrue(StatusUtils.getShowDialogWithResult_calls_calls() > refreshDialogCalls);
assertFalse(editor.isDirty());
testType = modelRoot.getSchema().getAllTypes(TEST_SIMPLETYPE_NAME);
assertNull(testType);
}
@Test
public void testSIEUnderlyingFileContentsChangedWhenEditorIsSaved() throws Throwable {
final String TEST_INTERFACE_NAME = "TestInterface";
final IFile file = ResourceUtils.copyFileIntoTestProject("pub/simple/NewWSDLFile.wsdl", Document_FOLDER_NAME, this
.getProject(), "NewWSDLFile.wsdl");
refreshProjectNFile(file);
final String oldContents = ResourceUtils.getContents(file, "UTF-8");
final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final FileEditorInput eInput = new FileEditorInput(file);
final IWorkbenchPage workbenchActivePage = window.getActivePage();
editor = (ServiceInterfaceEditor) workbenchActivePage.openEditor(eInput, ServiceInterfaceEditor.EDITOR_ID);
assertFalse(editor.isDirty());
final IWsdlModelRoot modelRoot = ((ServiceInterfaceEditor) editor).getModelRoot();
List<IServiceInterface> sIs = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertTrue(sIs.isEmpty());
final AddServiceInterfaceCommand addInterface = new AddServiceInterfaceCommand(modelRoot, modelRoot.getDescription(),
TEST_INTERFACE_NAME);
modelRoot.getEnv().execute(addInterface);
sIs = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertFalse(sIs.isEmpty());
IServiceInterface testInterface = sIs.get(0);
assertNotNull(testInterface);
// assert initial editor state
assertTrue(editor.isDirty());
editor.doSave(null);
assertFalse(editor.isDirty());
sIs = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertFalse(sIs.isEmpty());
testInterface = sIs.get(0);
assertNotNull(testInterface);
// return the old file's contents
final long refreshDialogCalls = StatusUtils.getShowDialogWithResult_calls_calls();
// set file contents from not UI thread, so any resource change
// listeners can react
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
ResourceUtils.setContents(file, oldContents);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
};
ModalContext.run(runnable, true, new NullProgressMonitor(), PlatformUI.getWorkbench().getDisplay());
// wait for the refresh editors job
//waitForResourceChangeListener();
// Assert the initial editor's state
// dialog is not shown because the editor was not dirty
assertEquals(refreshDialogCalls, StatusUtils.getShowDialogWithResult_calls_calls());
assertFalse(editor.isDirty());
final List<IServiceInterface> interfaces = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertTrue(interfaces.isEmpty());
}
@Test
public void testSIEUnderlyingFileContentsChangedWhenEditorIsNotSaved() throws Throwable {
final String TEST_INTERFACE_NAME = "TestInterface";
final IFile file = ResourceUtils.copyFileIntoTestProject("pub/simple/NewWSDLFile.wsdl", Document_FOLDER_NAME, this
.getProject(), "NewWSDLFile.wsdl");
refreshProjectNFile(file);
final String oldContents = ResourceUtils.getContents(file, "UTF-8");
final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final FileEditorInput eInput = new FileEditorInput(file);
final IWorkbenchPage workbenchActivePage = window.getActivePage();
final IWorkbenchPart initialActivePart = window.getActivePage().getActivePart();
editor = (ServiceInterfaceEditor) workbenchActivePage.openEditor(eInput, ServiceInterfaceEditor.EDITOR_ID);
show(editor);
workbenchActivePage.activate(editor.getEditorSite().getPart());
assertFalse(editor.isDirty());
final IWsdlModelRoot modelRoot = ((ServiceInterfaceEditor) editor).getModelRoot();
List<IServiceInterface> testInterfaces = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertTrue(testInterfaces.isEmpty());
final AddServiceInterfaceCommand addInterface = new AddServiceInterfaceCommand(modelRoot, modelRoot.getDescription(),
TEST_INTERFACE_NAME);
modelRoot.getEnv().execute(addInterface);
testInterfaces = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertFalse(testInterfaces.isEmpty());
final IServiceInterface testInterface = testInterfaces.get(0);
assertNotNull(testInterface);
// assert initial editor state
assertTrue(editor.isDirty());
//activate some other page
workbenchActivePage.activate(initialActivePart);
// return the old file's contents
final long refreshDialogCalls = StatusUtils.getShowDialogWithResult_calls_calls();
// set file contents from not UI thread, so any resource change
// listeners can react
final IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
ResourceUtils.setContents(file, oldContents);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
};
ModalContext.run(runnable, true, new NullProgressMonitor(), PlatformUI.getWorkbench().getDisplay());
//switch back to the SIE page
window.getActivePage().activate(editor.getEditorSite().getPart());
// Assert that the user is asked before reload editor contents
assertTrue(StatusUtils.getShowDialogWithResult_calls_calls() > refreshDialogCalls);
final boolean isDirty = editor.isDirty();
if (isDirty) {
// DEBUG PURPOSE - it is random failure
Logger.logError("ERROR testSIEUnderlyingFileContentsChangedWhenEditorIsNotSaved dirty pages: ");
for (final Object page : (editor).getPages()) {
if (page instanceof IFormPage) {
final IFormPage fpage = (IFormPage) page;
if (fpage.isDirty()) {
Logger.logError("Dirty page: " + (page.getClass()));
}
} else {
Logger.logError("Page which is not IFormPage: " + (page.getClass()));
}
}
}
assertFalse(isDirty);
final List<IServiceInterface> interfaces = modelRoot.getDescription().getInterface(TEST_INTERFACE_NAME);
assertTrue(interfaces.isEmpty());
}
/**
* Without setVisible & setSize, IPartListeners won't be notified upon part activation
* @param editor
*/
private void show(AbstractEditorWithSourcePage editor) {
Control control = ((PartSite) editor.getEditorSite().getPart().getSite()).getPane().getControl();
List<Control> controls = new ArrayList<Control>();
controls.add(control);
Control parent = null;
while ((parent = control.getParent()) != null) {
controls.add(0, parent);
control = parent;
}
for (Control ctrl : controls) {
ctrl.setVisible(true);
ctrl.setSize(10, 10);
}
}
/**
* Waits for the refresh editors job which is started in the resource change
* listener {@link ResourceChangeHandler}
*/
/*
private void waitForResourceChangeListener() {
try {
Job.getJobManager().join(ResourceChangeHandler.RefreshEditorsJob.REFRESH_EDITORS_FAMILY, new NullProgressMonitor());
} catch (final InterruptedException e) {
e.printStackTrace(System.err);
final Job[] jobs = Job.getJobManager().find(ResourceChangeHandler.RefreshEditorsJob.REFRESH_EDITORS_FAMILY);
if (jobs.length == 0) {
return;
}
for (final Job job : jobs) {
job.wakeUp();
}
waitForResourceChangeListener();
}
}
*/
}