/*
* com/mmbreakfast/unlod/app/ExtractionManager.java
*
* Copyright (C) 2000 Sil Veritas (sil_the_follower_of_dark@hotmail.com)
*/
/* This file is part of Unlod.
*
* Unlod is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Unlod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Unlod; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Unlod
*
* Copyright (C) 2000 Sil Veritas. All Rights Reserved. This work is
* distributed under the W3C(R) Software License [1] in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
*/
package com.mmbreakfast.unlod.app;
import java.awt.*;
import java.io.*;
import javax.swing.JOptionPane;
import javax.swing.ProgressMonitor;
import org.gamenet.application.mm8leveleditor.lod.LodEntry;
import java.util.*;
import com.mmbreakfast.unlod.lod.*;
public class ExtractionManager {
protected static final int PROGRESS_MIN = 0;
protected static final int PROGRESS_MAX = 250;
protected static final int DECIDE = 1;
protected static final int LIMIT = 1;
protected Extractor extractor;
protected Component parent;
protected volatile ProgressMonitor monitor;
protected volatile boolean timerAlive = false;
protected static final int DELAY = 100;
protected Thread timer;
protected Object lock = new Object();
protected ExtractorThread job;
public ExtractionManager(Component parent) {
this.parent = parent;
}
public void setFileExtractor(Extractor lodfileextractor)
{
extractor = lodfileextractor;
}
public void extractLodEntries(LodEntry[] entries, File dir, boolean convertData) {
this.stopExtraction();
synchronized (lock) {
if (entries.length == 0) {
return;
}
timerAlive = true;
monitor = new ProgressMonitor(parent, "Please wait...", "Extracting selection", PROGRESS_MIN, PROGRESS_MAX);
monitor.setMillisToDecideToPopup(DECIDE);
monitor.setMillisToPopup(LIMIT);
timer = new Thread(new ExtractionCancellationMonitor());
timer.start();
job = new ExtractorThread(Arrays.asList(entries), dir, convertData);
new Thread(job).start();
}
}
public void extract(LodFile lodFile, File dir, boolean convertData) {
this.stopExtraction();
synchronized (lock)
{
timerAlive = true;
monitor = new ProgressMonitor(parent, "Please wait...", "Extracting LOD File", PROGRESS_MIN, PROGRESS_MAX);
monitor.setProgress(0);
monitor.setMillisToDecideToPopup(DECIDE);
monitor.setMillisToPopup(LIMIT);
timer = new Thread(new ExtractionCancellationMonitor());
timer.start();
job = new ExtractorThread(lodFile.getLodEntries().values(), dir, convertData);
new Thread(job).start();
}
}
public void startExtraction(LodEntry entry) {
this.stopExtraction();
synchronized (lock) {
timerAlive = true;
monitor = new ProgressMonitor(parent, "Please wait...", "Extracting " + entry.getName(), PROGRESS_MIN, PROGRESS_MAX);
monitor.setProgress(0);
monitor.setMillisToDecideToPopup(DECIDE);
monitor.setMillisToPopup(LIMIT);
timer = new Thread(new ExtractionCancellationMonitor());
timer.start();
}
}
private int lastProgress = -1;
protected void setProgress(int progress) {
if (progress != lastProgress)
{
monitor.setProgress(progress);
lastProgress = progress;
}
}
private String lastNote = null;
protected void setNote(String name) {
if (false == name.equals(lastNote))
{
EventQueue.invokeLater(new EntryUpdater(name));
lastNote = name;
}
}
protected void updateEntry(String name) {
monitor.setNote("Extracting " + name);
}
protected void updateProgress(int progress) {
EventQueue.invokeLater(new ProgressMonitorUpdater(progress));
}
public void stopExtraction() {
this.cancelExtraction();
timerAlive = false;
if (timer != null) {
timer.interrupt();
}
if (monitor != null) {
//this.updateProgress(PROGRESS_MAX);
monitor.close();
}
}
public void cancelExtraction() {
if (null == extractor) return;
extractor.cancelExtraction();
//this.stopExtraction();
}
protected class ProgressMonitorUpdater implements Runnable {
private int progress;
public ProgressMonitorUpdater(int progress) {
this.progress = progress;
}
public void run() {
ExtractionManager.this.setProgress(progress);
}
}
protected class ExtractionCancellationMonitor implements Runnable {
public void run() {
synchronized (lock) {
while (timerAlive && !monitor.isCanceled())
{
try
{
Thread.sleep(DELAY);
} catch (InterruptedException e) {}
}
if (monitor.isCanceled()) {
ExtractionManager.this.cancelExtraction();
}
timerAlive = false;
}
}
}
protected class ProgressExtractionObserver implements ExtractionObserver {
public void directoryCreated() {}
private int range = PROGRESS_MAX - PROGRESS_MIN;
private int lastProgressUpdate = -1;
private String lastIdentifier = null;
public int getRange()
{
return range;
}
public void extractionProgress(String identifier, float percentageDone)
{
int trackableProgress = Math.round(percentageDone * range);
if ((trackableProgress > lastProgressUpdate) || (identifier != lastIdentifier))
{
setNote(identifier);
updateProgress(PROGRESS_MIN + trackableProgress);
lastProgressUpdate = trackableProgress;
lastIdentifier = identifier;
}
}
public void extractionStarted(String identifier) {
setNote(identifier);
updateEntry(identifier);
}
public void extractionFinished(String identifier) {
timerAlive = false;
ExtractionManager.this.setNote(identifier);
updateProgress(PROGRESS_MAX);
}
public void extractionCancelled(String identifier) {
if (job != null) {
job.cancel();
}
ExtractionManager.this.updateProgress(PROGRESS_MAX);
}
public void exceptionCaught(Exception e) {
e.printStackTrace(); /// DEBUG
}
public void directoryCreated(File dir) {}
}
protected class EntryUpdater implements Runnable {
protected String name;
public EntryUpdater(String name) {
this.name = name;
}
public void run() {
ExtractionManager.this.updateEntry(name);
}
}
protected class ExtractorThread implements Runnable
{
protected Collection lodEntries;
protected File dir;
protected ExtractionJob ejob;
protected boolean convertData = true;
public ExtractorThread(Collection lodEntries, File dir,
boolean convertData)
{
this.lodEntries = lodEntries;
this.dir = dir;
this.convertData = convertData;
}
public void cancel()
{
if (ejob != null)
{
ejob.cancelJob();
}
}
public void run()
{
try
{
Thread.currentThread().setPriority(
Thread.currentThread().getPriority() - 1);
ArrayList list = new ArrayList(lodEntries);
Collections.sort(list);
ejob = new ExtractionJob(list.iterator(), list.size());
ejob.extractToFiles(dir, new ProgressExtractionObserver(),
true, convertData);
}
catch (final Throwable exception)
{
exception.printStackTrace();
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JOptionPane.showMessageDialog(parent, exception.getMessage(), "Extraction Error", JOptionPane.ERROR_MESSAGE);
}
});
}
}
}
}