/*******************************************************************************
* Copyright (c) 2012 Arapiki Solutions Inc.
* 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:
* "Peter Smith <psmith@arapiki.com>" - initial API and
* implementation and/or initial documentation
*******************************************************************************/
package com.buildml.eclipse.wizards;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.progress.UIJob;
import org.xml.sax.SAXException;
import com.buildml.eclipse.MainEditor;
import com.buildml.eclipse.utils.AlertDialog;
import com.buildml.eclipse.utils.EclipsePartUtils;
import com.buildml.model.IBuildStore;
import com.buildml.scanner.FatalBuildScannerError;
import com.buildml.scanner.electricanno.ElectricAnnoScanner;
import com.buildml.utils.files.ProgressFileInputStreamListener;
/**
* Provides an Eclipse wizard for importing an ElectricAccelerator annotation file
* into a user-specified BuildStore.
*
* @author Peter Smith <psmith@arapiki.com>.
*/
public class ImportEaAnno extends Wizard implements IImportWizard {
/*=====================================================================================*
* FIELDS/TYPES
*=====================================================================================*/
/** The one-and-only wizard page */
private ImportEaAnnoPage mainPage;
/*=====================================================================================*
* CONSTRUCTORS
*=====================================================================================*/
/**
* Create a new ImportEaAnno object, which provides a UI wizard to allow the user
* to import an ElectricAccelerator file into the BuildStore.
*/
public ImportEaAnno() {
super();
}
/*=====================================================================================*
* PUBLIC METHODS
*=====================================================================================*/
/**
* Perform the operation that happens when the user presses "Finish".
* @return true if the action was accepted, else false.
*/
public boolean performFinish() {
/* we're importing content into this .bml file */
final String outputBmlFilePath = mainPage.getOutputPath();
/* here's the Annotation file we're reading from */
final String inputXmlFilePath = mainPage.getInputPath();
/*
* If the BuildStore is currently open in an editor, force it to save/close so
* we don't need to worry about concurrency problems.
*/
MainEditor bmlEditor = EclipsePartUtils.getOpenBmlEditor(new File(outputBmlFilePath));
if (bmlEditor != null) {
IWorkbenchPage page = EclipsePartUtils.getActiveWorkbenchPage();
if (page != null) {
page.closeEditor(bmlEditor, true);
}
}
/* Freshly open the BuildStore (but just not in an editor) */
IBuildStore buildStore = EclipsePartUtils.getNewBuildStore(outputBmlFilePath);
if (buildStore == null) {
return false;
}
/*
* Start the background job that does the import. Once it's finished,
* the editor will be (re)opened so the user can see the content.
*/
final IBuildStore importBuildStore = buildStore;
Job importJob = new Job("Import ElectricAccelerator Annotation File") {
/* the background job starts here... */
@Override
public IStatus run(final IProgressMonitor monitor) {
IStatus status = Status.OK_STATUS;
ElectricAnnoScanner eas = new ElectricAnnoScanner(importBuildStore);
try {
/*
* Create a listener that will monitor/display our progress in parsing the file.
* This listener reports the percentage of work completed so far (as a percentage
* of the size of file it's reading). On the first call to "progress()", we
* start our progress monitor, then we call worked() on that monitor whenever
* the percentage increases.
*/
ProgressFileInputStreamListener listener = new ProgressFileInputStreamListener() {
/** first time we've been called? */
private boolean firstReport = true;
/** the percentage complete, last time we were called */
private int lastPercentage = 0;
/**
* Progress has been made by the ElectricAnnoScanner.
*/
@Override
public void progress(long current, long total, int percentage) {
if (firstReport) {
monitor.beginTask("Importing Annotation File...", 0);
firstReport = false;
}
if (percentage != lastPercentage) {
monitor.worked(percentage - lastPercentage);
lastPercentage = percentage;
}
}
/** the import is completely done */
@Override
public void done() {
/* empty */
}
};
/*
* Start the parse - the listener will update us as we go.
*/
eas.parse(inputXmlFilePath, listener);
} catch (FileNotFoundException e) {
AlertDialog.displayErrorDialog("Error During Import",
"ElectricAccelerator annotation file " + inputXmlFilePath + " not found.");
status = Status.CANCEL_STATUS;
} catch (IOException e) {
AlertDialog.displayErrorDialog("Error During Import",
"I/O error while reading ElectricAccelerator annotation file " +
inputXmlFilePath + ".");
status = Status.CANCEL_STATUS;
} catch (SAXException e) {
AlertDialog.displayErrorDialog("Error During Import",
"Unexpected syntax in ElectricAccelerator annotation file " +
inputXmlFilePath + ".");
status = Status.CANCEL_STATUS;
} catch (FatalBuildScannerError e) {
AlertDialog.displayErrorDialog("Error During Import",
"Logic problem while scanning ElectricAccelerator annotation file " +
inputXmlFilePath + "\n" + e.getMessage());
status = Status.CANCEL_STATUS;
}
/* we're done - close the BuildStore */
monitor.done();
try {
importBuildStore.save();
} catch (IOException e) {
AlertDialog.displayErrorDialog("Import Failed",
"The build database could not be closed. " + e.getMessage());
}
importBuildStore.close();
/*
* Open the BuildStore in an editor (this must be done
* in the UI thread) so that the user can see what was just
* imported.
*/
UIJob openEditorJob = new UIJob("Open Editor") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
EclipsePartUtils.openNewEditor(outputBmlFilePath);
return Status.OK_STATUS;
}
};
openEditorJob.schedule();
return status;
}
};
/* start up the progress monitor service so that it monitors the job */
importJob.setUser(true);
importJob.schedule();
return true;
}
/*-------------------------------------------------------------------------------------*/
/**
* Initialize our wizards, adding a new UI page for the user to fill out the fields.
*/
public void init(IWorkbench workbench, IStructuredSelection selection) {
setWindowTitle("Import from an ElectricAccelerator Annotation File.");
setNeedsProgressMonitor(true);
mainPage = new ImportEaAnnoPage("Import ElectricAccelerator Annotation File.", selection);
}
/*-------------------------------------------------------------------------------------*/
/**
* Add the single wizard page to this wizard.
*/
public void addPages() {
super.addPages();
addPage(mainPage);
}
/*-------------------------------------------------------------------------------------*/
}