/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.framework.internal;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Window;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import javax.swing.Icon;
import org.eclipse.persistence.tools.workbench.framework.OpenException;
import org.eclipse.persistence.tools.workbench.framework.UnsupportedFileException;
import org.eclipse.persistence.tools.workbench.framework.app.ApplicationNode;
import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext;
import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository;
import org.eclipse.persistence.tools.workbench.framework.ui.dialog.WaitDialog;
import org.eclipse.persistence.tools.workbench.uitools.CancelException;
/**
* allow a project to be read in a separate thread
*/
final class RunnableProjectLoader implements Runnable {
private volatile FrameworkNodeManager nodeManager;
private File projectFile;
private WorkbenchContext context;
Dialog waitDialog;
// ********** constructor/initialization **********
RunnableProjectLoader(FrameworkNodeManager nodeManager, File projectFile, WorkbenchContext context) {
super();
this.nodeManager = nodeManager;
this.projectFile = projectFile;
this.context = context;
this.waitDialog = this.buildWaitDialog();
}
private Dialog buildWaitDialog() {
Window owner = this.context.getCurrentWindow();
ResourceRepository rr = this.context.getApplicationContext().getResourceRepository();
Icon icon = rr.getIcon("file.mwp.large");
String title = rr.getString("PROJECT_LOADER_DIALOG.TITLE");
String message = rr.getString("OPENING_PROJECT_MESSAGE", this.projectFile.getName());
return (owner instanceof Frame) ?
new WaitDialog((Frame) owner, icon, title, message)
:
new WaitDialog((Dialog) owner, icon, title, message);
}
// ********** Runnable implementation **********
/**
* launch the dialog, open the project file, add the node to the node
* manager, and shut down the dialog
*/
public void run() {
try {
this.run2();
} catch (Throwable t) {
// we're probably in trouble if we get here...
this.waitDialog.dispose();
EventQueue.invokeLater(this.buildDialogLauncher(this.buildExceptionDialog("OPEN_EXCEPTION", new Object[] {this.projectFile.getName()}, t)));
}
}
private void run2() throws InterruptedException, InvocationTargetException {
// put the dialog launcher on the AWT event queue
EventQueue.invokeLater(this.buildDialogLauncher(this.waitDialog));
ApplicationNode node = null;
try {
node = this.nodeManager.openCallback(this.projectFile, this.context);
} catch (OpenException ex) {
// shut down the dialog and display an error dialog
this.waitDialog.dispose();
EventQueue.invokeLater(this.buildDialogLauncher(this.buildExceptionDialog("OPEN_EXCEPTION", new Object[] {this.projectFile.getName()}, ex)));
return;
} catch (UnsupportedFileException ex) {
// shut down the dialog and display an error dialog
this.waitDialog.dispose();
EventQueue.invokeLater(this.buildDialogLauncher(this.buildExceptionDialog("UNSUPPORTED_FILE_TYPE", new Object[] {this.projectFile.getName()}, ex)));
return;
} catch (CancelException exception) {
// just shutdown the dialog and return, no error has occurred
this.waitDialog.dispose();
return;
}
// the project read in OK - add it to the node manager and shut down the dialog
EventQueue.invokeAndWait(new NodeInstaller(this.nodeManager, node, this.projectFile, this.context));
this.waitDialog.dispose();
}
private Runnable buildDialogLauncher(final Dialog d) {
return new Runnable() {
public void run() {
d.show();
}
};
}
Dialog buildExceptionDialog(String messageKey, Object[] messageArguments, Throwable exception) {
Window owner = this.context.getCurrentWindow();
String message = this.context.getApplicationContext().getResourceRepository().getString(messageKey, messageArguments);
return (owner instanceof Frame) ?
new FrameworkExceptionDialog(message, exception, this.context) :
new FrameworkExceptionDialog(message, exception, this.context, (Dialog) owner);
}
// ********** member classes **********
/**
* a Runnable that can be placed on the AWT Event Queue
* and will add a node to the node manager when it gets "dispatched"
*/
private static class NodeInstaller implements Runnable {
private FrameworkNodeManager nodeManager;
private ApplicationNode projectNode;
private File projectFile;
private WorkbenchContext context;
NodeInstaller(FrameworkNodeManager nodeManager, ApplicationNode projectNode, File projectFile, WorkbenchContext context) {
super();
this.nodeManager = nodeManager;
this.projectNode = projectNode;
if (projectNode.saveFile() != null) {
this.projectFile = projectNode.saveFile();
} else {
this.projectFile = projectFile;
}
this.context = context;
}
public void run() {
if ( ! EventQueue.isDispatchThread()) {
throw new IllegalStateException("this method must be executed in the AWT event dispatcher thread");
}
this.nodeManager.addProjectNodeCallback(this.projectNode, this.projectFile, this.context);
}
}
}