/*
- * jSite - a tool for uploading websites into Freenet
- * Copyright (C) 2006 David Roden
+ * jSite - ProjectInserter.java - Copyright © 2006–2011 David Roden
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import de.todesbaum.jsite.application.ProjectInserter.CheckReport.Issue;
import de.todesbaum.jsite.gui.FileScanner;
import de.todesbaum.jsite.gui.FileScannerListener;
import de.todesbaum.util.freenet.fcp2.Client;
import de.todesbaum.util.io.Closer;
import de.todesbaum.util.io.ReplacingOutputStream;
import de.todesbaum.util.io.StreamCopier;
+import de.todesbaum.util.io.StreamCopier.ProgressListener;
/**
* Manages project inserts.
/** The temp directory. */
private String tempDirectory;
+ /** The current connection. */
+ private Connection connection;
+
+ /** Whether the insert is cancelled. */
+ private volatile boolean cancelled = false;
+
+ /** Progress listener for payload transfers. */
+ private ProgressListener progressListener;
+
/**
* Adds a listener to the list of registered listeners.
*
/**
* Starts the insert.
+ *
+ * @param progressListener
+ * Listener to notify on progress events
*/
- public void start() {
+ public void start(ProgressListener progressListener) {
+ cancelled = false;
+ this.progressListener = progressListener;
fileScanner = new FileScanner(project);
fileScanner.addFileScannerListener(this);
new Thread(fileScanner).start();
}
/**
+ * Stops the current insert.
+ */
+ public void stop() {
+ cancelled = true;
+ synchronized (lockObject) {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ }
+
+ /**
* Creates an input stream that delivers the given file, replacing edition
* tokens in the file’s content, if necessary.
*
}
}
String indexFile = project.getIndexFile();
- boolean hasIndexFile = (indexFile != null);
+ boolean hasIndexFile = (indexFile != null) && (indexFile.length() > 0);
if (hasIndexFile && !project.getFileOption(indexFile).getContainer().equals("")) {
checkReport.addIssue("warning.container-index", false);
}
}
Map<String, FileOption> fileOptions = project.getFileOptions();
Set<Entry<String, FileOption>> fileOptionEntries = fileOptions.entrySet();
- boolean insert = false;
+ boolean insert = fileOptionEntries.isEmpty();
for (Entry<String, FileOption> fileOptionEntry : fileOptionEntries) {
String fileName = fileOptionEntry.getKey();
FileOption fileOption = fileOptionEntry.getValue();
List<String> files = fileScanner.getFiles();
/* create connection to node */
- Connection connection = freenetInterface.getConnection("project-insert-" + random + counter++);
+ synchronized (lockObject) {
+ connection = freenetInterface.getConnection("project-insert-" + random + counter++);
+ }
connection.setTempDirectory(tempDirectory);
boolean connected = false;
Throwable cause = null;
cause = e1;
}
- if (!connected) {
- fireProjectInsertFinished(false, cause);
+ if (!connected || cancelled) {
+ fireProjectInsertFinished(false, cancelled ? new AbortedException() : cause);
return;
}
}
putDir.setVerbosity(Verbosity.ALL);
putDir.setMaxRetries(-1);
+ putDir.setEarlyEncode(false);
for (String filename : files) {
FileEntry fileEntry = createFileEntry(filename, edition, containerFiles);
if (fileEntry != null) {
/* start request */
try {
- client.execute(putDir);
+ client.execute(putDir, progressListener);
+ fireProjectUploadFinished();
} catch (IOException ioe1) {
fireProjectInsertFinished(false, ioe1);
return;
/* parse progress and success messages */
String finalURI = null;
- boolean firstMessage = true;
boolean success = false;
boolean finished = false;
boolean disconnected = false;
- while (!finished) {
+ while (!finished && !cancelled) {
Message message = client.readMessage();
finished = (message == null) || (disconnected = client.isDisconnected());
- if (firstMessage) {
- fireProjectUploadFinished();
- firstMessage = false;
- }
logger.log(Level.FINE, "Received message: " + message);
if (!finished) {
@SuppressWarnings("null")
}
/* post-insert work */
- fireProjectInsertFinished(success, disconnected ? new IOException("Connection terminated") : null);
if (success) {
@SuppressWarnings("null")
String editionPart = finalURI.substring(finalURI.lastIndexOf('/') + 1);
project.setEdition(newEdition);
project.setLastInsertionTime(System.currentTimeMillis());
}
+ fireProjectInsertFinished(success, cancelled ? new AbortedException() : (disconnected ? new IOException("Connection terminated") : null));
}
//
return issues.size();
}
+ }
+
+ /**
+ * Container class for a single issue. An issue contains an error key
+ * that describes the error, and a fatality flag that determines whether
+ * the insert has to be aborted (if the flag is {@code true}) or if it
+ * can still be performed and only a warning should be generated (if the
+ * flag is {@code false}).
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’
+ * Roden</a>
+ */
+ public static class Issue {
+
+ /** The error key. */
+ private final String errorKey;
+
+ /** The fatality flag. */
+ private final boolean fatal;
+
+ /** Additional parameters. */
+ private String[] parameters;
+
/**
- * Container class for a single issue. An issue contains an error key
- * that describes the error, and a fatality flag that determines whether
- * the insert has to be aborted (if the flag is {@code true}) or if it
- * can still be performed and only a warning should be generated (if the
- * flag is {@code false}).
+ * Creates a new issue.
*
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’
- * Roden</a>
+ * @param errorKey
+ * The error key
+ * @param fatal
+ * The fatality flag
+ * @param parameters
+ * Any additional parameters
*/
- public static class Issue {
-
- /** The error key. */
- private final String errorKey;
-
- /** The fatality flag. */
- private final boolean fatal;
-
- /** Additional parameters. */
- private String[] parameters;
-
- /**
- * Creates a new issue.
- *
- * @param errorKey
- * The error key
- * @param fatal
- * The fatality flag
- * @param parameters
- * Any additional parameters
- */
- protected Issue(String errorKey, boolean fatal, String... parameters) {
- this.errorKey = errorKey;
- this.fatal = fatal;
- this.parameters = parameters;
- }
-
- /**
- * Returns the key of the encountered error.
- *
- * @return The error key
- */
- public String getErrorKey() {
- return errorKey;
- }
+ protected Issue(String errorKey, boolean fatal, String... parameters) {
+ this.errorKey = errorKey;
+ this.fatal = fatal;
+ this.parameters = parameters;
+ }
- /**
- * Returns whether the issue is fatal and the insert has to be
- * aborted. Otherwise only a warning should be shown.
- *
- * @return {@code true} if the insert needs to be aborted, {@code
- * false} otherwise
- */
- public boolean isFatal() {
- return fatal;
- }
+ /**
+ * Returns the key of the encountered error.
+ *
+ * @return The error key
+ */
+ public String getErrorKey() {
+ return errorKey;
+ }
- /**
- * Returns any additional parameters.
- *
- * @return The additional parameters
- */
- public String[] getParameters() {
- return parameters;
- }
+ /**
+ * Returns whether the issue is fatal and the insert has to be
+ * aborted. Otherwise only a warning should be shown.
+ *
+ * @return {@code true} if the insert needs to be aborted, {@code
+ * false} otherwise
+ */
+ public boolean isFatal() {
+ return fatal;
+ }
+ /**
+ * Returns any additional parameters.
+ *
+ * @return The additional parameters
+ */
+ public String[] getParameters() {
+ return parameters;
}
}