From: David ‘Bombe’ Roden Date: Tue, 31 May 2016 18:26:49 +0000 (+0200) Subject: Merge branch 'release-0.13' X-Git-Tag: 0.13^0 X-Git-Url: https://git.pterodactylus.net/?p=jSite.git;a=commitdiff_plain;h=d01d8e6ceadffe3b8bd2cf9f84f4bbd75cba4752;hp=668e00b821dce97504e8afed5038d4266ac67ce9 Merge branch 'release-0.13' --- diff --git a/pom.xml b/pom.xml index 88db65b..2bc9a9c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,19 +4,32 @@ jSite ${version} - 0.12 + 0.13 UTF-8 net.pterodactylus utils - 0.12.1 + 0.13 - com.google.guava - guava - 14.0.1 + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-library + 1.3 + test + + + org.mockito + mockito-core + 1.10.19 + test @@ -31,8 +44,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 UTF-8 @@ -85,7 +98,7 @@ org.jacoco jacoco-maven-plugin - 0.7.1.201405082137 + 0.7.5.201505241946 default-prepare-agent diff --git a/src/main/java/de/todesbaum/jsite/application/FileOption.java b/src/main/java/de/todesbaum/jsite/application/FileOption.java index 4c38286..8509257 100644 --- a/src/main/java/de/todesbaum/jsite/application/FileOption.java +++ b/src/main/java/de/todesbaum/jsite/application/FileOption.java @@ -18,10 +18,9 @@ package de.todesbaum.jsite.application; -import static com.google.common.base.Optional.absent; -import static com.google.common.base.Optional.of; +import static java.util.Optional.empty; -import com.google.common.base.Optional; +import java.util.Optional; /** * Container for various file options. @@ -64,7 +63,7 @@ public class FileOption { private String customKey; /** The changed name. */ - private Optional changedName = absent(); + private Optional changedName = empty(); /** The default MIME type. */ private final String defaultMimeType; @@ -86,6 +85,20 @@ public class FileOption { mimeType = defaultMimeType; } + public FileOption(FileOption other) { + this.insert = other.insert; + this.forceInsert = other.forceInsert; + this.insertRedirect = other.insertRedirect; + this.lastInsertHash = other.lastInsertHash; + this.lastInsertEdition = other.lastInsertEdition; + this.lastInsertFilename = other.lastInsertFilename; + this.currentHash = other.currentHash; + this.customKey = other.customKey; + this.changedName = other.changedName; + this.defaultMimeType = other.defaultMimeType; + this.mimeType = other.mimeType; + } + /** * Returns the custom key. The custom key is only used when * {@link #isInsert()} and {@link #isInsertRedirect()} both return {@code @@ -297,7 +310,7 @@ public class FileOption { * The new changed name for this file */ public void setChangedName(String changedName) { - this.changedName = ((changedName != null) && (changedName.length() > 0)) ? of(changedName) : Optional.absent(); + this.changedName = ((changedName != null) && (changedName.length() > 0)) ? Optional.of(changedName) : Optional.empty(); } /** diff --git a/src/main/java/de/todesbaum/jsite/application/Freenet7Interface.java b/src/main/java/de/todesbaum/jsite/application/Freenet7Interface.java index 657adfe..9263010 100644 --- a/src/main/java/de/todesbaum/jsite/application/Freenet7Interface.java +++ b/src/main/java/de/todesbaum/jsite/application/Freenet7Interface.java @@ -21,6 +21,7 @@ package de.todesbaum.jsite.application; import java.io.IOException; import de.todesbaum.util.freenet.fcp2.Client; +import de.todesbaum.util.freenet.fcp2.Command; import de.todesbaum.util.freenet.fcp2.Connection; import de.todesbaum.util.freenet.fcp2.GenerateSSK; import de.todesbaum.util.freenet.fcp2.Message; @@ -39,35 +40,24 @@ public class Freenet7Interface { /** Counter. */ private static int counter = 0; + private final NodeSupplier nodeSupplier; + private final ConnectionSupplier connectionSupplier; + private final ClientSupplier clientSupplier; + /** The node to connect to. */ private Node node; /** The connection to the node. */ private Connection connection; - /** - * Sets the hostname of the node. The default port for FCP2 connections ({@link Node#DEFAULT_PORT}) - * is used. - * - * @param hostname - * The hostname of the node - */ - public void setNodeAddress(String hostname) { - node = new Node(hostname); - connection = new Connection(node, "jSite-" + number + "-connection-" + counter++); + public Freenet7Interface() { + this(new DefaultNodeSupplier(), new DefaultConnectionSupplier(), new DefaultClientSupplier()); } - /** - * Sets the hostname and the port of the node. - * - * @param hostname - * The hostname of the node - * @param port - * The port number of the node - */ - public void setNodeAddress(String hostname, int port) { - node = new Node(hostname, port); - connection = new Connection(node, "jSite-" + number + "-connection-" + counter++); + Freenet7Interface(NodeSupplier nodeSupplier, ConnectionSupplier connectionSupplier, ClientSupplier clientSupplier) { + this.nodeSupplier = nodeSupplier; + this.connectionSupplier = connectionSupplier; + this.clientSupplier = clientSupplier; } /** @@ -78,8 +68,8 @@ public class Freenet7Interface { */ public void setNode(de.todesbaum.jsite.application.Node node) { if (node != null) { - this.node = new Node(node.getHostname(), node.getPort()); - connection = new Connection(node, "jSite-" + number + "-connection-" + counter++); + this.node = nodeSupplier.supply(node.getHostname(), node.getPort()); + connection = connectionSupplier.supply(node, "jSite-" + number + "-connection-" + counter++); } else { this.node = null; connection = null; @@ -87,14 +77,6 @@ public class Freenet7Interface { } /** - * Removes the current node from the interface. - */ - public void removeNode() { - node = null; - connection = null; - } - - /** * Returns the node this interface is connecting to. * * @return The node @@ -111,7 +93,7 @@ public class Freenet7Interface { * @return The connection to the node */ public Connection getConnection(String identifier) { - return new Connection(node, identifier); + return connectionSupplier.supply(node, identifier); } /** @@ -144,7 +126,7 @@ public class Freenet7Interface { throw new IOException("Node is offline."); } GenerateSSK generateSSK = new GenerateSSK(); - Client client = new Client(connection, generateSSK); + Client client = clientSupplier.supply(connection, generateSSK); Message keypairMessage = client.readMessage(); return new String[] { keypairMessage.get("InsertURI"), keypairMessage.get("RequestURI") }; } @@ -159,4 +141,49 @@ public class Freenet7Interface { return (node != null) && (connection != null); } + public interface NodeSupplier { + + Node supply(String hostname, int port); + + } + + public static class DefaultNodeSupplier implements NodeSupplier { + + @Override + public Node supply(String hostname, int port) { + return new Node(hostname, port); + } + + } + + public interface ConnectionSupplier { + + Connection supply(Node node, String identifier); + + } + + public static class DefaultConnectionSupplier implements ConnectionSupplier { + + @Override + public Connection supply(Node node, String identifier) { + return new Connection(node, identifier); + } + + } + + public interface ClientSupplier { + + Client supply(Connection connection, Command command) throws IOException; + + } + + public static class DefaultClientSupplier implements ClientSupplier { + + @Override + public Client supply(Connection connection, Command command) throws IOException { + return new Client(connection, command); + } + + } + } diff --git a/src/main/java/de/todesbaum/jsite/application/Project.java b/src/main/java/de/todesbaum/jsite/application/Project.java index 836a2cd..59dcba9 100644 --- a/src/main/java/de/todesbaum/jsite/application/Project.java +++ b/src/main/java/de/todesbaum/jsite/application/Project.java @@ -19,8 +19,10 @@ package de.todesbaum.jsite.application; import java.io.File; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -94,7 +96,9 @@ public class Project implements Comparable { lastInsertionTime = project.lastInsertionTime; alwaysForceInserts = project.alwaysForceInserts; ignoreHiddenFiles = project.ignoreHiddenFiles; - fileOptions = new HashMap(project.fileOptions); + for (Entry fileOption : fileOptions.entrySet()) { + fileOptions.put(fileOption.getKey(), new FileOption(fileOption.getValue())); + } } /** @@ -363,13 +367,33 @@ public class Project implements Comparable { */ public FileOption getFileOption(String filename) { FileOption fileOption = fileOptions.get(filename); + String defaultMimeType = "application/octet-stream"; if (fileOption == null) { - fileOption = new FileOption(MimeTypes.getMimeType(filename.substring(filename.lastIndexOf('.') + 1))); - fileOptions.put(filename, fileOption); + List suffixes = getSuffixes(filename); + for (String suffix : suffixes) { + String mimeType = MimeTypes.getMimeType(suffix); + if (!mimeType.equals(defaultMimeType)) { + defaultMimeType = mimeType; + break; + } + } + fileOption = new FileOption(defaultMimeType); } + fileOptions.put(filename, fileOption); return fileOption; } + private List getSuffixes(String filename) { + List suffixes = new ArrayList<>(); + int dot = filename.lastIndexOf("."); + while (dot > -1) { + String suffix = filename.substring(dot + 1); + suffixes.add(0, suffix); + dot = filename.lastIndexOf(".", dot - 1); + } + return suffixes; + } + /** * Sets options for a file. * @@ -460,7 +484,7 @@ public class Project implements Comparable { if ((fileOption.getCurrentHash() != null) && (fileOption.getCurrentHash().length() > 0) && (!fileOption.getCurrentHash().equals(fileOption.getLastInsertHash()) || fileOption.isForceInsert())) { fileOption.setLastInsertEdition(edition); fileOption.setLastInsertHash(fileOption.getCurrentHash()); - fileOption.setLastInsertFilename(fileOption.getChangedName().or(fileOptionEntry.getKey())); + fileOption.setLastInsertFilename(fileOption.getChangedName().orElse(fileOptionEntry.getKey())); } fileOption.setForceInsert(false); } diff --git a/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java b/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java index 35a2452..c7dad3b 100644 --- a/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java +++ b/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java @@ -25,25 +25,26 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; import net.pterodactylus.util.io.StreamCopier.ProgressListener; -import com.google.common.base.Optional; import de.todesbaum.jsite.gui.FileScanner; -import de.todesbaum.jsite.gui.FileScanner.ScannedFile; +import de.todesbaum.jsite.gui.ScannedFile; import de.todesbaum.jsite.gui.FileScannerListener; import de.todesbaum.util.freenet.fcp2.Client; import de.todesbaum.util.freenet.fcp2.ClientPutComplexDir; -import de.todesbaum.util.freenet.fcp2.ClientPutDir.ManifestPutter; import de.todesbaum.util.freenet.fcp2.Connection; import de.todesbaum.util.freenet.fcp2.DirectFileEntry; import de.todesbaum.util.freenet.fcp2.FileEntry; @@ -66,7 +67,7 @@ public class ProjectInserter implements FileScannerListener, Runnable { private static final int random = (int) (Math.random() * Integer.MAX_VALUE); /** Counter for FCP connection identifier. */ - private static int counter = 0; + private static final AtomicInteger counter = new AtomicInteger(); private final ProjectInsertListeners projectInsertListeners = new ProjectInsertListeners(); @@ -100,9 +101,6 @@ public class ProjectInserter implements FileScannerListener, Runnable { /** The insert priority. */ private PriorityClass priority; - /** The manifest putter. */ - private ManifestPutter manifestPutter; - /** * Adds a listener to the list of registered listeners. * @@ -166,16 +164,6 @@ public class ProjectInserter implements FileScannerListener, Runnable { } /** - * Sets the manifest putter to use for inserts. - * - * @param manifestPutter - * The manifest putter to use - */ - public void setManifestPutter(ManifestPutter manifestPutter) { - this.manifestPutter = manifestPutter; - } - - /** * Starts the insert. * * @param progressListener @@ -184,9 +172,8 @@ public class ProjectInserter implements FileScannerListener, Runnable { public void start(ProgressListener progressListener) { cancelled = false; this.progressListener = progressListener; - fileScanner = new FileScanner(project); - fileScanner.addFileScannerListener(this); - new Thread(fileScanner).start(); + fileScanner = new FileScanner(project, this); + fileScanner.startInBackground(); } /** @@ -209,7 +196,7 @@ public class ProjectInserter implements FileScannerListener, Runnable { * The name and hash of the file to insert * @return A file entry for the given file */ - private FileEntry createFileEntry(ScannedFile file) { + private Optional createFileEntry(ScannedFile file) { String filename = file.getFilename(); FileOption fileOption = project.getFileOption(filename); if (fileOption.isInsert()) { @@ -218,25 +205,25 @@ public class ProjectInserter implements FileScannerListener, Runnable { if (!project.isAlwaysForceInsert() && !fileOption.isForceInsert() && file.getHash().equals(fileOption.getLastInsertHash())) { /* only insert a redirect. */ logger.log(Level.FINE, String.format("Inserting redirect to edition %d for %s.", fileOption.getLastInsertEdition(), filename)); - return new RedirectFileEntry(fileOption.getChangedName().or(filename), fileOption.getMimeType(), "SSK@" + project.getRequestURI() + "/" + project.getPath() + "-" + fileOption.getLastInsertEdition() + "/" + fileOption.getLastInsertFilename()); + return Optional.of(new RedirectFileEntry(fileOption.getChangedName().orElse(filename), fileOption.getMimeType(), "SSK@" + project.getRequestURI() + "/" + project.getPath() + "-" + fileOption.getLastInsertEdition() + "/" + fileOption.getLastInsertFilename())); } try { - return createFileEntry(filename, fileOption.getChangedName(), fileOption.getMimeType()); + return Optional.of(createFileEntry(filename, fileOption.getChangedName(), fileOption.getMimeType())); } catch (IOException ioe1) { /* ignore, null is returned. */ } } else { if (fileOption.isInsertRedirect()) { - return new RedirectFileEntry(fileOption.getChangedName().or(filename), fileOption.getMimeType(), fileOption.getCustomKey()); + return Optional.of(new RedirectFileEntry(fileOption.getChangedName().orElse(filename), fileOption.getMimeType(), fileOption.getCustomKey())); } } - return null; + return Optional.empty(); } private FileEntry createFileEntry(String filename, Optional changedName, String mimeType) throws FileNotFoundException { File physicalFile = new File(project.getLocalPath(), filename); InputStream fileEntryInputStream = new FileInputStream(physicalFile); - return new DirectFileEntry(changedName.or(filename), mimeType, fileEntryInputStream, physicalFile.length()); + return new DirectFileEntry(changedName.orElse(filename), mimeType, fileEntryInputStream, physicalFile.length()); } /** @@ -294,23 +281,16 @@ public class ProjectInserter implements FileScannerListener, Runnable { logger.log(Level.FINEST, "Ignoring {0}.", fileOptionEntry.getKey()); continue; } - String fileName = fileOption.getChangedName().or(fileOptionEntry.getKey()); + String fileName = fileOption.getChangedName().orElse(fileOptionEntry.getKey()); logger.log(Level.FINEST, "Adding “{0}” for {1}.", new Object[] { fileName, fileOptionEntry.getKey() }); if (!fileNames.add(fileName)) { checkReport.addIssue("error.duplicate-file", true, fileName); } } long totalSize = 0; - FileScanner fileScanner = new FileScanner(project); final CountDownLatch completionLatch = new CountDownLatch(1); - fileScanner.addFileScannerListener(new FileScannerListener() { - - @Override - public void fileScannerFinished(FileScanner fileScanner) { - completionLatch.countDown(); - } - }); - new Thread(fileScanner).start(); + FileScanner fileScanner = new FileScanner(project, (error, files) -> completionLatch.countDown()); + fileScanner.startInBackground(); while (completionLatch.getCount() > 0) { try { completionLatch.await(); @@ -342,7 +322,7 @@ public class ProjectInserter implements FileScannerListener, Runnable { /* create connection to node */ synchronized (lockObject) { - connection = freenetInterface.getConnection("project-insert-" + random + counter++); + connection = freenetInterface.getConnection("project-insert-" + random + counter.getAndIncrement()); } connection.setTempDirectory(tempDirectory); boolean connected = false; @@ -363,7 +343,7 @@ public class ProjectInserter implements FileScannerListener, Runnable { /* collect files */ int edition = project.getEdition(); String dirURI = "USK@" + project.getInsertURI() + "/" + project.getPath() + "/" + edition + "/"; - ClientPutComplexDir putDir = new ClientPutComplexDir("dir-" + counter++, dirURI, tempDirectory); + ClientPutComplexDir putDir = new ClientPutComplexDir("dir-" + counter.getAndIncrement(), dirURI, tempDirectory); if ((project.getIndexFile() != null) && (project.getIndexFile().length() > 0)) { FileOption indexFileOption = project.getFileOption(project.getIndexFile()); Optional changedName = indexFileOption.getChangedName(); @@ -377,12 +357,11 @@ public class ProjectInserter implements FileScannerListener, Runnable { putDir.setMaxRetries(-1); putDir.setEarlyEncode(useEarlyEncode); putDir.setPriorityClass(priority); - putDir.setManifestPutter(manifestPutter); for (ScannedFile file : files) { - FileEntry fileEntry = createFileEntry(file); - if (fileEntry != null) { + Optional fileEntry = createFileEntry(file); + if (fileEntry.isPresent()) { try { - putDir.addFileEntry(fileEntry); + putDir.addFileEntry(fileEntry.get()); } catch (IOException ioe1) { projectInsertListeners.fireProjectInsertFinished(project, false, ioe1); return; @@ -448,13 +427,12 @@ public class ProjectInserter implements FileScannerListener, Runnable { * {@inheritDoc} */ @Override - public void fileScannerFinished(FileScanner fileScanner) { - if (!fileScanner.isError()) { + public void fileScannerFinished(boolean error, Collection files) { + if (!error) { new Thread(this).start(); } else { projectInsertListeners.fireProjectInsertFinished(project, false, null); } - fileScanner.removeFileScannerListener(this); } /** diff --git a/src/main/java/de/todesbaum/jsite/application/UpdateChecker.java b/src/main/java/de/todesbaum/jsite/application/UpdateChecker.java index 24949a9..4e95b73 100644 --- a/src/main/java/de/todesbaum/jsite/application/UpdateChecker.java +++ b/src/main/java/de/todesbaum/jsite/application/UpdateChecker.java @@ -27,7 +27,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import net.pterodactylus.util.io.Closer; -import de.todesbaum.jsite.main.Main; import de.todesbaum.jsite.main.Version; import de.todesbaum.util.freenet.fcp2.Client; import de.todesbaum.util.freenet.fcp2.ClientGet; @@ -51,7 +50,7 @@ public class UpdateChecker implements Runnable { private static int counter = 0; /** The edition for the update check URL. */ - private static final int UPDATE_EDITION = 7; + private static final int UPDATE_EDITION = 11; /** The URL for update checks. */ private static final String UPDATE_KEY = "USK@1waTsw46L9-JEQ8yX1khjkfHcn--g0MlMsTlYHax9zQ,oYyxr5jyFnaTsVGDQWk9e3ddOWGKnqEASxAk08MHT2Y,AQACAAE"; @@ -69,7 +68,7 @@ public class UpdateChecker implements Runnable { private int lastUpdateEdition = UPDATE_EDITION; /** Last found version. */ - private Version lastVersion = Main.getVersion(); + private Version lastVersion; /** The freenet interface. */ private final Freenet7Interface freenetInterface; @@ -81,8 +80,9 @@ public class UpdateChecker implements Runnable { * @param freenetInterface * The freenet interface */ - public UpdateChecker(Freenet7Interface freenetInterface) { + public UpdateChecker(Freenet7Interface freenetInterface, Version currentVersion) { this.freenetInterface = freenetInterface; + this.lastVersion = currentVersion; } // diff --git a/src/main/java/de/todesbaum/jsite/gui/FileScanner.java b/src/main/java/de/todesbaum/jsite/gui/FileScanner.java index eef5158..04705b5 100644 --- a/src/main/java/de/todesbaum/jsite/gui/FileScanner.java +++ b/src/main/java/de/todesbaum/jsite/gui/FileScanner.java @@ -29,6 +29,7 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,7 +44,7 @@ import de.todesbaum.jsite.i18n.I18n; * files as an event. * * @see Project#getLocalPath() - * @see FileScannerListener#fileScannerFinished(FileScanner) + * @see FileScannerListener#fileScannerFinished(boolean, java.util.Collection) * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ public class FileScanner implements Runnable { @@ -52,7 +53,7 @@ public class FileScanner implements Runnable { private final static Logger logger = Logger.getLogger(FileScanner.class.getName()); /** The list of listeners. */ - private final List fileScannerListeners = new ArrayList(); + private final FileScannerListener fileScannerListener; /** The project to scan. */ private final Project project; @@ -72,37 +73,9 @@ public class FileScanner implements Runnable { * @param project * The project whose files to scan */ - public FileScanner(Project project) { + public FileScanner(Project project, FileScannerListener fileScannerListener) { this.project = project; - } - - /** - * Adds the given listener to the list of listeners. - * - * @param fileScannerListener - * The listener to add - */ - public void addFileScannerListener(FileScannerListener fileScannerListener) { - fileScannerListeners.add(fileScannerListener); - } - - /** - * Removes the given listener from the list of listeners. - * - * @param fileScannerListener - * The listener to remove - */ - public void removeFileScannerListener(FileScannerListener fileScannerListener) { - fileScannerListeners.remove(fileScannerListener); - } - - /** - * Notifies all listeners that the file scan finished. - */ - protected void fireFileScannerFinished() { - for (FileScannerListener fileScannerListener : new ArrayList(fileScannerListeners)) { - fileScannerListener.fileScannerFinished(this); - } + this.fileScannerListener = Objects.requireNonNull(fileScannerListener); } /** @@ -115,13 +88,17 @@ public class FileScanner implements Runnable { return lastFilename; } + public void startInBackground() { + new Thread(this).start(); + } + /** * {@inheritDoc} *

* Scans all available files in the project’s local path and emits an event * when finished. * - * @see FileScannerListener#fileScannerFinished(FileScanner) + * @see FileScannerListener#fileScannerFinished(boolean, java.util.Collection) */ @Override public void run() { @@ -134,7 +111,7 @@ public class FileScanner implements Runnable { } catch (IOException ioe1) { error = true; } - fireFileScannerFinished(); + fileScannerListener.fileScannerFinished(error, files); } /** @@ -234,95 +211,4 @@ public class FileScanner implements Runnable { return hexString.toString(); } - /** - * Container for a scanned file, consisting of the name of the file and its - * hash. - * - * @author David ‘Bombe’ Roden <bombe@freenetproject.org> - */ - public static class ScannedFile implements Comparable { - - /** The name of the file. */ - private final String filename; - - /** The hash of the file. */ - private final String hash; - - /** - * Creates a new scanned file. - * - * @param filename - * The name of the file - * @param hash - * The hash of the file - */ - public ScannedFile(String filename, String hash) { - this.filename = filename; - this.hash = hash; - } - - // - // ACCESSORS - // - - /** - * Returns the name of the file. - * - * @return The name of the file - */ - public String getFilename() { - return filename; - } - - /** - * Returns the hash of the file. - * - * @return The hash of the file - */ - public String getHash() { - return hash; - } - - // - // OBJECT METHODS - // - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return filename.hashCode(); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - return filename.equals(obj); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return filename; - } - - // - // COMPARABLE METHODS - // - - /** - * {@inheritDoc} - */ - @Override - public int compareTo(ScannedFile scannedFile) { - return filename.compareTo(scannedFile.filename); - } - - } - } diff --git a/src/main/java/de/todesbaum/jsite/gui/FileScannerListener.java b/src/main/java/de/todesbaum/jsite/gui/FileScannerListener.java index d3d5145..4088697 100644 --- a/src/main/java/de/todesbaum/jsite/gui/FileScannerListener.java +++ b/src/main/java/de/todesbaum/jsite/gui/FileScannerListener.java @@ -18,6 +18,7 @@ package de.todesbaum.jsite.gui; +import java.util.Collection; import java.util.EventListener; /** @@ -29,12 +30,6 @@ import java.util.EventListener; */ public interface FileScannerListener extends EventListener { - /** - * Notifies a listener that scanning a project’s local path has finished. - * - * @param fileScanner - * The file scanner that finished - */ - public void fileScannerFinished(FileScanner fileScanner); + void fileScannerFinished(boolean error, Collection files); -} \ No newline at end of file +} diff --git a/src/main/java/de/todesbaum/jsite/gui/KeyDialog.java b/src/main/java/de/todesbaum/jsite/gui/KeyDialog.java index 6f2c38e..9797708 100644 --- a/src/main/java/de/todesbaum/jsite/gui/KeyDialog.java +++ b/src/main/java/de/todesbaum/jsite/gui/KeyDialog.java @@ -348,7 +348,9 @@ public class KeyDialog extends JDialog { final JLabel projectLabel = new JLabel(I18n.getMessage("jsite.key-dialog.label.project")); contentPanel.add(projectLabel, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(12, 18, 0, 0), 0, 0)); - projectsComboBox = new JComboBox(new ComboBoxModelList(projects)); + synchronized (projects) { + projectsComboBox = new JComboBox(new ComboBoxModelList(projects)); + } projectsComboBox.addActionListener(new ActionListener() { @Override diff --git a/src/main/java/de/todesbaum/jsite/gui/PreferencesPage.java b/src/main/java/de/todesbaum/jsite/gui/PreferencesPage.java index 7cbeec6..5c4dcfa 100644 --- a/src/main/java/de/todesbaum/jsite/gui/PreferencesPage.java +++ b/src/main/java/de/todesbaum/jsite/gui/PreferencesPage.java @@ -40,7 +40,6 @@ import javax.swing.JTextField; import de.todesbaum.jsite.i18n.I18n; import de.todesbaum.jsite.i18n.I18nContainer; import de.todesbaum.jsite.main.ConfigurationLocator.ConfigurationLocation; -import de.todesbaum.util.freenet.fcp2.ClientPutDir.ManifestPutter; import de.todesbaum.util.freenet.fcp2.PriorityClass; import de.todesbaum.util.swing.TWizard; import de.todesbaum.util.swing.TWizardPage; @@ -112,9 +111,6 @@ public class PreferencesPage extends TWizardPage { /** The insert priority select box. */ private JComboBox insertPriorityComboBox; - /** The manifest putter select box. */ - private JComboBox manifestPutterComboBox; - /** * Creates a new “preferences” page. * @@ -266,25 +262,6 @@ public class PreferencesPage extends TWizardPage { } /** - * Returns the selected manifest putter. - * - * @return The selected manifest putter - */ - public ManifestPutter getManifestPutter() { - return (ManifestPutter) manifestPutterComboBox.getSelectedItem(); - } - - /** - * Sets the manifest putter. - * - * @param manifestPutter - * The manifest putter - */ - public void setManifestPutter(ManifestPutter manifestPutter) { - manifestPutterComboBox.setSelectedItem(manifestPutter); - } - - /** * {@inheritDoc} */ @Override @@ -466,12 +443,6 @@ public class PreferencesPage extends TWizardPage { insertPriorityComboBox.setAction(priorityAction); preferencesPanel.add(insertPriorityComboBox, new GridBagConstraints(1, 9, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 18, 0, 0), 0, 0)); - final JLabel manifestPutterLabel = new JLabel(I18n.getMessage("jsite.preferences.insert-options.manifest-putter")); - preferencesPanel.add(manifestPutterLabel, new GridBagConstraints(0, 10, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(6, 18, 0, 0), 0, 0)); - - manifestPutterComboBox = new JComboBox(ManifestPutter.values()); - preferencesPanel.add(manifestPutterComboBox, new GridBagConstraints(1, 10, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 18, 0, 0), 0, 0)); - I18nContainer.getInstance().registerRunnable(new Runnable() { /** @@ -483,7 +454,6 @@ public class PreferencesPage extends TWizardPage { configurationDirectoryLabel.setText("" + I18n.getMessage("jsite.preferences.config-directory") + ""); insertOptionsLabel.setText("" + I18n.getMessage("jsite.preferences.insert-options") + ""); insertPriorityLabel.setText(I18n.getMessage("jsite.preferences.insert-options.priority")); - manifestPutterLabel.setText(I18n.getMessage("jsite.preferences.insert-options.manifest-putter")); } }); diff --git a/src/main/java/de/todesbaum/jsite/gui/ProjectFilesPage.java b/src/main/java/de/todesbaum/jsite/gui/ProjectFilesPage.java index 0e700c9..4229e48 100644 --- a/src/main/java/de/todesbaum/jsite/gui/ProjectFilesPage.java +++ b/src/main/java/de/todesbaum/jsite/gui/ProjectFilesPage.java @@ -29,9 +29,9 @@ import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.MessageFormat; +import java.util.Collection; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Set; import javax.swing.AbstractAction; @@ -65,7 +65,6 @@ import net.pterodactylus.util.swing.SwingUtils; import net.pterodactylus.util.thread.StoppableDelay; import de.todesbaum.jsite.application.FileOption; import de.todesbaum.jsite.application.Project; -import de.todesbaum.jsite.gui.FileScanner.ScannedFile; import de.todesbaum.jsite.i18n.I18n; import de.todesbaum.jsite.i18n.I18nContainer; import de.todesbaum.util.swing.TLabel; @@ -182,8 +181,7 @@ public class ProjectFilesPage extends TWizardPage implements ActionListener, Lis @Override public void pageAdded(TWizard wizard) { /* create file scanner. */ - fileScanner = new FileScanner(project); - fileScanner.addFileScannerListener(this); + fileScanner = new FileScanner(project, this); actionScan(); this.wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous")); @@ -338,7 +336,7 @@ public class ProjectFilesPage extends TWizardPage implements ActionListener, Lis scanningFilesDialog.getContentPane().add(progressPanel, BorderLayout.CENTER); progressPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); - final TLabel scanningLabel = new TLabel(I18n.getMessage("jsite.project-files.scanning"), SwingConstants.CENTER); + final JLabel scanningLabel = new JLabel(I18n.getMessage("jsite.project-files.scanning"), SwingConstants.CENTER); progressPanel.add(scanningLabel, BorderLayout.NORTH); progressBar = new JProgressBar(SwingConstants.HORIZONTAL); progressPanel.add(progressBar, BorderLayout.SOUTH); @@ -445,7 +443,7 @@ public class ProjectFilesPage extends TWizardPage implements ActionListener, Lis scanningFilesDialog.setVisible(false); } }, 2000); - new Thread(fileScanner).start(); + fileScanner.startInBackground(); new Thread(delayedNotification).start(); new Thread(new Runnable() { @@ -470,11 +468,9 @@ public class ProjectFilesPage extends TWizardPage implements ActionListener, Lis * Updates the file list. */ @Override - public void fileScannerFinished(FileScanner fileScanner) { + public void fileScannerFinished(boolean error, Collection files) { delayedNotification.finish(); - final boolean error = fileScanner.isError(); if (!error) { - final List files = fileScanner.getFiles(); SwingUtilities.invokeLater(new Runnable() { @Override @@ -630,7 +626,7 @@ public class ProjectFilesPage extends TWizardPage implements ActionListener, Lis fileOptionsCustomKeyTextField.setText(fileOption.getCustomKey()); fileOptionsRenameCheckBox.setSelected(fileOption.getChangedName().isPresent()); fileOptionsRenameTextField.setEnabled(fileOption.getChangedName().isPresent()); - fileOptionsRenameTextField.setText(fileOption.getChangedName().or("")); + fileOptionsRenameTextField.setText(fileOption.getChangedName().orElse("")); fileOptionsMIMETypeComboBox.getModel().setSelectedItem(fileOption.getMimeType()); } else { defaultFileCheckBox.setSelected(false); diff --git a/src/main/java/de/todesbaum/jsite/gui/ProjectInsertPage.java b/src/main/java/de/todesbaum/jsite/gui/ProjectInsertPage.java index f68144d..fd793ce 100644 --- a/src/main/java/de/todesbaum/jsite/gui/ProjectInsertPage.java +++ b/src/main/java/de/todesbaum/jsite/gui/ProjectInsertPage.java @@ -55,7 +55,6 @@ import de.todesbaum.jsite.application.Project; import de.todesbaum.jsite.application.ProjectInserter; import de.todesbaum.jsite.i18n.I18n; import de.todesbaum.jsite.i18n.I18nContainer; -import de.todesbaum.util.freenet.fcp2.ClientPutDir.ManifestPutter; import de.todesbaum.util.freenet.fcp2.PriorityClass; import de.todesbaum.util.swing.TWizard; import de.todesbaum.util.swing.TWizardPage; @@ -342,17 +341,6 @@ public class ProjectInsertPage extends TWizardPage implements InsertListener, Cl projectInserter.setPriority(priority); } - /** - * Sets the manifest putter to use for the insert. - * - * @see ProjectInserter#setManifestPutter(ManifestPutter) - * @param manifestPutter - * The manifest putter - */ - public void setManifestPutter(ManifestPutter manifestPutter) { - projectInserter.setManifestPutter(manifestPutter); - } - // // INTERFACE InsertListener // diff --git a/src/main/java/de/todesbaum/jsite/gui/ScannedFile.java b/src/main/java/de/todesbaum/jsite/gui/ScannedFile.java new file mode 100644 index 0000000..00a659e --- /dev/null +++ b/src/main/java/de/todesbaum/jsite/gui/ScannedFile.java @@ -0,0 +1,92 @@ +package de.todesbaum.jsite.gui; + +/** + * Container for a scanned file, consisting of the name of the file and its + * hash. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + */ +public class ScannedFile implements Comparable { + + /** The name of the file. */ + private final String filename; + + /** The hash of the file. */ + private final String hash; + + /** + * Creates a new scanned file. + * + * @param filename + * The name of the file + * @param hash + * The hash of the file + */ + public ScannedFile(String filename, String hash) { + this.filename = filename; + this.hash = hash; + } + + // + // ACCESSORS + // + + /** + * Returns the name of the file. + * + * @return The name of the file + */ + public String getFilename() { + return filename; + } + + /** + * Returns the hash of the file. + * + * @return The hash of the file + */ + public String getHash() { + return hash; + } + + // + // OBJECT METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return filename.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + return filename.equals(obj); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return filename; + } + + // + // COMPARABLE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(ScannedFile scannedFile) { + return filename.compareTo(scannedFile.filename); + } + +} diff --git a/src/main/java/de/todesbaum/jsite/main/CLI.java b/src/main/java/de/todesbaum/jsite/main/CLI.java index 3280551..1765074 100644 --- a/src/main/java/de/todesbaum/jsite/main/CLI.java +++ b/src/main/java/de/todesbaum/jsite/main/CLI.java @@ -272,6 +272,9 @@ public class CLI implements InsertListener { */ @Override public void projectInsertProgress(Project project, int succeeded, int failed, int fatal, int total, boolean finalized) { + if (total == 0) { + return; + } outputWriter.println("Progress: " + succeeded + " done, " + failed + " failed, " + fatal + " fatal, " + total + " total" + (finalized ? " (finalized)" : "") + ", " + ((succeeded + failed + fatal) * 100 / total) + "%"); } diff --git a/src/main/java/de/todesbaum/jsite/main/Configuration.java b/src/main/java/de/todesbaum/jsite/main/Configuration.java index 2a27e89..41eafdb 100644 --- a/src/main/java/de/todesbaum/jsite/main/Configuration.java +++ b/src/main/java/de/todesbaum/jsite/main/Configuration.java @@ -43,8 +43,8 @@ import de.todesbaum.jsite.application.FileOption; import de.todesbaum.jsite.application.Node; import de.todesbaum.jsite.application.Project; import de.todesbaum.jsite.main.ConfigurationLocator.ConfigurationLocation; -import de.todesbaum.util.freenet.fcp2.ClientPutDir.ManifestPutter; import de.todesbaum.util.freenet.fcp2.PriorityClass; +import org.w3c.dom.Document; /** * The configuration. @@ -129,7 +129,10 @@ public class Configuration { StreamCopier.copy(fileInputStream, fileByteOutputStream, configurationFile.length()); fileByteOutputStream.close(); byte[] fileBytes = fileByteOutputStream.toByteArray(); - rootNode = SimpleXML.fromDocument(XML.transformToDocument(fileBytes)); + Document document = XML.transformToDocument(fileBytes); + if (document != null) { + rootNode = SimpleXML.fromDocument(document); + } return; } catch (FileNotFoundException e) { /* ignore. */ @@ -430,7 +433,7 @@ public class Configuration { fileOptionNode.append("insert", String.valueOf(fileOption.isInsert())); fileOptionNode.append("insert-redirect", String.valueOf(fileOption.isInsertRedirect())); fileOptionNode.append("custom-key", fileOption.getCustomKey()); - fileOptionNode.append("changed-name", fileOption.getChangedName().orNull()); + fileOptionNode.append("changed-name", fileOption.getChangedName().orElse(null)); fileOptionNode.append("mime-type", fileOption.getMimeType()); } } @@ -623,25 +626,4 @@ public class Configuration { return this; } - /** - * Returns the manifest putter. - * - * @return The manifest putter - */ - public ManifestPutter getManifestPutter() { - return ManifestPutter.valueOf(getNodeValue(new String[] { "manifest-putter" }, "simple").toUpperCase()); - } - - /** - * Sets the manifest putter. - * - * @param manifestPutter - * The manifest putter - * @return This configuration - */ - public Configuration setManifestPutter(ManifestPutter manifestPutter) { - rootNode.replace("manifest-putter", manifestPutter.name().toLowerCase()); - return this; - } - } diff --git a/src/main/java/de/todesbaum/jsite/main/Main.java b/src/main/java/de/todesbaum/jsite/main/Main.java index 59a3116..8a0b898 100644 --- a/src/main/java/de/todesbaum/jsite/main/Main.java +++ b/src/main/java/de/todesbaum/jsite/main/Main.java @@ -80,7 +80,7 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen private static final Logger logger = Logger.getLogger(Main.class.getName()); /** The version. */ - private static final Version VERSION = new Version(0, 12); + private static final Version VERSION = new Version(0, 13); /** The configuration. */ private Configuration configuration; @@ -126,6 +126,7 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen Locale.ENGLISH, Locale.GERMAN, Locale.FRENCH, + Locale.ITALIAN, new Locale("pl"), new Locale("fi") }; @@ -196,7 +197,7 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen jSiteIcon = IconLoader.loadIcon("/jsite-icon.png"); wizard.setIcon(jSiteIcon); - updateChecker = new UpdateChecker(freenetInterface); + updateChecker = new UpdateChecker(freenetInterface, getVersion()); updateChecker.addUpdateListener(this); updateChecker.start(); @@ -483,7 +484,6 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen ((PreferencesPage) pages.get(PageType.PAGE_PREFERENCES)).setHasCustomConfiguration(configuration.getConfigurationLocator().isValidLocation(ConfigurationLocation.CUSTOM)); ((PreferencesPage) pages.get(PageType.PAGE_PREFERENCES)).setUseEarlyEncode(configuration.useEarlyEncode()); ((PreferencesPage) pages.get(PageType.PAGE_PREFERENCES)).setPriority(configuration.getPriority()); - ((PreferencesPage) pages.get(PageType.PAGE_PREFERENCES)).setManifestPutter(configuration.getManifestPutter()); showPage(PageType.PAGE_PREFERENCES); optionsPreferencesAction.setEnabled(false); wizard.setNextEnabled(true); @@ -588,7 +588,6 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen projectInsertPage.setTempDirectory(tempDirectory); projectInsertPage.setUseEarlyEncode(configuration.useEarlyEncode()); projectInsertPage.setPriority(configuration.getPriority()); - projectInsertPage.setManifestPutter(configuration.getManifestPutter()); projectInsertPage.startInsert(); nodeMenu.setEnabled(false); optionsPreferencesAction.setEnabled(false); @@ -607,7 +606,6 @@ public class Main implements ActionListener, ListSelectionListener, WizardListen optionsPreferencesAction.setEnabled(true); configuration.setUseEarlyEncode(preferencesPage.useEarlyEncode()); configuration.setPriority(preferencesPage.getPriority()); - configuration.setManifestPutter(preferencesPage.getManifestPutter()); configuration.setConfigurationLocation(preferencesPage.getConfigurationLocation()); } } diff --git a/src/main/java/de/todesbaum/util/freenet/fcp2/ClientPutDir.java b/src/main/java/de/todesbaum/util/freenet/fcp2/ClientPutDir.java index 386fe1d..4ea4b1d 100644 --- a/src/main/java/de/todesbaum/util/freenet/fcp2/ClientPutDir.java +++ b/src/main/java/de/todesbaum/util/freenet/fcp2/ClientPutDir.java @@ -30,66 +30,9 @@ import java.io.Writer; */ public class ClientPutDir> extends ClientPut { - /** - * All possible manifest putters. Manifest putters are used to distribute - * files of a directory insert to different containers, depending on size, - * type, and other factors. - * - * @author David ‘Bombe’ Roden <bombe@freenetproject.org> - */ - public enum ManifestPutter { - - /** - * Use the “simple” manifest putter. Despite its name this is currently - * the default manifest putter. - */ - SIMPLE("simple"), - - /** Use the “default” manifest putter. */ - DEFAULT("default"); - - /** The name of the manifest putter. */ - private final String name; - - /** - * Creates a new manifest putter. - * - * @param name - * The name of the manifest putter - */ - private ManifestPutter(String name) { - this.name = name; - } - - /** - * Returns the name of the manifest putter. - * - * @return The name of the manifest putter - */ - public String getName() { - return name; - } - - // - // OBJECT METHODS - // - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return name.substring(0, 1).toUpperCase() + name.substring(1); - } - - } - /** The default file of the directory. */ protected String defaultName; - /** The manifest putter to use. */ - private ManifestPutter manifestPutter; - /** * Creates a new request with the specified name, identifier, and URI. * @@ -128,30 +71,6 @@ public class ClientPutDir> extends ClientPut { } /** - * Returns the current manifest putter. - * - * @return The current manifest putter (may be {@code null}) - */ - public ManifestPutter getManifestPutter() { - return manifestPutter; - } - - /** - * Sets the manifest putter for the “ClientPutDir” command. If {@code null} - * is given the node will choose a manifest putter. - * - * @param manifestPutter - * The manifest putter to use for the command (may be - * {@code null}) - * @return This ClientPutDir command - */ - @SuppressWarnings("unchecked") - public C setManifestPutter(ManifestPutter manifestPutter) { - this.manifestPutter = manifestPutter; - return (C) this; - } - - /** * {@inheritDoc} */ @Override @@ -159,9 +78,6 @@ public class ClientPutDir> extends ClientPut { super.write(writer); if (defaultName != null) writer.write("DefaultName=" + defaultName + LINEFEED); - if (manifestPutter != null) { - writer.write("ManifestPutter=" + manifestPutter.getName() + LINEFEED); - } } } diff --git a/src/main/java/de/todesbaum/util/swing/TLabel.java b/src/main/java/de/todesbaum/util/swing/TLabel.java index 0393f5c..822ca17 100644 --- a/src/main/java/de/todesbaum/util/swing/TLabel.java +++ b/src/main/java/de/todesbaum/util/swing/TLabel.java @@ -29,40 +29,6 @@ import javax.swing.JLabel; */ public class TLabel extends JLabel { - public TLabel() { - super(); - } - - public TLabel(int mnemonic, Component labelFor) { - super(); - setDisplayedMnemonic(mnemonic); - setLabelFor(labelFor); - } - - public TLabel(Icon image) { - super(image); - } - - public TLabel(Icon image, int mnemonic, Component labelFor) { - super(image); - setDisplayedMnemonic(mnemonic); - setLabelFor(labelFor); - } - - public TLabel(Icon image, int horizontalAlignment) { - super(image); - } - - public TLabel(Icon image, int horizontalAlignment, int mnemonic, Component labelFor) { - super(image); - setDisplayedMnemonic(mnemonic); - setLabelFor(labelFor); - } - - public TLabel(String text) { - super(text); - } - public TLabel(String text, int mnemonic, Component labelFor) { super(text); setDisplayedMnemonic(mnemonic); @@ -70,24 +36,4 @@ public class TLabel extends JLabel { setAlignmentX(0.0f); } - public TLabel(String text, Icon icon, int horizontalAlignment) { - super(text, icon, horizontalAlignment); - } - - public TLabel(String text, Icon icon, int horizontalAlignment, int mnemonic, Component labelFor) { - super(text, icon, horizontalAlignment); - setDisplayedMnemonic(mnemonic); - setLabelFor(labelFor); - } - - public TLabel(String text, int horizontalAlignment) { - super(text, horizontalAlignment); - } - - public TLabel(String text, int horizontalAlignment, int mnemonic, Component labelFor) { - super(text, horizontalAlignment); - setDisplayedMnemonic(mnemonic); - setLabelFor(labelFor); - } - } diff --git a/src/main/resources/de/todesbaum/jsite/i18n/jSite_it.properties b/src/main/resources/de/todesbaum/jsite/i18n/jSite_it.properties new file mode 100644 index 0000000..1fc66b6 --- /dev/null +++ b/src/main/resources/de/todesbaum/jsite/i18n/jSite_it.properties @@ -0,0 +1,207 @@ +# +# jSite - jSite_it.properties - Copyright © 2006–2014 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# Italian language file by Stefano Calabrese + +# Attention, translators! Most of the strings here are used directly. +# However, some of them are parsed by MessageFormat +# (http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html) +# and thus have to adhere to some rules (check the URL above). This is the +# case when a line contains placeholders like {0} or {0,number}! In these +# lines single quotes (ASCII 39) needs to be escaped by entering them twice, +# otherwise the placeholder will not be replaced! + +jsite.general.ok=OK +jsite.general.cancel=Annulla + +jsite.wizard.previous=Precedente +jsite.wizard.next=Prossimo +jsite.wizard.quit=Esci + +jsite.quit.question=Vuoi veramente uscire? +jsite.quit.question.title=Confermi l\u2019uscita? +jsite.quit.overwrite-configuration=Sovrascrivere configurazione?

Esiste gi\u00e0 un file di configurazione:
{0}

Dovrebbe essere sovrascritto? +jsite.quit.overwrite-configuration.title=Sovrascrivere configurazione? +jsite.quit.config-not-saved=Configuratione non salvata

Non \u00e8 stato possibile salvare la configurazione.
Vuoi uscire comunque? + +jsite.menu.languages=Lingue +jsite.menu.language.en=English +jsite.menu.language.de=Deutsch +jsite.menu.language.fr=Fran\u00e7ais +jsite.menu.language.it=Italiano +jsite.menu.language.pl=Polski +jsite.menu.language.fi=Suomi +jsite.menu.nodes=Nodi +jsite.menu.nodes.manage-nodes=Gestisci nodi +jsite.menu.options=Opzioni +jsite.menu.options.preferences=Preferenze +jsite.menu.help=Aiuto +jsite.menu.help.check-for-updates=Cerca aggiornamenti +jsite.menu.help.about=Informazioni + +jsite.about.message=jSite {0}

Copyright \u00a9 2006\u20132012 David Roden
Rilasciato sotto la GNU General Public License + +jsite.node-manager.heading=Gestore Nodi +jsite.node-manager.description=Gestisci i tuoi nodi qui. +jsite.node-manager.node-information=Informazioni Nodo +jsite.node-manager.add-node=Aggiungi Nodo +jsite.node-manager.new-node=Nuovo Nodo +jsite.node-manager.delete-node=Elimina Nodo +jsite.node-manager.delete-node.warning=Conferma l\u2019eliminazione del nodo

Vuoi davvero cancellare questo nodo? +jsite.node-manager.name=Nome +jsite.node-manager.hostname=Hostname +jsite.node-manager.port=Porta + +jsite.preferences.heading=Preferenze +jsite.preferences.description=Usa questa pagina per gestire alcune impostazioni globali. +jsite.preferences.temp-directory=Cartella per i file temporanei +jsite.preferences.temp-directory.default=Predefinita (scelta dal sistema) +jsite.preferences.temp-directory.custom=Personalizza +jsite.preferences.temp-directory.choose=Scegli +jsite.preferences.temp-directory.choose.approve=Scegli +jsite.preferences.config-directory=Posizione del file di configurazione +jsite.preferences.config-directory.jar=Accanto al file JAR +jsite.preferences.config-directory.home=Cartella principale +jsite.preferences.config-directory.custom=Cartella personalizzata +jsite.preferences.insert-options=Opzioni d\u2019inserimento +jsite.preferences.insert-options.use-early-encode=Genera l\u2019URI finale in anticipo +jsite.preferences.insert-options.priority=Priorit\u00e0 +jsite.preferences.insert-options.manifest-putter=Aggiungi manifesto + +jsite.insert.heading=Inserimento Progetto +jsite.insert.description=Per favore attendi mentre il progetto viene inserito. +jsite.insert.project-information=Informazioni Progetto +jsite.insert.request-uri=Freesite +jsite.insert.start-time=Tempo d\u2019inizio +jsite.insert.starting=Inizio\u2026 +jsite.insert.done=Fatto. +jsite.insert.done.title=Inserimento completato +jsite.insert.insert-aborted=L\u2019inserimento \u00e8 stato annullato. +jsite.insert.insert-aborted.title=Inserimento Annullato +jsite.insert.progress=Progresso +jsite.insert.k-per-s=KB/s +jsite.insert.insert-failed=Inserimento fallito

L\u2019inserimento del progetto \u00e8 fallito.
Non \u00e8 stato possibile inserire alcuni file. +jsite.insert.insert-failed-with-cause=Inserimento fallito

L\u2019inserimento del progetto \u00e8 fallito.
Non \u00e8 stato possibile inserire alcuni file.
Si \u00e8 verificato il seguente errore:

{0} +jsite.insert.insert-failed.title=Inserimento fallito +jsite.insert.inserted=Progetto inserito

Il tuo progetto \u00e8 stato inserito con successo. +jsite.insert.okay-copy-uri=Copia URI alla Clipboard +jsite.insert.reinserted-edition=Edizione Reinserita

L\u2019edizione che stai inserendo
\u00e8 gi\u00e0 stata inserita prima. +jsite.insert.reinserted-edition.title=Edizione Reinserita + +jsite.file-scanner.can-not-read-directory=Impossibile aprire cartella + +jsite.project.heading=Seleziona un Progetto +jsite.project.description=Seleziona un progetto da esaminare dalla seguente lista, oppure crea un nuovo progetto. +jsite.project.action.browse=Sfoglia +jsite.project.action.browse.choose=Scegli +jsite.project.action.browse.tooltip=Sfoglia per cartella +jsite.project.action.add-project=Aggiungi progetto +jsite.project.action.add-project.tooltip=Aggiungi nuovo progetto +jsite.project.new-project.name=Nuovo Progetto +jsite.project.action.delete-project=Elimina progetto +jsite.project.action.delete-project.tooltip=Cancella un progetto +jsite.project.action.delete-project.confirm=Conferma eliminzione

Il progetto \u201c{0}\u201d sar\u00e0 cancellato!
Vuoi continuare? +jsite.project.action.clone-project=Clona progetto +jsite.project.action.clone-project.copy=Copia di {0} +jsite.project.action.clone-project.tooltip=Clona il progetto selezionato +jsite.project.action.copy-uri=Copia URI sulla Clipboard +jsite.project.action.copy-uri.tooltip=Copia l\u2019URI del progetto sulla clipboard +jsite.project.action.manage-keys=Gestisci Chiavi +jsite.project.action.manage-keys.tooltip=Gestisce le chiavi di questo progetto +jsite.project.action.reset-edition=Resetta Edizione +jsite.project.action.reset-edition.tooltip=Resetta il numero di edizione del progetto +jsite.project.project.information=Informazioni Progetto +jsite.project.project.name=Nome +jsite.project.project.description=Descrizione +jsite.project.project.local-path=Percorso locale +jsite.project.project.address=Indirizzo +jsite.project.project.path=Percorso Freesite +jsite.project.project.edition=Edizione +jsite.project.project.uri=URI +jsite.project.keygen.io-error=Comunicazione nodo fallita

La comunicazione con il nodo \u00e8 fallita
con il seguente messaggio d\u2019errore:

{0}

Per favore, assicurati d\u2019aver inserito
l\u2019hostname ed il numero della porta corretti
sulla pagina \u201cGestore Nodi\u201d. +jsite.project.warning.generate-new-key=Generare nuova chiave?

Se generi una nuova chiave, il tuo sito sar\u00e0 pubblicato
sotto quella nuova chiave. Qualsiasi affidamento gli altri utenti abbiano fatto
sulla vecchia chiave del tuo sito sparir\u00e0!
Inoltre, l\u2019edizione verr\u00e0 resettata. +jsite.project.warning.reset-edition=Resettare edizione?

Resettare l\u2019edizione pu\u00f2 portare ad inserimenti fallimentari
e molta confusione se non hai cambiato
il percorso o le chiavi del progetto! +jsite.project.warning.use-clipboard-now=URI copiato

Per piacere, considera il fatto che uscire da jSite adesso
potrebbe svuotare la clipboard. Sei pregato di usare immediatamente l\u2019URI
copiato in un\u2019altra finestra! + +jsite.project-files.heading=File del Progetto +jsite.project-files.description=Su questa pagina puoi specificare i parametri per i file contenuti nel progetto, come le
chiavi generate esternamente o i tipi MIME, se il rilevamento automatico \u00e8 fallito. +jsite.project-files.action.rescan=Scansiona di nuovo +jsite.project-files.action.rescan.tooltip=Scansiona di nuovo la cartella del progetto per i nuovi file +jsite.project-files.always-force-insert=Forza sempre l\u2019inserimento +jsite.project-files.always-force-insert.tooltip=Quando selezionato, tutti i file di questo progetto sono inseriti anche se non sono cambiati +jsite.project-files.ignore-hidden-files=Ignora file nascosti +jsite.project-files.ignore-hidden-files.tooltip=Se selezionato, i file nascosti non vengono inseriti +jsite.project-files.file-options=Opzioni File +jsite.project-files.default=File predefinito +jsite.project-files.default.tooltip=Specifica che questo file \u00e8 il file indice del progetto +jsite.project-files.insert=Inserisci +jsite.project-files.insert.tooltip=Non spuntarlo se non vuoi inserire questo file +jsite.project-files.force-insert=Forza inserimento +jsite.project-files.force-insert.tooltip=Forza l\u2019inserimento di questo file anche se non \u00e8 modificato +jsite.project-files.insert-redirect=Redirect +jsite.project-files.insert-redirect.tooltip=Seleziona se vuoi inserire un redirect per questo file +jsite.project-files.custom-key=Chiave personalizzata +jsite.project-files.custom-key.tooltip=La chiave creata esternamente per questo file +jsite.project-files.rename=Rinomina +jsite.project-files.rename.tooltip=Rinomina il file nel sito caricato +jsite.project-files.mime-type=Tipo MIME +jsite.project-files.mime-type.tooltip=Seleziona il tipo MIME corretto qui se il rilevamento \u00e8 fallito +jsite.project-files.container=Contenitore +jsite.project-files.container.tooltip=Seleziona un contenitore per il file corrente +jsite.project-files.scan-error=Errore scansione file

O la cartella del progetto non esiste
oppure alcuni file/cartelle dentro di esso non sono accessibili.
Per favore, torna indietro e seleziona la cartella corretta. +jsite.project-files.insert-now=Inserisci adesso +jsite.project-files.invalid-default-file=Solo i file nella cartella principale possono essere selezionati come file predefiniti. +jsite.project-files.scanning=Scansionando\u2026 + +jsite.update-checker.found-version.title=Trovata nuova versione +jsite.update-checker.found-version.message=Una nuova versione \u00e8 stata trovata.

Versione {0} (rilasciata {1,date}) +jsite.update-checker.latest-version.title=Controlla aggiornamenti +jsite.update-checker.latest-version.newer.message=Stai usando la versione {0} ma
\u00e8 stata stata trovata la versione pi\u00f9 recente ({1})! +jsite.update-checker.latest-version.older.message=Stai usando la versione {0} ma
l\u2019ultima versione \u00e8 {1}. +jsite.update-checker.latest-version.okay.message=Attualmente stai usando la versione {0}
che \u00e8 l\u2019ultima uscita. + +jsite.key-dialog.title=Gestisci Chiavi del Progetto +jsite.key-dialog.button.ok.tooltip=Conferma i cambiamenti +jsite.key-dialog.button.cancel.tooltip=Annulla i cambiamenti +jsite.key-dialog.button.copy-from-project=Copia da Progetto +jsite.key-dialog.button.copy-from-project.tooltip=Copia le chiavi pubbliche e private dal progetto selezionato +jsite.key-dialog.button.copy-from-identity=Copia da Identit\u00e0 +jsite.key-dialog.button.copy-from-identity.tooltip=Copia le chiavi pubbliche e private dall\u2019identit\u00e0 selezionata +jsite.key-dialog.button.generate=Rigenera Chiavi +jsite.key-dialog.button.generate.tooltip=Crea una nuova coppia di chiavi +jsite.key-dialog.label.keys=Chiavi +jsite.key-dialog.label.private-key=Chiave Privata +jsite.key-dialog.label.public-key=Chiave Pubblica +jsite.key-dialog.label.copy-keys=Copia Chiavi +jsite.key-dialog.label.project=Progetto +jsite.key-dialog.label.identity=Identit\u00e0 +jsite.key-dialog.label.actions=Azioni + +jsite.warning.empty-index=Nessun file predefinito

Non hai specificato un file predefinito per questo progetto.
Nonostante sia possibile inserire un progetto senza un file
predefinito, dovresti comunque specificarne uno per facilitare la navigazione. +jsite.warning.index-not-html=Il tuo file predefinito non \u00e8 HTML

Il tuo file predefinito non ha il tipo MIME \u201ctext/html\u201d!
Caricare il tuo Freesite su un browser potrebbe dare risultati inaspettati. +jsite.warning.site-larger-than-2-mib=Il sito \u00e8 pi\u00f9 grande di 2 MiB!

Il tuo sito contiene pi\u00f9 di 2 megabyte di dati.
A causa di alcuni bug su Freenet, esso probabilmente non verr\u00e0 caricato correttamente.
Prova a ridurre le dimensioni del tuo sito, oppure continua a tuo rischio. + +jsite.error.no-node-selected=Nessun nodo selezionato

Per favore, seleziona un nodo dal menu! +jsite.error.no-node-running=Il nodo non funziona

Non puoi inserire un progetto se il tuo nodo non funziona.
Per favore, attiva il nodo e riprova. +jsite.error.no-local-path=Nessun percorso locale

Non hai specificato un percorso locale per i file da inserire.
Non \u00e8 possibile continuare senza. +jsite.error.no-path=Nessun percorso freesite

Non hai specificato un percorso freesite.
Non \u00e8 possibile continuare senza. +jsite.error.index-missing=File predefinito mancante

Un file predefinito era stato specificato in precedenza ma
non esiste pi\u00f9! Per favore, seleziona
un nuovo file predefinito dalla lista dei file. +jsite.error.index-not-inserted=File predefinito non inserito

Hai scelto di non inserire il file predefinito!
Devi scegliere di inserirlo oppure selezionare
un file predefinito diverso! +jsite.error.no-custom-key=Nessuna chiave personalizzata per il file

Hai specificato di non inserire {0}
ma non hai inserito una chiave per reindirizzarlo! +jsite.error.no-files-to-insert=Nessun file da inserire

Non hai selezionato alcun file da inserire!
Per favore seleziona almeno un file da inserire. +jsite.error.duplicate-file=File duplicato

Il file {0} \u00e8 inserito due volte!
Per favore controlla i tuoi nomi file ed i redirect. diff --git a/src/main/resources/flag-it.png b/src/main/resources/flag-it.png new file mode 100644 index 0000000..9de468b Binary files /dev/null and b/src/main/resources/flag-it.png differ diff --git a/src/test/java/de/todesbaum/jsite/application/FileOptionTest.java b/src/test/java/de/todesbaum/jsite/application/FileOptionTest.java new file mode 100644 index 0000000..880b6e6 --- /dev/null +++ b/src/test/java/de/todesbaum/jsite/application/FileOptionTest.java @@ -0,0 +1,239 @@ +package de.todesbaum.jsite.application; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import java.util.Optional; + +import org.junit.Test; + +/** + * Unit test for {@link FileOption}. + * + * @author David ‘Bombe’ Roden + */ +public class FileOptionTest { + + private static final String DEFAULT_MIME_TYPE = "application/octet-stream"; + private static final String DEFAULT_CUSTOM_KEY = "CHK@"; + private static final String CUSTOM_KEY = "KSK@custom-key"; + private static final String EMPTY_CUSTOM_KEY = ""; + private static final boolean DEFAULT_INSERT = true; + private static final boolean CUSTOM_INSERT = false; + private static final boolean DEFAULT_FORCE_INSERT = false; + private static final boolean CUSTOM_FORCE_INSERT = true; + private static final boolean DEFAULT_INSERT_REDIRECT = true; + private static final boolean CUSTOM_INSERT_REDIRECT = false; + private static final String DEFAULT_LAST_INSERT_HASH = null; + private static final String CUSTOM_LAST_INSERT_HASH = "last-insert-hash"; + private static final int DEFAULT_LAST_INSERT_EDITION = 0; + private static final int CUSTOM_LAST_INSERT_EDITION = 12345; + private static final String DEFAULT_LAST_INSERT_FILENAME = null; + private static final String CUSTOM_LAST_INSERT_FILENAME = "filename.dat"; + private static final String DEFAULT_CURRENT_HASH = null; + private static final String CUSTOM_CURRENT_HASH = "current-hash"; + private static final Optional DEFAULT_CHANGED_NAME = Optional.empty(); + private static final String CUSTOM_CHANGED_NAME = "changed-name"; + private static final String NULL_CHANGED_NAME = null; + private static final String ZERO_LENGTH_CHANGED_NAME = ""; + private static final String CUSTOM_MIME_TYPE = "custom/mime-type"; + private static final String NULL_MIME_TYPE = null; + private final FileOption fileOption = new FileOption(DEFAULT_MIME_TYPE); + + @Test + public void defaultCustomKeyIsCHK() { + assertThat(fileOption.getCustomKey(), is(DEFAULT_CUSTOM_KEY)); + } + + @Test + public void customKeyIsRetainedCorrectly() { + fileOption.setCustomKey(CUSTOM_KEY); + assertThat(fileOption.getCustomKey(), is(CUSTOM_KEY)); + } + + @Test + public void nullCustomKeyIsTurnedIntoEmptyCustomKey() { + fileOption.setCustomKey(null); + assertThat(fileOption.getCustomKey(), is(EMPTY_CUSTOM_KEY)); + } + + @Test + public void defaultInsertIsTrue() { + assertThat(fileOption.isInsert(), is(DEFAULT_INSERT)); + } + + @Test + public void insertIsRetainedCorrectly() { + fileOption.setInsert(CUSTOM_INSERT); + assertThat(fileOption.isInsert(), is(CUSTOM_INSERT)); + } + + @Test + public void defaultForceInsertIsFalse() { + assertThat(fileOption.isForceInsert(), is(DEFAULT_FORCE_INSERT)); + } + + @Test + public void customForceInsertIsRetainedCorrectly() { + fileOption.setForceInsert(CUSTOM_FORCE_INSERT); + assertThat(fileOption.isForceInsert(), is(CUSTOM_FORCE_INSERT)); + } + + @Test + public void defaultInsertRedirectIsTrue() { + assertThat(fileOption.isInsertRedirect(), is(DEFAULT_INSERT_REDIRECT)); + } + + @Test + public void customInsertRedirectIsRetainedCorrectly() { + fileOption.setInsertRedirect(CUSTOM_INSERT_REDIRECT); + assertThat(fileOption.isInsertRedirect(), is(CUSTOM_INSERT_REDIRECT)); + } + + @Test + public void defaultLastInsertHashIsNull() { + assertThat(fileOption.getLastInsertHash(), is(DEFAULT_LAST_INSERT_HASH)); + } + + @Test + public void lastInsertHashIsRetainedCorrectly() { + fileOption.setLastInsertHash(CUSTOM_LAST_INSERT_HASH); + assertThat(fileOption.getLastInsertHash(), is(CUSTOM_LAST_INSERT_HASH)); + } + + @Test + public void defaultLastInsertEditionIsZero() { + assertThat(fileOption.getLastInsertEdition(), is(DEFAULT_LAST_INSERT_EDITION)); + } + + @Test + public void lastInsertEditionIsRetainedCorrectly() { + fileOption.setLastInsertEdition(CUSTOM_LAST_INSERT_EDITION); + assertThat(fileOption.getLastInsertEdition(), is(CUSTOM_LAST_INSERT_EDITION)); + } + + @Test + public void defaultLastInsertFilenameIsNull() { + assertThat(fileOption.getLastInsertFilename(), is(DEFAULT_LAST_INSERT_FILENAME)); + } + + @Test + public void lastInsertFilenameIsRetainedCorrectly() { + fileOption.setLastInsertFilename(CUSTOM_LAST_INSERT_FILENAME); + assertThat(fileOption.getLastInsertFilename(), is(CUSTOM_LAST_INSERT_FILENAME)); + } + + @Test + public void defaultCurrentHashIsNull() { + assertThat(fileOption.getCurrentHash(), is(DEFAULT_CURRENT_HASH)); + } + + @Test + public void currentHashIsRetainedCorrectly() { + fileOption.setCurrentHash(CUSTOM_CURRENT_HASH); + assertThat(fileOption.getCurrentHash(), is(CUSTOM_CURRENT_HASH)); + } + + @Test + public void defaultChangedNameIsEmpty() { + assertThat(fileOption.getChangedName(), is(DEFAULT_CHANGED_NAME)); + } + + @Test + public void changedNameIsRetainedCorrectly() { + fileOption.setChangedName(CUSTOM_CHANGED_NAME); + assertThat(fileOption.getChangedName().get(), is(CUSTOM_CHANGED_NAME)); + } + + @Test + public void nullSetsChangedNameToEmpty() { + fileOption.setChangedName(NULL_CHANGED_NAME); + assertThat(fileOption.getChangedName(), is(DEFAULT_CHANGED_NAME)); + } + + @Test + public void zeroLengthStringSetsChangedNameToEmpty() { + fileOption.setChangedName(ZERO_LENGTH_CHANGED_NAME); + assertThat(fileOption.getChangedName(), is(DEFAULT_CHANGED_NAME)); + } + + @Test + public void defaultMimeTypeIsTheOneGivenInTheConstructor() { + assertThat(fileOption.getMimeType(), is(DEFAULT_MIME_TYPE)); + } + + @Test + public void mimeTypeIsRetainedCorrectly() { + fileOption.setMimeType(CUSTOM_MIME_TYPE); + assertThat(fileOption.getMimeType(), is(CUSTOM_MIME_TYPE)); + } + + @Test + public void nullSetsMimeTypeBackToTheOneGivenInConstructor() { + fileOption.setMimeType(NULL_MIME_TYPE); + assertThat(fileOption.getMimeType(), is(DEFAULT_MIME_TYPE)); + } + + @Test + public void fileWithCustomInsertIsCustom() { + fileOption.setInsert(CUSTOM_INSERT); + assertThat(fileOption.isCustom(), is(true)); + } + + @Test + public void fileWithCustomKeyIsCustom() { + fileOption.setCustomKey(CUSTOM_KEY); + assertThat(fileOption.isCustom(), is(true)); + } + + @Test + public void fileWithChangedNameIsCustom() { + fileOption.setChangedName(CUSTOM_CHANGED_NAME); + assertThat(fileOption.isCustom(), is(true)); + } + + @Test + public void fileWithCustomMimeTypeIsCustom() { + fileOption.setMimeType(CUSTOM_MIME_TYPE); + assertThat(fileOption.isCustom(), is(true)); + } + + @Test + public void fileWithCustomInsertRedirectIsCustom() { + fileOption.setInsertRedirect(CUSTOM_INSERT_REDIRECT); + assertThat(fileOption.isCustom(), is(true)); + } + + @Test + public void unchangedFileIsNotCustom() { + assertThat(fileOption.isCustom(), is(false)); + } + + @Test + public void copyConstructorCopiesAllProperties() { + fileOption.setChangedName(CUSTOM_CHANGED_NAME); + fileOption.setInsertRedirect(CUSTOM_INSERT_REDIRECT); + fileOption.setInsert(CUSTOM_INSERT); + fileOption.setMimeType(CUSTOM_MIME_TYPE); + fileOption.setCurrentHash(CUSTOM_CURRENT_HASH); + fileOption.setCustomKey(CUSTOM_KEY); + fileOption.setForceInsert(CUSTOM_FORCE_INSERT); + fileOption.setLastInsertEdition(CUSTOM_LAST_INSERT_EDITION); + fileOption.setLastInsertFilename(CUSTOM_LAST_INSERT_FILENAME); + fileOption.setLastInsertHash(CUSTOM_LAST_INSERT_HASH); + fileOption.setCurrentHash(CUSTOM_CURRENT_HASH); + FileOption copiedFileOption = new FileOption(fileOption); + assertThat(copiedFileOption.getChangedName().get(), is(CUSTOM_CHANGED_NAME)); + assertThat(copiedFileOption.isInsertRedirect(), is(CUSTOM_INSERT_REDIRECT)); + assertThat(copiedFileOption.isInsert(), is(CUSTOM_INSERT)); + assertThat(copiedFileOption.getMimeType(), is(CUSTOM_MIME_TYPE)); + assertThat(copiedFileOption.getCurrentHash(), is(CUSTOM_CURRENT_HASH)); + assertThat(copiedFileOption.getCustomKey(), is(CUSTOM_KEY)); + assertThat(copiedFileOption.isForceInsert(), is(CUSTOM_FORCE_INSERT)); + assertThat(copiedFileOption.getLastInsertEdition(), is(CUSTOM_LAST_INSERT_EDITION)); + assertThat(copiedFileOption.getLastInsertFilename(), is(CUSTOM_LAST_INSERT_FILENAME)); + assertThat(copiedFileOption.getLastInsertHash(), is(CUSTOM_LAST_INSERT_HASH)); + assertThat(copiedFileOption.getCurrentHash(), is(CUSTOM_CURRENT_HASH)); + } + +} diff --git a/src/test/java/de/todesbaum/jsite/application/Freenet7InterfaceTest.java b/src/test/java/de/todesbaum/jsite/application/Freenet7InterfaceTest.java new file mode 100644 index 0000000..1f19977 --- /dev/null +++ b/src/test/java/de/todesbaum/jsite/application/Freenet7InterfaceTest.java @@ -0,0 +1,193 @@ +package de.todesbaum.jsite.application; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import de.todesbaum.jsite.application.Freenet7Interface.ClientSupplier; +import de.todesbaum.jsite.application.Freenet7Interface.ConnectionSupplier; +import de.todesbaum.jsite.application.Freenet7Interface.NodeSupplier; +import de.todesbaum.util.freenet.fcp2.Client; +import de.todesbaum.util.freenet.fcp2.Connection; +import de.todesbaum.util.freenet.fcp2.GenerateSSK; +import de.todesbaum.util.freenet.fcp2.Message; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +/** + * Unit test for {@link Freenet7Interface}. + * + * @author David ‘Bombe’ Roden + */ +public class Freenet7InterfaceTest { + + private static final String NODE_ADDRESS = "node-address"; + private static final int NODE_PORT = 12345; + private static final String IDENTIFIER = "connection-identifier"; + private static final String INSERT_URI = "insert-uri"; + private static final String REQUEST_URI = "request-uri"; + + @Rule + public final ExpectedException expectedException = ExpectedException.none(); + + private final NodeSupplier nodeSupplier = mock(NodeSupplier.class); + private final ConnectionSupplier connectionSupplier = mock(ConnectionSupplier.class); + private final ClientSupplier clientSupplier = mock(ClientSupplier.class); + private final Freenet7Interface freenet7Interface = new Freenet7Interface(nodeSupplier, connectionSupplier, clientSupplier); + + @Test + public void defaultConstructorCanBeCalled() { + new Freenet7Interface(); + } + + @Test + public void defaultConstructorCreatesDefaultNode() { + Freenet7Interface freenet7Interface = new Freenet7Interface(); + freenet7Interface.setNode(new Node("foo", 12345)); + de.todesbaum.util.freenet.fcp2.Node node = freenet7Interface.getNode(); + assertThat(node.getHostname(), is("foo")); + assertThat(node.getPort(), is(12345)); + } + + @Test + public void withoutSettingANodeThereIsNoNode() { + assertThat(freenet7Interface.hasNode(), is(false)); + } + + @Test + public void afterSettingANodeThereIsANode() { + when(nodeSupplier.supply(anyString(), anyInt())).thenReturn(mock(de.todesbaum.util.freenet.fcp2.Node.class)); + when(connectionSupplier.supply(any(de.todesbaum.util.freenet.fcp2.Node.class), anyString())).thenReturn(mock(Connection.class)); + freenet7Interface.setNode(new Node("foo", 12345)); + assertThat(freenet7Interface.hasNode(), is(true)); + } + + @Test + public void withoutConnectionThereIsNoNode() { + when(nodeSupplier.supply(anyString(), anyInt())).thenReturn(mock(de.todesbaum.util.freenet.fcp2.Node.class)); + freenet7Interface.setNode(new Node("foo", 12345)); + assertThat(freenet7Interface.hasNode(), is(false)); + } + + @Test + public void defaultConstructorCreatesDefaultConnection() { + Freenet7Interface freenet7Interface = new Freenet7Interface(); + Connection connection = freenet7Interface.getConnection("foo"); + assertThat(connection.getName(), is("foo")); + } + + @Test + public void settingNodeAddressUsesNodeAndConnectionSuppliers() { + Node node = new Node(NODE_ADDRESS, NODE_PORT); + freenet7Interface.setNode(node); + verify(nodeSupplier).supply(NODE_ADDRESS, NODE_PORT); + verify(connectionSupplier).supply(eq(node), anyString()); + } + + @Test + public void settingNodeRetainsNodeCorrectly() { + Node node = new Node(NODE_ADDRESS, NODE_PORT); + Node realNode = mock(Node.class); + when(nodeSupplier.supply(NODE_ADDRESS, NODE_PORT)).thenReturn(realNode); + freenet7Interface.setNode(node); + assertThat(freenet7Interface.getNode(), is(realNode)); + } + + @Test + public void newConnectionCanBeCreated() { + Connection connection = mock(Connection.class); + when(connectionSupplier.supply(any(Node.class), eq(IDENTIFIER))).thenReturn(connection); + Connection returnedConnection = freenet7Interface.getConnection(IDENTIFIER); + assertThat(returnedConnection, is(connection)); + } + + @Test + public void interfaceHasNoNodeBeforeNodeIsSet() { + assertThat(freenet7Interface.hasNode(), is(false)); + } + + @Test + public void interfaceHasNodeOnceANodeWasSet() { + Connection connection = mock(Connection.class); + when(nodeSupplier.supply(anyString(), anyInt())).thenReturn(mock(Node.class)); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + assertThat(freenet7Interface.hasNode(), is(true)); + } + + @Test + public void interfaceHasNoNodeIfNodeIsSetToNull() { + Connection connection = mock(Connection.class); + when(nodeSupplier.supply(anyString(), anyInt())).thenReturn(mock(Node.class)); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + freenet7Interface.setNode(null); + assertThat(freenet7Interface.hasNode(), is(false)); + } + + + @Test + public void nodeIsPresentIfConnectionIsConnected() throws IOException { + Connection connection = mock(Connection.class); + when(connection.isConnected()).thenReturn(true); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + assertThat(freenet7Interface.isNodePresent(), is(true)); + } + + @Test + public void nodeIsPresentIfConnectionCanBeCreated() throws IOException { + Connection connection = mock(Connection.class); + when(connection.connect()).thenReturn(true); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + assertThat(freenet7Interface.isNodePresent(), is(true)); + } + + @Test + public void exceptionIsThrownIfNodeIsNotPresentAndConnectionCanNotBeCreated() throws IOException { + Connection connection = mock(Connection.class); + doThrow(IOException.class).when(connection).connect(); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + expectedException.expect(IOException.class); + freenet7Interface.isNodePresent(); + } + + @Test + public void keyPairIsNotGeneratedIfNodeIsNotPresent() throws IOException { + Connection connection = mock(Connection.class); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + expectedException.expect(IOException.class); + freenet7Interface.generateKeyPair(); + } + + @Test + public void keyPairIsGeneratedSuccessfully() throws IOException { + Connection connection = mock(Connection.class); + when(connection.isConnected()).thenReturn(true); + when(connectionSupplier.supply(any(Node.class), anyString())).thenReturn(connection); + freenet7Interface.setNode(mock(Node.class)); + Message message = new Message("SSKKeyPair"); + message.put("InsertURI", INSERT_URI); + message.put("RequestURI", REQUEST_URI); + Client client = mock(Client.class); + when(client.readMessage()).thenReturn(message); + when(clientSupplier.supply(eq(connection), any(GenerateSSK.class))).thenReturn(client); + String[] keyPair = freenet7Interface.generateKeyPair(); + assertThat(keyPair[0], is(INSERT_URI)); + assertThat(keyPair[1], is(REQUEST_URI)); + } + +} diff --git a/src/test/java/de/todesbaum/jsite/application/ProjectTest.java b/src/test/java/de/todesbaum/jsite/application/ProjectTest.java new file mode 100644 index 0000000..df89de9 --- /dev/null +++ b/src/test/java/de/todesbaum/jsite/application/ProjectTest.java @@ -0,0 +1,22 @@ +package de.todesbaum.jsite.application; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +/** + * Unit test for {@link ProjectTest}. + * + * @author David ‘Bombe’ Roden + */ +public class ProjectTest { + + @Test + public void mimeTypeForTarBz2IsRecognizedCorrectly() { + Project project = new Project(); + FileOption fileOption = project.getFileOption("foo.tar.bz2"); + assertThat(fileOption.getMimeType(), is("application/x-gtar")); + } + +}