blob: 6619d219eff76af0d2e27f984e97f94745862f52 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2007 Boeing.
* 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:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.osee.ote.ui.test.manager.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.osee.connection.service.IServiceConnector;
import org.eclipse.osee.framework.jdk.core.type.IPropertyStore;
import org.eclipse.osee.framework.jdk.core.type.Pair;
import org.eclipse.osee.framework.jdk.core.type.PropertyStore;
import org.eclipse.osee.framework.jdk.core.util.Lib;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.framework.plugin.core.util.OseeData;
import org.eclipse.osee.framework.ui.swt.Displays;
import org.eclipse.osee.framework.ui.swt.ImageManager;
import org.eclipse.osee.ote.core.environment.interfaces.IHostTestEnvironment;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironment;
import org.eclipse.osee.ote.service.ConnectionEvent;
import org.eclipse.osee.ote.service.ITestConnectionListener;
import org.eclipse.osee.ote.ui.test.manager.ITestManagerFactory;
import org.eclipse.osee.ote.ui.test.manager.OteTestManagerImage;
import org.eclipse.osee.ote.ui.test.manager.internal.TestManagerPlugin;
import org.eclipse.osee.ote.ui.test.manager.pages.contributions.TestManagerStorageKeys;
import org.eclipse.osee.ote.ui.test.manager.util.ClassServerInst;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.part.MultiPageEditorPart;
/**
* Resource Test Manager Editor Pages:
* <ul>
* <li>Overview Page
* <li>Target Page
* <li>Scripts Page
* <li>Advanced Page
* <li>Source Page
* </ul>
*/
public abstract class TestManagerEditor extends MultiPageEditorPart implements ITestConnectionListener {
private static final Image errorImage = ImageManager.getImage(OteTestManagerImage.ERROR);
public static final String namespace = "org.eclipse.osee.ote.ui.test.manager.editors.TestManagerEditor";
public final QualifiedName clearCaseViewName = new QualifiedName(namespace, "CLEARCASEVIEW");
public final QualifiedName configFileName = new QualifiedName(namespace, "CONFIGFILENAME");
public final QualifiedName ofpQualName = new QualifiedName(namespace, "OFP");
public final QualifiedName scriptsQualName = new QualifiedName(namespace, "SCRIPTS");
private boolean fileIsDirty = false;
private boolean fileWasSaved = false;
private int lastPageIndex = 0;
private final ITestManagerModel model;
private boolean reloadSourcePage = false;
private int scriptPageIndex = 1;
private TextEditor sourceEditor;
private int sourcePage;
private final ITestManagerFactory testManagerFactory;
private IFile thisIFile = null;
private final IPropertyStore propertyStore;
private final PageManager pageManager;
private ITestEnvironment connectedEnv = null;
private IServiceConnector connector = null;
private IHostTestEnvironment connectedHost;
public TestManagerEditor(final ITestManagerFactory testManagerFactory, ITestManagerModel model) {
super();
this.testManagerFactory = testManagerFactory;
this.pageManager = new PageManager(testManagerFactory, this);
this.model = model;
this.propertyStore = new PropertyStore(testManagerFactory.getClass().getSimpleName());
}
public void activateScriptsPage() {
setActivePage(scriptPageIndex);
}
public void addFile(String fullPath) {
pageManager.getScriptPage().addFile(fullPath);
}
@Override
public void dispose() {
super.dispose();
TestManagerPlugin.getInstance().getOteClientService().removeConnectionListener(this);
try {
pageManager.dispose();
} catch (Throwable t) {
TestManagerPlugin.log(Level.SEVERE, "exception while disposing test manager", t);
}
}
/**
* Saves the multi-page editor's document.
*/
@Override
public void doSave(IProgressMonitor monitor) {
if (getActivePage() != sourcePage) {
pageSourceLoad();
}
if(isDirty()){
getEditor(sourcePage).doSave(monitor);
}
fileIsDirty = false;
fileWasSaved = true;
doSave();
firePropertyChange(PROP_DIRTY);
}
/**
* Saves the multi-page editor's document as another file. Also updates the text for page 0's tab, and updates this
* multi-page editor's input to correspond to the nested editor's.
*/
@Override
public void doSaveAs() {
if (getActivePage() != sourcePage) {
pageSourceLoad();
}
IEditorPart editor = getEditor(sourcePage);
editor.doSaveAs();
setPageText(sourcePage, "Source");
setInput(editor.getEditorInput());
doSave();
}
protected void registerPage(int pageNumber, String pageName, boolean isScriptPage) {
setPageText(pageNumber, pageName);
if(isScriptPage){
scriptPageIndex = pageNumber;
}
}
public void executionCompleted() {
pageManager.getScriptPage().onScriptRunning(false);
}
public void fireSaveNeeded() {
fileIsDirty = true;
firePropertyChange(PROP_DIRTY);
}
public String getAlternateOutputDir() {
String scriptOutput = "";
IPropertyStore propertyStore = getPropertyStore();
scriptOutput = propertyStore.get(TestManagerStorageKeys.SCRIPT_OUTPUT_DIRECTORY_KEY);
if (scriptOutput == null) {
scriptOutput = "";
// TODO: Escobar
// try {
// IEditorInput coreinput = getEditorInput();
// if (coreinput instanceof IFileEditorInput) {
// scriptOutput =
// thisIFile.getPersistentProperty(scriptOutputQualName);
// } else if (coreinput instanceof TestManagerInput) {
// TestManagerInput input = (TestManagerInput) getEditorInput();
// scriptOutput =
// input.getValue(scriptOutputQualName.getLocalName());
// }
//
// scriptOutput =
// thisIFile.getPersistentProperty(scriptOutputQualName);
// } catch (CoreException e) {
// e.printStackTrace();
// }
}
return scriptOutput;
}
public String getDefaultConfigPath() {
Location user = Platform.getUserLocation();
String path = user.getURL().getPath();
File file = new File(path + File.separator + "org.eclipse.osee.ote.ui.test.manager");
file.mkdirs();
file =
new File(
path + File.separator + "org.eclipse.osee.ote.ui.test.manager" + File.separator + this.getClass().getName() + ".scriptConfig.xml");
file.getParentFile().mkdirs();
return file.getAbsolutePath();
}
/**
* @return Returns the model.
*/
public ITestManagerModel getModel() {
return model;
}
public String getName() {
return this.getTitle();
}
public ClassServerInst getScriptClassServer() {
return ClassServerInst.getInstance();
}
public ITestManagerFactory getTestManagerFactory() {
return testManagerFactory;
}
@Override
public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
if (!(editorInput instanceof IFileEditorInput || editorInput instanceof TestManagerInput || editorInput instanceof IEditorInput)) {
throw new PartInitException("Invalid Input: Must be IFileEditorInput");
}
super.init(site, editorInput);
}
@Override
public boolean isDirty() {
if (super.isDirty()) {
return true;
}
return fileIsDirty;
}
@Override
public boolean isSaveAsAllowed() {
return true;
}
/**
* Retrieves the value for the key. See <code>storeValue</code>. If the key could not be found, an empty string is
* returned.
*
* @param key The <code>QualifiedName</code> whose value is to be retrieved.
* @return The value of key, or an empty string if the key does not exist.
*/
public String loadValue(QualifiedName key) {
TestManagerPlugin.log(Level.INFO, "loadValue: " + key.getQualifier());
try {
IEditorInput coreinput = getEditorInput();
if (coreinput instanceof IFileEditorInput) {
return thisIFile.getPersistentProperty(key);
} else if (coreinput instanceof TestManagerInput) {
TestManagerInput input = (TestManagerInput) getEditorInput();
return input.getValue(key.getLocalName());
}
} catch (CoreException ex) {
TestManagerPlugin.log(Level.SEVERE, "Can't get value: " + ex);
}
return "";
}
public void setPageError(int page, boolean set) {
if (set) {
setPageImage(page, errorImage);
} else {
setPageImage(page, null);
}
}
/**
* Stores the value for the key. The key should be one of the publicly available <code>QualifiedName</code>'s in
* <code>this</code>.
*
* @param key The <code>QualifiedName</code> associated with the value to be stored
* @param value What will be stored under the key.
*/
public void storeValue(QualifiedName key, String value) {
TestManagerPlugin.log(Level.INFO, "storeValue: " + key.getQualifier());
try {
IEditorInput coreinput = getEditorInput();
if (coreinput instanceof IFileEditorInput) {
thisIFile.setPersistentProperty(key, value);
} else if (coreinput instanceof TestManagerInput) {
TestManagerInput input = (TestManagerInput) getEditorInput();
input.storeValue(key.getLocalName(), value);
}
} catch (Exception ex) {
TestManagerPlugin.log(Level.SEVERE, "Can't set value: " + ex);
}
}
private void pageSourceCheck() {
setPageError(sourcePage, model.hasParseExceptions());
}
private void readXmlData() {
TestManagerPlugin.log(Level.INFO, "readXmlData");
IEditorInput coreinput = getEditorInput();
String xmlText = "";
if (coreinput instanceof IFileEditorInput) {
IFileEditorInput input = (IFileEditorInput) getEditorInput();
thisIFile = input.getFile();
try {
thisIFile.refreshLocal(IResource.DEPTH_ZERO, null);
} catch (CoreException e) {
e.printStackTrace();
}
String name = thisIFile.getName();
this.setPartName(name);
if (thisIFile != null) {
try {
xmlText = Lib.inputStreamToString(thisIFile.getContents());
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
TestManagerPlugin.log(Level.SEVERE, "Can't open xml file!");
}
} else if (coreinput instanceof TestManagerInput) {
TestManagerInput input = (TestManagerInput) getEditorInput();
String name = "TestManager";
this.setPartName(name);
xmlText = input.getDefaultXML();
}
model.setFromXml(xmlText);
}
/**
* Creates the pages of the multi-page editor.
*/
@Override
protected void createPages() {
readXmlData();
pageManager.createPages(getContainer());
pageSourceCreate();
fileIsDirty = false;
reloadSourcePage = false;
pageSourceCheck();
restoreSettings();
// If parse errors, send to sourcePage and set error on page
if (model.hasParseExceptions()) {
if (sourceEditor == null) {
pageSourceCreate();
}
handleSourceEditorError();
}
fileIsDirty = false;
firePropertyChange(PROP_DIRTY);
TestManagerPlugin.getInstance().getOteClientService().addConnectionListener(this);
}
protected void handleSelection() {
fireSaveNeeded();
reloadSourcePage = true;
}
/**
* reloads pages as necessary
*/
@Override
protected void pageChange(int newPageIndex) {
// NOTE: Hosts page will be updated continuously, even it if it is not
// the current page.
// so it is unnecessary to update it on pageChange.
super.pageChange(newPageIndex);
if (newPageIndex == sourcePage) {
pageSourceLoad();
} else {
if (sourceEditor == null) {
return;
}
String newXml = sourceEditor.getDocumentProvider().getDocument(sourceEditor.getEditorInput()).get();
if (sourceEditor.isDirty() || fileWasSaved) {
fileWasSaved = false;
// If we just came from sourcePage, re-parse
if (lastPageIndex == sourcePage) {
// if parse error, goto source and error
if (!model.setFromXml(newXml)) {
handleSourceEditorError();
return;
}
setPageError(sourcePage, false);
}
}
}
doSave(null);
lastPageIndex = newPageIndex;
}
private void handleSourceEditorError() {
if (model.hasParseExceptions()) {
try {
setActivePage(sourcePage);
pageSourceCheck();
MessageDialog.openError(getSite().getShell(), "Source Page Error",
"Error parsing Source page\n "+model.getParseError());
Pair<Integer, Integer> parseErrorRange = model.getParseErrorRange();
sourceEditor.setHighlightRange(parseErrorRange.getFirst(), parseErrorRange.getSecond(), false);
sourceEditor.getSelectionProvider().setSelection(new TextSelection(parseErrorRange.getFirst(), parseErrorRange.getSecond()));
} catch (Throwable th) {}
}
}
public void updateFromTestManagerModel() {
IDocument doc = sourceEditor.getDocumentProvider().getDocument(sourceEditor.getEditorInput());
if (!doc.get().equals(model.getRawXml())) {
doc.set(model.getRawXml());
try {
sourceEditor.getDocumentProvider().saveDocument(new NullProgressMonitor(), null, doc, true);
} catch (CoreException e) {
OseeLog.log(getClass(), Level.SEVERE, e);
}
}
}
void pageSourceCreate() {
try {
if (getEditorInput() instanceof IFileEditorInput) {
sourceEditor = new TextEditor();
int index = addPage(sourceEditor, getEditorInput());
sourcePage = index;
setPageText(sourcePage, "Source");
}
} catch (PartInitException e) {
TestManagerPlugin.log(Level.SEVERE, "Error creating nested text editor", e);
ErrorDialog.openError(getSite().getShell(), "Error creating nested text editor", null, e.getStatus());
}
}
void pageSourceLoad() {
if (reloadSourcePage) {
sourceEditor.getDocumentProvider().getDocument(sourceEditor.getEditorInput()).set(model.getRawXml());
reloadSourcePage = false;
}
pageSourceCheck();
}
public void doSave() {
pageManager.save();
OutputStream outputStream = null;
try {
File file = OseeData.getFile("testManagerSettings.xml");
outputStream = new FileOutputStream(file);
getPropertyStore().save(outputStream);
} catch (Exception ex) {
TestManagerPlugin.log(Level.SEVERE, "Error storing settings.", ex);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex) {
TestManagerPlugin.log(Level.WARNING, "Error closing stream during settings storage.", ex);
}
}
}
}
public void restoreSettings() {
InputStream inputStream = null;
try {
File file = OseeData.getFile("testManagerSettings.xml");
if(file.exists()){
inputStream = new FileInputStream(file);
getPropertyStore().load(inputStream);
pageManager.restore();
}
} catch (Exception ex) {
TestManagerPlugin.log(Level.WARNING, "Stored settings not available. Using defaults.", ex);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ex) {
TestManagerPlugin.log(Level.WARNING, "Error closing stream while loading settings.", ex);
}
}
}
}
public IPropertyStore getPropertyStore() {
return propertyStore;
}
public PageManager getPageManager() {
return pageManager;
}
@Override
public void onConnectionLost(IServiceConnector connector) {
connectedEnv = null;
connector = null;
boolean problemEncountered = pageManager.onConnectionLost();
if (problemEncountered) {
Displays.ensureInDisplayThread(new Runnable() {
@Override
public void run() {
MessageDialog.openError(Displays.getActiveShell(), "Disconnect Error",
"Test manager has encountered a problem while processing the disconnect event. See Error Log for details");
}
});
}
connectedHost = null;
}
@Override
public void onPostConnect(ConnectionEvent event) {
connectedEnv = event.getEnvironment();
connectedHost = event.getHostEnvironment();
connector = event.getConnector();
boolean problemEncountered = pageManager.onPostConnect(event);
if (problemEncountered) {
Displays.ensureInDisplayThread(new Runnable() {
@Override
public void run() {
MessageDialog.openError(Displays.getActiveShell(), "Connection Error",
"Test manager has encountered a problem while processing the connection event. See Error Log for details");
}
});
}
}
@Override
public void onPreDisconnect(ConnectionEvent event) {
event.getEnvironment();
connectedEnv = null;
connector = null;
boolean problemEncountered = pageManager.onPreDisconnect(event);
if (problemEncountered) {
Displays.ensureInDisplayThread(new Runnable() {
@Override
public void run() {
MessageDialog.openError(Displays.getActiveShell(), "Disconnect Error",
"Test manager has encountered a problem while processing the disconnect event. See Error Log for details");
}
});
}
connectedHost = null;
}
public boolean isConnected() {
return connectedEnv != null;
}
public ITestEnvironment getConnectedEnvironment() {
return connectedEnv;
}
public IHostTestEnvironment getConnectedHostEnvironment() {
return connectedHost;
}
public IServiceConnector getConnector() {
return connector;
}
public abstract void createHostWidget(Composite parent);
public void addFiles(String[] files) {
pageManager.getScriptPage().addFiles(files);
}
}