From: David ‘Bombe’ Roden Date: Tue, 31 May 2016 17:43:09 +0000 (+0200) Subject: Merge branch 'italian-translation' into next X-Git-Tag: 0.13^2~1 X-Git-Url: https://git.pterodactylus.net/?p=jSite.git;a=commitdiff_plain;h=0f1855d94540e29163a648d6004e2331ecf9f5b2;hp=7249254b8eb3dbbdf5328be9c30f51a5e7085a07 Merge branch 'italian-translation' into next --- diff --git a/pom.xml b/pom.xml index 88db65b..0becb74 100644 --- a/pom.xml +++ b/pom.xml @@ -11,12 +11,25 @@ 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 66efc09..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; @@ -311,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 d9146a1..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; @@ -365,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. * @@ -462,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 1504a9f..c7dad3b 100644 --- a/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java +++ b/src/main/java/de/todesbaum/jsite/application/ProjectInserter.java @@ -25,21 +25,23 @@ 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; @@ -65,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(); @@ -170,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(); } /** @@ -195,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()) { @@ -204,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()); } /** @@ -280,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(); @@ -328,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; @@ -349,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(); @@ -364,10 +358,10 @@ public class ProjectInserter implements FileScannerListener, Runnable { putDir.setEarlyEncode(useEarlyEncode); putDir.setPriorityClass(priority); 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; @@ -433,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..ce6d96f 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; @@ -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/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/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 ea072d1..41eafdb 100644 --- a/src/main/java/de/todesbaum/jsite/main/Configuration.java +++ b/src/main/java/de/todesbaum/jsite/main/Configuration.java @@ -44,6 +44,7 @@ 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.PriorityClass; +import org.w3c.dom.Document; /** * The configuration. @@ -128,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. */ @@ -429,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()); } } diff --git a/src/main/java/de/todesbaum/jsite/main/Main.java b/src/main/java/de/todesbaum/jsite/main/Main.java index 545a887..a6ac559 100644 --- a/src/main/java/de/todesbaum/jsite/main/Main.java +++ b/src/main/java/de/todesbaum/jsite/main/Main.java @@ -197,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(); 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/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")); + } + +}