Author: bombe
Date: 2008-06-22 23:52:45 +0000 (Sun, 22 Jun 2008)
New Revision: 20627
Modified:
trunk/apps/jSite/src/de/todesbaum/jsite/application/FileOption.java
trunk/apps/jSite/src/de/todesbaum/jsite/application/Freenet7Interface.java
trunk/apps/jSite/src/de/todesbaum/jsite/application/InsertListener.java
trunk/apps/jSite/src/de/todesbaum/jsite/application/Node.java
trunk/apps/jSite/src/de/todesbaum/jsite/application/Project.java
trunk/apps/jSite/src/de/todesbaum/jsite/application/ProjectInserter.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScanner.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScannerListener.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerListener.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerPage.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectFilesPage.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectInsertPage.java
trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectPage.java
trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18n.java
trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18nContainer.java
trunk/apps/jSite/src/de/todesbaum/jsite/main/CLI.java
trunk/apps/jSite/src/de/todesbaum/jsite/main/Configuration.java
trunk/apps/jSite/src/de/todesbaum/jsite/main/Main.java
trunk/apps/jSite/src/de/todesbaum/jsite/main/Version.java
Log:
version 0.4.12.2:
forgot to increase version
add lots of javadoc
more small code cleanups
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/application/FileOption.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/FileOption.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/FileOption.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -19,22 +19,55 @@
package de.todesbaum.jsite.application;
+/**
+ * Container for various file options.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
+ */
public class FileOption {
+ /** The default for the insert state. */
private static final boolean DEFAULT_INSERT = true;
+
+ /** The default for the custom key. */
private static final String DEFAULT_CUSTOM_KEY = "CHK@";
+
+ /** The default container. */
private static final String DEFAULT_CONTAINER = "";
+
+ /** The default edition range. */
private static final int DEFAULT_EDITION_RANGE = 3;
+
+ /** The default for the replace edition state. */
private static final boolean DEFAULT_REPLACE_EDITION = false;
+ /** The insert state. */
private boolean insert;
+
+ /** The custom key. */
private String customKey;
+
+ /** The default MIME type. */
private final String defaultMimeType;
+
+ /** The current MIME type. */
private String mimeType;
+
+ /** The container. */
private String container;
+
+ /** The edition range. */
private int editionRange;
+
+ /** The replace edition state. */
private boolean replaceEdition;
+ /**
+ * Creates new file options.
+ *
+ * @param defaultMimeType
+ * The default MIME type of the file
+ */
public FileOption(String defaultMimeType) {
insert = DEFAULT_INSERT;
customKey = DEFAULT_CUSTOM_KEY;
@@ -46,15 +79,21 @@
}
/**
- * @return Returns the customKey.
+ * Returns the custom key. The custom key is only used when
+ * {@link #isInsert()} returns <code>true</code>.
+ *
+ * @return The custom key
*/
public String getCustomKey() {
return customKey;
}
/**
+ * Sets the custom key. The custom key is only used when {@link
#isInsert()}
+ * returns <code>true</code>.
+ *
* @param customKey
- * The customKey to set.
+ * The custom key
*/
public void setCustomKey(String customKey) {
if (customKey == null) {
@@ -64,20 +103,36 @@
}
/**
- * @return Returns the insert.
+ * Returns whether the file should be inserted. If a file is not
inserted, a
+ * custom key has to be specified for it.
+ *
+ * @see #setCustomKey(String)
+ * @return <code>true</code> if the file should be inserted,
+ * <code>false</code> otherwise
*/
public boolean isInsert() {
return insert;
}
/**
+ * Sets whether the file should be inserted. If a file is not inserted,
a
+ * custom key has to be specified for it.
+ *
* @param insert
- * The insert to set.
+ * <code>true</code> if the file should be inserted,
+ * <code>false</code> otherwise
*/
public void setInsert(boolean insert) {
this.insert = insert;
}
+ /**
+ * Sets the MIME type of the file. Setting the MIME type to
+ * <code>null</code> will set the MIME type to the default MIME type.
+ *
+ * @param mimeType
+ * The MIME type of the file
+ */
public void setMimeType(String mimeType) {
if (mimeType == null) {
mimeType = defaultMimeType;
@@ -85,20 +140,30 @@
this.mimeType = mimeType;
}
+ /**
+ * Returns the MIME type of the file. If no custom MIME type has been
set,
+ * the default MIME type is returned.
+ *
+ * @return The MIME type of the file
+ */
public String getMimeType() {
return mimeType;
}
/**
- * @return Returns the container.
+ * Returns the name of the container this file should be put in.
+ *
+ * @return The name of the container
*/
public String getContainer() {
return container;
}
/**
+ * Sets the name of the container this file should be put in.
+ *
* @param container
- * The container to set.
+ * The name of the container
*/
public void setContainer(String container) {
if (container == null) {
@@ -107,22 +172,54 @@
this.container = container;
}
+ /**
+ * Sets whether the file should have ?$[EDITION+<i>n</i>]? tags
replaced.
+ *
+ * @param replaceEdition
+ * <code>true</code> to replace tags, <code>false</code> not
+ * to replace
+ */
public void setReplaceEdition(boolean replaceEdition) {
this.replaceEdition = replaceEdition;
}
+ /**
+ * Returns whether the file should have ?$[EDITION+<i>n</i>]? tags
+ * replaced.
+ *
+ * @return <code>true</code> if tags should be replaced,
+ * <code>false</code> otherwise
+ */
public boolean getReplaceEdition() {
return replaceEdition;
}
+ /**
+ * Sets the range of editions that should be replaced.
+ *
+ * @param editionRange
+ * The range editions to replace
+ */
public void setEditionRange(int editionRange) {
this.editionRange = editionRange;
}
+ /**
+ * Returns the range of editions that should be replaced.
+ *
+ * @return The range of editions to replace
+ */
public int getEditionRange() {
return editionRange;
}
+ /**
+ * Returns whether the options for this file have been modified, i.e.
are
+ * not at their default values.
+ *
+ * @return <code>true</code> if the options have been modified,
+ * <code>false</code> if they are at default values
+ */
public boolean isCustom() {
if (insert != DEFAULT_INSERT) {
return true;
Modified:
trunk/apps/jSite/src/de/todesbaum/jsite/application/Freenet7Interface.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/Freenet7Interface.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/Freenet7Interface.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -28,26 +28,52 @@
import de.todesbaum.util.freenet.fcp2.Node;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Interface for freenet-related operations.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Freenet7Interface {
+ /** Counter. */
private static int counter = 0;
+ /** 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, "connection-" + counter++);
}
+ /**
+ * 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, "connection-" + counter++);
}
-
+
+ /**
+ * Sets hostname and port from the given node.
+ *
+ * @param node
+ * The node to get the hostname and port from
+ */
public void setNode(de.todesbaum.jsite.application.Node node) {
if (node != null) {
this.node = new Node(node.getHostname(),
node.getPort());
@@ -57,26 +83,44 @@
connection = null;
}
}
-
+
+ /**
+ * Removes the current node from the interface.
+ */
public void removeNode() {
node = null;
connection = null;
}
/**
- * @return Returns the node.
+ * Returns the node this interface is connecting to.
+ *
+ * @return The node
*/
public Node getNode() {
return node;
}
/**
- * @return Returns the connection.
+ * Creates a new connection to the current node with the given
identifier.
+ *
+ * @param identifier
+ * The identifier of the connection
+ * @return The connection to the node
*/
public Connection getConnection(String identifier) {
return new Connection(node, identifier);
}
+ /**
+ * Checks whether the current node is connected. If the node is not
+ * connected, a connection will be tried.
+ *
+ * @return <code>true</code> if the node is connected,
<code>false</code>
+ * otherwise
+ * @throws IOException
+ * if an I/O error occurs communicating with the node
+ */
public boolean isNodePresent() throws IOException {
if (!connection.isConnected()) {
return connection.connect();
@@ -84,6 +128,15 @@
return true;
}
+ /**
+ * Generates an SSK key pair.
+ *
+ * @return An array of strings, the first one being the generated
private
+ * (insert) URI and the second one being the generated public
+ * (request) URI
+ * @throws IOException
+ * if an I/O error occurs communicating with the node
+ */
public String[] generateKeyPair() throws IOException {
if (!isNodePresent()) {
return null;
@@ -95,6 +148,8 @@
}
/**
+ * Checks whether the interface has already been configured with a node.
+ *
* @return <code>true</code> if this interface already has a node set,
* <code>false</code> otherwise
*/
Modified:
trunk/apps/jSite/src/de/todesbaum/jsite/application/InsertListener.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/InsertListener.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/InsertListener.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -22,20 +22,83 @@
import java.util.EventListener;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Interface for objects that want to be notified abount insert events.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public interface InsertListener extends EventListener {
+ /**
+ * Enumeration for the different error situations.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
+ */
public static enum ErrorType {
- KEY_COLLISION, ROUTE_NOT_FOUND, DATA_NOT_FOUND, FCP_ERROR,
IO_ERROR
+
+ /** The key does already exist. */
+ KEY_COLLISION,
+
+ /** The route to the key was not found. */
+ ROUTE_NOT_FOUND,
+
+ /** The data was not found. */
+ DATA_NOT_FOUND,
+
+ /** Error in the FCP communication. */
+ FCP_ERROR,
+
+ /** General error in the communication. */
+ IO_ERROR
}
+ /**
+ * Notifies a listener that an insert has started.
+ *
+ * @param project
+ * The project that is now being inserted
+ */
public void projectInsertStarted(Project project);
+
+ /**
+ * Notifies a listener that a project insert has generated a URI.
+ *
+ * @param project
+ * The project being inserted
+ * @param uri
+ * The generated URI
+ */
public void projectURIGenerated(Project project, String uri);
+ /**
+ * Notifies a listener that an insert has made some progress.
+ *
+ * @param project
+ * The project being inserted
+ * @param succeeded
+ * The number of succeeded blocks
+ * @param failed
+ * The number of failed blocks
+ * @param fatal
+ * The number of fatally failed blocks
+ * @param total
+ * The total number of blocks
+ * @param finalized
+ * <code>true</code> if the total number of blocks has been
+ * finalized, <code>false</code> otherwise
+ */
public void projectInsertProgress(Project project, int succeeded, int
failed, int fatal, int total, boolean finalized);
+ /**
+ * Notifies a listener that a project insert has finished.
+ *
+ * @param project
+ * The project being inserted
+ * @param success
+ * <code>true</code> if the insert succeeded,
+ * <code>false</code> otherwise
+ * @param cause
+ * The cause of a failure, if any (may be <code>null</code>)
+ */
public void projectInsertFinished(Project project, boolean success,
Throwable cause);
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/application/Node.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/Node.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/Node.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -20,64 +20,120 @@
package de.todesbaum.jsite.application;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Container for node information.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Node extends de.todesbaum.util.freenet.fcp2.Node {
+ /** The name of the node. */
protected String name;
/**
+ * Creates a new node with the given hostname and the default port.
+ *
+ * @see de.todesbaum.util.freenet.fcp2.Node#DEFAULT_PORT
* @param hostname
+ * The hostname of the new node
*/
public Node(String hostname) {
this(hostname, DEFAULT_PORT);
}
/**
+ * Creates a new node with the given hostname and port.
+ *
* @param hostname
+ * The hostname of the new node
* @param port
+ * The port of the new node
*/
public Node(String hostname, int port) {
this(hostname, port, "");
}
+ /**
+ * Creates a new node with the given hostname, port, and name.
+ *
+ * @param hostname
+ * The hostname of the new node
+ * @param port
+ * The port of the new node
+ * @param name
+ * The name of the node
+ */
public Node(String hostname, int port, String name) {
super(hostname, port);
this.name = name;
}
+ /**
+ * Creates a new node that gets its settings from the given node.
+ *
+ * @param node
+ * The node to copy
+ */
public Node(Node node) {
this(node.getHostname(), node.getPort());
}
+ /**
+ * Creates a new node from the given node, overwriting the name.
+ *
+ * @param node
+ * The node to copy from
+ * @param name
+ * The new name of the node
+ */
public Node(Node node, String name) {
this(node.getHostname(), node.getPort(), name);
}
/**
+ * Sets the name of the node.
+ *
* @param name
- * The name to set.
+ * The name of the node
*/
public void setName(String name) {
this.name = name;
}
/**
- * @return Returns the name.
+ * Returns the name of the node.
+ *
+ * @return The name of the node
*/
public String getName() {
return name;
}
+ /**
+ * Sets the hostname of the node.
+ *
+ * @param hostname
+ * The hostname of the node
+ */
public void setHostname(String hostname) {
this.hostname = hostname;
}
+ /**
+ * Sets the port of the node.
+ *
+ * @param port
+ * The port of the node
+ */
public void setPort(int port) {
this.port = port;
}
-
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * A node is considered as being equal to this node its name, hostname,
and
+ * port equal their counterparts in this node.
+ */
@Override
public boolean equals(Object o) {
if ((o == null) || !(o instanceof Node)) {
@@ -86,12 +142,23 @@
Node node = (Node) o;
return name.equals(node.name) && hostname.equals(node.hostname)
&& (port == node.port);
}
-
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The hashcode for a node is created from its name, its hostname, and
its
+ * port.
+ */
@Override
public int hashCode() {
return name.hashCode() ^ hostname.hashCode() ^ port;
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Creates a textual representation of this node.
+ */
@Override
public String toString() {
return name + " (" + hostname + ":" + port + ")";
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/application/Project.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/Project.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/Project.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -27,33 +27,54 @@
import de.todesbaum.util.mime.DefaultMIMETypes;
/**
- * @author David Roden <dr at todesbaum.dyndns.org>
- * @version $Id$
+ * Container for project information.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Project implements Comparable<Project> {
+ /** The name of the project. */
protected String name;
+
+ /** The description of the project. */
protected String description;
+ /** The insert URI of the project. */
protected String insertURI;
+
+ /** The request URI of the project. */
protected String requestURI;
+ /** The index file of the project. */
protected String indexFile;
+
+ /** The local path of the project. */
protected String localPath;
+
+ /** The remote path of the URI. */
protected String path;
+
+ /** The time of the last insertion. */
protected long lastInsertionTime;
+
/** The edition to insert to. */
protected int edition;
+ /** Options for files. */
protected Map<String, FileOption> fileOptions = new HashMap<String,
FileOption>();
+ /**
+ * Empty constructor.
+ */
public Project() {
+ /* do nothing. */
}
/**
- * Clone-constructor.
+ * Creates a new project from an existing one.
*
* @param project
+ * The project to clone
*/
public Project(Project project) {
name = project.name;
@@ -69,130 +90,180 @@
}
/**
- * @return Returns the title.
+ * Returns the name of the project.
+ *
+ * @return The name of the project
*/
public String getName() {
return name;
}
/**
- * @param title
- * The title to set.
+ * Sets the name of the project.
+ *
+ * @param name
+ * The name of the project
*/
- public void setName(String title) {
- name = title;
+ public void setName(String name) {
+ this.name = name;
}
/**
- * @return Returns the description.
+ * Returns the description of the project.
+ *
+ * @return The description of the project
*/
public String getDescription() {
return description;
}
/**
+ * Sets the description of the project.
+ *
* @param description
- * The description to set.
+ * The description of the project
*/
public void setDescription(String description) {
this.description = description;
}
/**
- * @return Returns the localPath.
+ * Returns the local path of the project.
+ *
+ * @return The local path of the project
*/
public String getLocalPath() {
return localPath;
}
/**
+ * Sets the local path of the project.
+ *
* @param localPath
- * The localPath to set.
+ * The local path of the project
*/
public void setLocalPath(String localPath) {
this.localPath = localPath;
}
/**
- * @return Returns the indexFile.
+ * Returns the name of the index file of the project, relative to the
+ * project?s local path.
+ *
+ * @return The name of the index file of the project
*/
public String getIndexFile() {
return indexFile;
}
/**
+ * Sets the name of the index file of the project, relative to the
project?s
+ * local path.
+ *
* @param indexFile
- * The indexFile to set.
+ * The name of the index file of the project
*/
public void setIndexFile(String indexFile) {
this.indexFile = indexFile;
}
/**
- * @return Returns the lastInserted.
+ * Returns the time the project was last inserted, in milliseconds
since the
+ * epoch.
+ *
+ * @return The time of the last insertion
*/
public long getLastInsertionTime() {
return lastInsertionTime;
}
/**
+ * Sets the time the project was last inserted, in milliseconds since
the
+ * last epoch.
+ *
* @param lastInserted
- * The lastInserted to set.
+ * The time of the last insertion
*/
public void setLastInsertionTime(long lastInserted) {
lastInsertionTime = lastInserted;
}
/**
- * @return Returns the name.
+ * Returns the remote path of the project. The remote path is the path
that
+ * directly follows the request URI of the project.
+ *
+ * @return The remote path of the project
*/
public String getPath() {
return path;
}
/**
- * @param name
- * The name to set.
+ * Sets the remote path of the project. The remote path is the path that
+ * directly follows the request URI of the project.
+ *
+ * @param path
+ * The remote path of the project
*/
- public void setPath(String name) {
- path = name;
+ public void setPath(String path) {
+ this.path = path;
}
/**
- * @return Returns the insertURI.
+ * Returns the insert URI of the project.
+ *
+ * @return The insert URI of the project
*/
public String getInsertURI() {
return insertURI;
}
/**
+ * Sets the insert URI of the project.
+ *
* @param insertURI
- * The insertURI to set.
+ * The insert URI of the project
*/
public void setInsertURI(String insertURI) {
this.insertURI = shortenURI(insertURI);
}
/**
- * @return Returns the requestURI.
+ * Returns the request URI of the project.
+ *
+ * @return The request URI of the project
*/
public String getRequestURI() {
return requestURI;
}
/**
+ * Sets the request URI of the project.
+ *
* @param requestURI
- * The requestURI to set.
+ * The request URI of the project
*/
public void setRequestURI(String requestURI) {
this.requestURI = shortenURI(requestURI);
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method returns the name of the project.
+ */
@Override
public String toString() {
return name;
}
+ /**
+ * Shortens the given URI by removing scheme and key-type prefixes.
+ *
+ * @param uri
+ * The URI to shorten
+ * @return The shortened URI
+ */
private String shortenURI(String uri) {
if (uri.startsWith("freenet:")) {
uri = uri.substring("freenet:".length());
@@ -209,6 +280,14 @@
return uri;
}
+ /**
+ * Shortens the name of the given file by removing the local path of the
+ * project and leading file separators.
+ *
+ * @param file
+ * The file whose name should be shortened
+ * @return The shortened name of the file
+ */
public String shortenFilename(File file) {
String filename = file.getPath();
if (filename.startsWith(localPath)) {
@@ -220,6 +299,15 @@
return filename;
}
+ /**
+ * Returns the options for the file with the given name. If the file
does
+ * not yet have any options, a new set of default options is created and
+ * returned.
+ *
+ * @param filename
+ * The name of the file, relative to the project root
+ * @return The options for the file
+ */
public FileOption getFileOption(String filename) {
FileOption fileOption = fileOptions.get(filename);
if (fileOption == null) {
@@ -229,6 +317,16 @@
return fileOption;
}
+ /**
+ * Sets options for a file.
+ *
+ * @param filename
+ * The filename to set the options for, relative to the
project
+ * root
+ * @param fileOption
+ * The options to set for the file, or <code>null</code> to
+ * remove the options for the file
+ */
public void setFileOption(String filename, FileOption fileOption) {
if (fileOption != null) {
fileOptions.put(filename, fileOption);
@@ -238,15 +336,19 @@
}
/**
- * @return Returns the fileOptions.
+ * Returns all file options.
+ *
+ * @return All file options
*/
public Map<String, FileOption> getFileOptions() {
return Collections.unmodifiableMap(fileOptions);
}
/**
+ * Sets all file options.
+ *
* @param fileOptions
- * The fileOptions to set.
+ * The file options
*/
public void setFileOptions(Map<String, FileOption> fileOptions) {
this.fileOptions.clear();
@@ -255,6 +357,8 @@
/**
* {@inheritDoc}
+ * <p>
+ * Projects are compared by their name only.
*/
public int compareTo(Project project) {
return name.compareToIgnoreCase(project.name);
@@ -282,6 +386,8 @@
/**
* Constructs the final request URI including the edition number.
*
+ * @param offset
+ * The offset for the edition number
* @return The final request URI
*/
public String getFinalRequestURI(int offset) {
Modified:
trunk/apps/jSite/src/de/todesbaum/jsite/application/ProjectInserter.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/application/ProjectInserter.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/application/ProjectInserter.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -48,81 +48,174 @@
import de.todesbaum.util.io.StreamCopier;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Manages project inserts.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class ProjectInserter implements FileScannerListener, Runnable {
+ /** Counter for FCP connection identifier. */
private static int counter = 0;
+
+ /** Whether debug mode is set. */
private boolean debug = false;
+
+ /** The list of insert listeners. */
private List<InsertListener> insertListeners = new
ArrayList<InsertListener>();
+
+ /** The freenet interface. */
protected Freenet7Interface freenetInterface;
+
+ /** The project to insert. */
protected Project project;
+
+ /** The file scanner. */
private FileScanner fileScanner;
+
+ /** Object used for synchronization. */
protected final Object lockObject = new Object();
+ /**
+ * Adds a listener to the list of registered listeners.
+ *
+ * @param insertListener
+ * The listener to add
+ */
public void addInsertListener(InsertListener insertListener) {
insertListeners.add(insertListener);
}
+ /**
+ * Removes a listener from the list of registered listeners.
+ *
+ * @param insertListener
+ * The listener to remove
+ */
public void removeInsertListener(InsertListener insertListener) {
insertListeners.remove(insertListener);
}
+ /**
+ * Notifies all listeners that the project insert has started.
+ *
+ * @see InsertListener#projectInsertStarted(Project)
+ */
protected void fireProjectInsertStarted() {
- for (InsertListener insertListener: insertListeners) {
+ for (InsertListener insertListener : insertListeners) {
insertListener.projectInsertStarted(project);
}
}
-
+
+ /**
+ * Notifies all listeners that the insert has generated a URI.
+ *
+ * @see InsertListener#projectURIGenerated(Project, String)
+ * @param uri
+ * The generated URI
+ */
protected void fireProjectURIGenerated(String uri) {
- for (InsertListener insertListener: insertListeners) {
+ for (InsertListener insertListener : insertListeners) {
insertListener.projectURIGenerated(project, uri);
}
}
+ /**
+ * Notifies all listeners that the insert has made some progress.
+ *
+ * @see InsertListener#projectInsertProgress(Project, int, int, int,
int,
+ * boolean)
+ * @param succeeded
+ * The number of succeeded blocks
+ * @param failed
+ * The number of failed blocks
+ * @param fatal
+ * The number of fatally failed blocks
+ * @param total
+ * The total number of blocks
+ * @param finalized
+ * <code>true</code> if the total number of blocks has
already
+ * been finalized, <code>false</code> otherwise
+ */
protected void fireProjectInsertProgress(int succeeded, int failed, int
fatal, int total, boolean finalized) {
- for (InsertListener insertListener: insertListeners) {
+ for (InsertListener insertListener : insertListeners) {
insertListener.projectInsertProgress(project,
succeeded, failed, fatal, total, finalized);
}
}
+ /**
+ * Notifies all listeners the project insert has finished.
+ *
+ * @see InsertListener#projectInsertFinished(Project, boolean,
Throwable)
+ * @param success
+ * <code>true</code> if the project was inserted
successfully,
+ * <code>false</code> if it failed
+ * @param cause
+ * The cause of the failure, if any
+ */
protected void fireProjectInsertFinished(boolean success, Throwable
cause) {
- for (InsertListener insertListener: insertListeners) {
+ for (InsertListener insertListener : insertListeners) {
insertListener.projectInsertFinished(project, success,
cause);
}
}
/**
+ * Sets the debug mode.
+ *
* @param debug
- * The debug to set.
+ * <code>true</code> to activate debug mode,
<code>false</code>
+ * to deactivate
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
/**
+ * Sets the project to insert.
+ *
* @param project
- * The project to set.
+ * The project to insert
*/
public void setProject(Project project) {
this.project = project;
}
/**
+ * Sets the freenet interface to use.
+ *
* @param freenetInterface
- * The freenetInterface to set.
+ * The freenet interface to use
*/
public void setFreenetInterface(Freenet7Interface freenetInterface) {
this.freenetInterface = freenetInterface;
}
+ /**
+ * Starts the insert.
+ */
public void start() {
fileScanner = new FileScanner(project);
fileScanner.addFileScannerListener(this);
new Thread(fileScanner).start();
}
+ /**
+ * Creates an input stream that delivers the given file, replacing
edition
+ * tokens in the file?s content, if necessary.
+ *
+ * @param filename
+ * The name of the file
+ * @param fileOption
+ * The file options
+ * @param edition
+ * The current edition
+ * @param length
+ * An array containing a single long which is used to
+ * <em>return</em> the final length of the file, after all
+ * replacements
+ * @return The input stream for the file
+ * @throws IOException
+ * if an I/O error occurs
+ */
private InputStream createFileInputStream(String filename, FileOption
fileOption, int edition, long[] length) throws IOException {
File file = new File(project.getLocalPath(), filename);
length[0] = file.length();
@@ -150,13 +243,30 @@
return new ByteArrayInputStream(filteredBytes);
}
+ /**
+ * Creates an input stream for a container.
+ *
+ * @param containerFiles
+ * All container definitions
+ * @param containerName
+ * The name of the container to create
+ * @param edition
+ * The current edition
+ * @param containerLength
+ * An array containing a single long which is used to
+ * <em>return</em> the final length of the container stream,
+ * after all replacements
+ * @return The input stream for the container
+ * @throws IOException
+ * if an I/O error occurs
+ */
private InputStream createContainerInputStream(Map<String,
List<String>> containerFiles, String containerName, int edition, long[]
containerLength) throws IOException {
File tempFile = File.createTempFile("jsite", ".zip");
tempFile.deleteOnExit();
FileOutputStream fileOutputStream = new
FileOutputStream(tempFile);
ZipOutputStream zipOutputStream = new
ZipOutputStream(fileOutputStream);
try {
- for (String filename:
containerFiles.get(containerName)) {
+ for (String filename :
containerFiles.get(containerName)) {
File dataFile = new
File(project.getLocalPath(), filename);
if (dataFile.exists()) {
ZipEntry zipEntry = new
ZipEntry(filename);
@@ -171,7 +281,7 @@
}
}
}
- } finally {
+ } finally {
zipOutputStream.closeEntry();
Closer.close(zipOutputStream);
Closer.close(fileOutputStream);
@@ -181,6 +291,18 @@
return new FileInputStream(tempFile);
}
+ /**
+ * Creates a file entry suitable for handing in to
+ * {@link ClientPutComplexDir#addFileEntry(FileEntry)}.
+ *
+ * @param filename
+ * The name of the file to insert
+ * @param edition
+ * The current edition
+ * @param containerFiles
+ * The container definitions
+ * @return A file entry for the given file
+ */
private FileEntry createFileEntry(String filename, int edition,
Map<String, List<String>> containerFiles) {
FileEntry fileEntry = null;
FileOption fileOption = project.getFileOption(filename);
@@ -191,6 +313,7 @@
InputStream containerInputStream =
createContainerInputStream(containerFiles, containerName, edition,
containerLength);
fileEntry = new DirectFileEntry(containerName +
".zip", "application/zip", containerInputStream, containerLength[0]);
} catch (IOException ioe1) {
+ /* ignore, null is returned. */
}
} else {
if (fileOption.isInsert()) {
@@ -199,6 +322,7 @@
InputStream fileEntryInputStream =
createFileInputStream(filename, fileOption, edition, fileLength);
fileEntry = new
DirectFileEntry(filename, project.getFileOption(filename).getMimeType(),
fileEntryInputStream, fileLength[0]);
} catch (IOException ioe1) {
+ /* ignore, null is returned. */
}
} else {
fileEntry = new RedirectFileEntry(filename,
fileOption.getMimeType(), fileOption.getCustomKey());
@@ -207,8 +331,18 @@
return fileEntry;
}
+ /**
+ * Creates container definitions.
+ *
+ * @param files
+ * The list of all files
+ * @param containers
+ * The list of all containers
+ * @param containerFiles
+ * Empty map that will be filled with container definitions
+ */
private void createContainers(List<String> files, List<String>
containers, Map<String, List<String>> containerFiles) {
- for (String filename: new ArrayList<String>(files)) {
+ for (String filename : new ArrayList<String>(files)) {
FileOption fileOption = project.getFileOption(filename);
String containerName = fileOption.getContainer();
if (!containerName.equals("")) {
@@ -240,12 +374,12 @@
} catch (IOException e1) {
cause = e1;
}
-
+
if (!connected) {
fireProjectInsertFinished(false, cause);
return;
}
-
+
Client client = new Client(connection);
/* create containers */
@@ -260,7 +394,7 @@
putDir.setDefaultName(project.getIndexFile());
putDir.setVerbosity(Verbosity.ALL);
putDir.setMaxRetries(-1);
- for (String filename: files) {
+ for (String filename : files) {
FileEntry fileEntry = createFileEntry(filename,
edition, containerFiles);
if (fileEntry != null) {
putDir.addFileEntry(fileEntry);
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScanner.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScanner.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScanner.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -29,31 +29,75 @@
import de.todesbaum.jsite.application.Project;
import de.todesbaum.jsite.i18n.I18n;
+/**
+ * Scans the local path of a project anychronously and returns the list of
found
+ * files as an event.
+ *
+ * @see Project#getLocalPath()
+ * @see FileScannerListener#fileScannerFinished(FileScanner)
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
+ */
public class FileScanner implements Runnable {
+ /** The list of listeners. */
private final List<FileScannerListener> fileScannerListeners = new
ArrayList<FileScannerListener>();
+
+ /** The project to scan. */
private final Project project;
+
+ /** The list of found files. */
private List<String> files;
+
+ /** Wether there was an error. */
private boolean error = false;
+ /**
+ * Creates a new file scanner for the given project.
+ *
+ * @param project
+ * The project whose files to scan
+ */
public FileScanner(Project project) {
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<FileScannerListener>(fileScannerListeners)) {
+ for (FileScannerListener fileScannerListener : new
ArrayList<FileScannerListener>(fileScannerListeners)) {
fileScannerListener.fileScannerFinished(this);
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Scans all available files in the project?s local path and emits an
event
+ * when finished.
+ *
+ * @see FileScannerListener#fileScannerFinished(FileScanner)
+ */
public void run() {
files = new ArrayList<String>();
error = false;
@@ -66,14 +110,35 @@
fireFileScannerFinished();
}
+ /**
+ * Returns whether there was an error scanning for files.
+ *
+ * @return <code>true</code> if there was an error, <code>false</code>
+ * otherwise
+ */
public boolean isError() {
return error;
}
+ /**
+ * Returns the list of found files.
+ *
+ * @return The list of found files
+ */
public List<String> getFiles() {
return files;
}
+ /**
+ * Recursively scans a directory and adds all found files to the given
list.
+ *
+ * @param rootDir
+ * The directory to scan
+ * @param fileList
+ * The list to which to add the found files
+ * @throws IOException
+ * if an I/O error occurs
+ */
private void scanFiles(File rootDir, List<String> fileList) throws
IOException {
File[] files = rootDir.listFiles(new FileFilter() {
@@ -84,7 +149,7 @@
if (files == null) {
throw new
IOException(I18n.getMessage("jsite.file-scanner.can-not-read-directory"));
}
- for (File file: files) {
+ for (File file : files) {
if (file.isDirectory()) {
scanFiles(file, fileList);
continue;
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScannerListener.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScannerListener.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/FileScannerListener.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -21,8 +21,21 @@
import java.util.EventListener;
+/**
+ * Listener interface for objects that want to be notified when scanning a
+ * project?s local path has finished.
+ *
+ * @see FileScanner
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
+ */
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);
}
\ No newline at end of file
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerListener.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerListener.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerListener.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -23,13 +23,20 @@
import de.todesbaum.jsite.application.Node;
-
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Listener interface for objects that want to be notified if the node
+ * configuration changes.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public interface NodeManagerListener extends EventListener {
+ /**
+ * Notifies a listener that the node configuration was changed.
+ *
+ * @param nodes
+ * The new list of nodes
+ */
public void nodesUpdated(Node[] nodes);
-
+
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerPage.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerPage.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/NodeManagerPage.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -61,21 +61,42 @@
import de.todesbaum.util.swing.TWizardPage;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Wizard page that lets the user edit his nodes.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class NodeManagerPage extends TWizardPage implements
ListSelectionListener, DocumentListener, ChangeListener {
+ /** List of node manager listeners. */
private List<NodeManagerListener> nodeManagerListeners = new
ArrayList<NodeManagerListener>();
+ /** The ?add node? action. */
protected Action addNodeAction;
+
+ /** The ?delete node? action. */
protected Action deleteNodeAction;
+
+ /** The node list model. */
private DefaultListModel nodeListModel;
+
+ /** The node list. */
private JList nodeList;
+
+ /** The node name textfield. */
private JTextField nodeNameTextField;
+
+ /** The node hostname textfield. */
private JTextField nodeHostnameTextField;
+
+ /** The spinner for the node port. */
private JSpinner nodePortSpinner;
+ /**
+ * Creates a new node manager wizard page.
+ *
+ * @param wizard
+ * The wizard this page belongs to
+ */
public NodeManagerPage(final TWizard wizard) {
super(wizard);
pageInit();
@@ -89,21 +110,42 @@
}
});
}
-
+
+ /**
+ * Adds a listener for node manager events.
+ *
+ * @param nodeManagerListener
+ * The listener to add
+ */
public void addNodeManagerListener(NodeManagerListener
nodeManagerListener) {
nodeManagerListeners.add(nodeManagerListener);
}
-
+
+ /**
+ * Removes a listener for node manager events.
+ *
+ * @param nodeManagerListener
+ * The listener to remove
+ */
public void removeNodeManagerListener(NodeManagerListener
nodeManagerListener) {
nodeManagerListeners.remove(nodeManagerListener);
}
-
+
+ /**
+ * Notifies all listeners that the node configuration has changed.
+ *
+ * @param nodes
+ * The new list of nodes
+ */
protected void fireNodesUpdated(Node[] nodes) {
- for (NodeManagerListener nodeManagerListener:
nodeManagerListeners) {
+ for (NodeManagerListener nodeManagerListener :
nodeManagerListeners) {
nodeManagerListener.nodesUpdated(nodes);
}
}
+ /**
+ * Creates all actions.
+ */
private void createActions() {
addNodeAction = new
AbstractAction(I18n.getMessage("jsite.node-manager.add-node")) {
@@ -131,6 +173,9 @@
});
}
+ /**
+ * Initializes the page and all components in it.
+ */
private void pageInit() {
createActions();
nodeListModel = new DefaultListModel();
@@ -144,7 +189,7 @@
nodeNameTextField.getDocument().putProperty("Name",
"node-name");
nodeNameTextField.getDocument().addDocumentListener(this);
nodeNameTextField.setEnabled(false);
-
+
nodeHostnameTextField = new JTextField("localhost");
nodeHostnameTextField.getDocument().putProperty("Name",
"node-hostname");
nodeHostnameTextField.getDocument().addDocumentListener(this);
@@ -190,7 +235,7 @@
}
});
}
-
+
/**
* {@inheritDoc}
*/
@@ -202,15 +247,26 @@
this.wizard.setQuitName(I18n.getMessage("jsite.wizard.quit"));
}
+ /**
+ * Sets the node list.
+ *
+ * @param nodes
+ * The list of nodes
+ */
public void setNodes(Node[] nodes) {
nodeListModel.clear();
- for (Node node: nodes) {
+ for (Node node : nodes) {
nodeListModel.addElement(node);
}
nodeList.repaint();
fireNodesUpdated(nodes);
}
+ /**
+ * Returns the node list.
+ *
+ * @return The list of nodes
+ */
public Node[] getNodes() {
Node[] returnNodes = new Node[nodeListModel.getSize()];
for (int nodeIndex = 0, nodeCount = nodeListModel.getSize();
nodeIndex < nodeCount; nodeIndex++) {
@@ -219,10 +275,25 @@
return returnNodes;
}
+ /**
+ * Returns the currently selected node.
+ *
+ * @return The selected node, or <code>null</code> if no node is
selected
+ */
private Node getSelectedNode() {
return (Node) nodeList.getSelectedValue();
}
-
+
+ /**
+ * Updates node name or hostname when the user types into the
textfields.
+ *
+ * @see #insertUpdate(DocumentEvent)
+ * @see #removeUpdate(DocumentEvent)
+ * @see #changedUpdate(DocumentEvent)
+ * @see DocumentListener
+ * @param documentEvent
+ * The document event
+ */
private void updateTextField(DocumentEvent documentEvent) {
Node node = getSelectedNode();
if (node == null) {
@@ -233,6 +304,7 @@
try {
documentText = document.getText(0,
document.getLength());
} catch (BadLocationException ble1) {
+ /* ignore. */
}
if (documentText == null) {
return;
@@ -253,6 +325,9 @@
// ACTIONS
//
+ /**
+ * Adds a new node to the list of nodes.
+ */
private void addNode() {
Node node = new Node("localhost", 9481,
I18n.getMessage("jsite.node-manager.new-node"));
nodeListModel.addElement(node);
@@ -260,6 +335,9 @@
fireNodesUpdated(getNodes());
}
+ /**
+ * Deletes the currently selected node from the list of nodes.
+ */
private void deleteNode() {
Node node = getSelectedNode();
if (node == null) {
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectFilesPage.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectFilesPage.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectFilesPage.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -73,39 +73,77 @@
import de.todesbaum.util.swing.TWizardPage;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Wizard page that lets the user manage the files of a project.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class ProjectFilesPage extends TWizardPage implements ActionListener,
ListSelectionListener, DocumentListener, FileScannerListener, ChangeListener {
+ /** The project. */
private Project project;
+ /** The ?scan files? action. */
private Action scanAction;
+
+ /** The ?edit container? action. */
private Action editContainerAction;
+
+ /** The ?add container? action. */
private Action addContainerAction;
- private Action deleteContainerAction;
+ /** The ?delete container? action. */
+ protected Action deleteContainerAction;
+
+ /** The list of project files. */
private JList projectFileList;
+
+ /** The ?default file? checkbox. */
private JCheckBox defaultFileCheckBox;
+
+ /** The ?insert? checkbox. */
private JCheckBox fileOptionsInsertCheckBox;
+
+ /** The ?custom key? textfield. */
private JTextField fileOptionsCustomKeyTextField;
+
+ /** The ?mime type? combo box. */
private JComboBox fileOptionsMIMETypeComboBox;
+
+ /** The ?mime type? combo box model. */
private DefaultComboBoxModel containerComboBoxModel;
+
+ /** The ?container? combo box. */
private JComboBox fileOptionsContainerComboBox;
+
+ /** The ?edition replacement range? spinner. */
private JSpinner replaceEditionRangeSpinner;
+
+ /** The ?replacement? check box. */
private JCheckBox replacementCheckBox;
+ /**
+ * Creates a new project file page.
+ *
+ * @param wizard
+ * The wizard the page belongs to
+ */
public ProjectFilesPage(final TWizard wizard) {
super(wizard);
pageInit();
}
+ /**
+ * Initializes the page and all its actions and components.
+ */
private void pageInit() {
createActions();
setLayout(new BorderLayout(12, 12));
add(createProjectFilesPanel(), BorderLayout.CENTER);
}
+ /**
+ * Creates all actions.
+ */
private void createActions() {
scanAction = new
AbstractAction(I18n.getMessage("jsite.project-files.action.rescan")) {
@@ -163,6 +201,9 @@
});
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void pageAdded(TWizard wizard) {
actionScan();
@@ -171,6 +212,11 @@
this.wizard.setQuitName(I18n.getMessage("jsite.wizard.quit"));
}
+ /**
+ * Creates the panel contains the project file list and options.
+ *
+ * @return The created panel
+ */
private JComponent createProjectFilesPanel() {
JPanel projectFilesPanel = new JPanel(new BorderLayout(12, 12));
@@ -287,6 +333,12 @@
return projectFilesPanel;
}
+ /**
+ * Sets the project whose files to manage.
+ *
+ * @param project
+ * The project whose files to manage
+ */
public void setProject(final Project project) {
this.project = project;
setHeading(MessageFormat.format(I18n.getMessage("jsite.project-files.heading"),
project.getName()));
@@ -300,6 +352,11 @@
});
}
+ /**
+ * Returns a list of all project files.
+ *
+ * @return All project files
+ */
private List<String> getProjectFiles() {
List<String> files = new ArrayList<String>();
for (int index = 0, size =
projectFileList.getModel().getSize(); index < size; index++) {
@@ -308,6 +365,9 @@
return files;
}
+ /**
+ * Updates the container combo box model.
+ */
private void rebuildContainerComboBox() {
/* scan files for containers */
List<String> files = getProjectFiles();
@@ -332,6 +392,9 @@
// ACTIONS
//
+ /**
+ * Rescans the project?s files.
+ */
private void actionScan() {
projectFileList.clearSelection();
projectFileList.setListData(new Object[0]);
@@ -345,6 +408,9 @@
new Thread(fileScanner).start();
}
+ /**
+ * Adds a container.
+ */
private void actionAddContainer() {
String containerName = JOptionPane.showInputDialog(wizard,
I18n.getMessage("jsite.project-files.action.add-container.message") + ":",
null, JOptionPane.INFORMATION_MESSAGE);
if (containerName == null) {
@@ -358,6 +424,9 @@
fileOptionsContainerComboBox.setSelectedItem(containerName);
}
+ /**
+ * Edits the container.
+ */
private void actionEditContainer() {
String selectedFilename = (String)
projectFileList.getSelectedValue();
FileOption fileOption = project.getFileOption(selectedFilename);
@@ -382,6 +451,9 @@
fileOptionsContainerComboBox.setSelectedItem(containerName);
}
+ /**
+ * Deletes the container.
+ */
private void actionDeleteContainer() {
if (JOptionPane.showConfirmDialog(wizard,
I18n.getMessage("jsite.project-files.action.delete-container.message"), null,
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) ==
JOptionPane.OK_OPTION) {
String containerName = (String)
fileOptionsContainerComboBox.getSelectedItem();
@@ -396,6 +468,11 @@
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Updates the file list.
+ */
public void fileScannerFinished(FileScanner fileScanner) {
final boolean error = fileScanner.isError();
if (!error) {
@@ -530,6 +607,13 @@
// INTERFACE DocumentListener
//
+ /**
+ * Updates the options of the currently selected file with the changes
made
+ * in the ?custom key? textfield.
+ *
+ * @param documentEvent
+ * The document event to process
+ */
private void processDocumentUpdate(DocumentEvent documentEvent) {
String filename = (String) projectFileList.getSelectedValue();
if (filename == null) {
@@ -541,6 +625,7 @@
String text = document.getText(0, document.getLength());
fileOption.setCustomKey(text);
} catch (BadLocationException ble1) {
+ /* ignore. */
}
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectInsertPage.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectInsertPage.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectInsertPage.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -56,19 +56,36 @@
import de.todesbaum.util.swing.TWizardPage;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Wizard page that shows the progress of an insert.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class ProjectInsertPage extends TWizardPage implements InsertListener,
ClipboardOwner {
- protected ProjectInserter projectInserter;
+ /** The project inserter. */
+ private ProjectInserter projectInserter;
- protected Action copyURIAction;
- protected JTextField requestURITextField;
- protected JLabel startTimeLabel;
- protected JProgressBar progressBar;
- protected long startTime = 0;
+ /** The ?copy URI? action. */
+ private Action copyURIAction;
+ /** The ?request URI? textfield. */
+ private JTextField requestURITextField;
+
+ /** The ?start time? label. */
+ private JLabel startTimeLabel;
+
+ /** The progress bar. */
+ private JProgressBar progressBar;
+
+ /** The start time of the insert. */
+ private long startTime = 0;
+
+ /**
+ * Creates a new progress insert wizard page.
+ *
+ * @param wizard
+ * The wizard this page belongs to
+ */
public ProjectInsertPage(final TWizard wizard) {
super(wizard);
createActions();
@@ -86,8 +103,13 @@
projectInserter.addInsertListener(this);
}
+ /**
+ * Creates all used actions.
+ */
private void createActions() {
copyURIAction = new
AbstractAction(I18n.getMessage("jsite.project.action.copy-uri")) {
+
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionCopyURI();
}
@@ -98,6 +120,7 @@
I18nContainer.getInstance().registerRunnable(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
copyURIAction.putValue(Action.NAME,
I18n.getMessage("jsite.project.action.copy-uri"));
copyURIAction.putValue(Action.SHORT_DESCRIPTION,
I18n.getMessage("jsite.project.action.copy-uri.tooltip"));
@@ -105,11 +128,19 @@
});
}
+ /**
+ * Initializes the page.
+ */
private void pageInit() {
setLayout(new BorderLayout(12, 12));
add(createProjectInsertPanel(), BorderLayout.CENTER);
}
+ /**
+ * Creates the main panel.
+ *
+ * @return The main panel
+ */
private JComponent createProjectInsertPanel() {
JComponent projectInsertPanel = new JPanel(new GridBagLayout());
@@ -137,6 +168,7 @@
I18nContainer.getInstance().registerRunnable(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
projectInformationLabel.setText("<html><b>" +
I18n.getMessage("jsite.insert.project-information") + "</b></html>");
requestURILabel.setText(I18n.getMessage("jsite.insert.request-uri") + ":");
@@ -164,6 +196,9 @@
this.wizard.setQuitName(I18n.getMessage("jsite.wizard.quit"));
}
+ /**
+ * Starts the insert.
+ */
public void startInsert() {
wizard.setNextEnabled(false);
copyURIAction.setEnabled(false);
@@ -174,27 +209,39 @@
}
/**
+ * Sets whether to activate the debug mode.
+ *
* @param debug
- * The debug to set.
+ * <code>true</code> to activate the debug mode,
+ * <code>false</code> to deactivate.
*/
public void setDebug(boolean debug) {
projectInserter.setDebug(debug);
}
/**
+ * Sets the project to insert.
+ *
* @param project
- * The project to set.
+ * The project to insert
*/
public void setProject(final Project project) {
projectInserter.setProject(project);
SwingUtilities.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
requestURITextField.setText(project.getFinalRequestURI(1));
}
});
}
+ /**
+ * Sets the freenet interface to use.
+ *
+ * @param freenetInterface
+ * The freenet interface to use
+ */
public void setFreenetInterface(Freenet7Interface freenetInterface) {
projectInserter.setFreenetInterface(freenetInterface);
}
@@ -210,6 +257,7 @@
startTime = System.currentTimeMillis();
SwingUtilities.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
startTimeLabel.setText(DateFormat.getDateTimeInstance().format(new
Date(startTime)));
}
@@ -221,6 +269,8 @@
*/
public void projectURIGenerated(Project project, final String uri) {
SwingUtilities.invokeLater(new Runnable() {
+
+ @SuppressWarnings("synthetic-access")
public void run() {
copyURIAction.setEnabled(true);
requestURITextField.setText(uri);
@@ -234,6 +284,7 @@
public void projectInsertProgress(Project project, final int succeeded,
final int failed, final int fatal, final int total, final boolean finalized) {
SwingUtilities.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
progressBar.setMaximum(total);
progressBar.setValue(succeeded + failed +
fatal);
@@ -265,6 +316,7 @@
}
SwingUtilities.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
public void run() {
progressBar.setValue(progressBar.getMaximum());
progressBar.setString(I18n.getMessage("jsite.insert.done"));
@@ -278,7 +330,10 @@
// ACTIONS
//
- protected void actionCopyURI() {
+ /**
+ * Copies the request URI of the project to the clipboard.
+ */
+ private void actionCopyURI() {
Clipboard clipboard =
Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new
StringSelection(requestURITextField.getText()), this);
}
@@ -291,6 +346,7 @@
* {@inheritDoc}
*/
public void lostOwnership(Clipboard clipboard, Transferable contents) {
+ /* ignore. */
}
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectPage.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectPage.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/gui/ProjectPage.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -68,31 +68,69 @@
import de.todesbaum.util.swing.TWizardPage;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Wizard page that lets the user manage his projects and start inserts.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class ProjectPage extends TWizardPage implements ListSelectionListener,
DocumentListener, ClipboardOwner {
+ /** The freenet interface. */
private Freenet7Interface freenetInterface;
- protected Action projectLocalPathBrowseAction;
- protected Action projectAddAction;
- protected Action projectDeleteAction;
- protected Action projectCloneAction;
- protected Action projectCopyURIAction;
- protected Action projectGenerateKeyAction;
+ /** The ?browse? action. */
+ private Action projectLocalPathBrowseAction;
+ /** The ?add project? action. */
+ private Action projectAddAction;
+
+ /** The ?delete project? action. */
+ private Action projectDeleteAction;
+
+ /** The ?clone project? action. */
+ private Action projectCloneAction;
+
+ /** The ?copy URI? action. */
+ private Action projectCopyURIAction;
+
+ /** The ?generate key? action. */
+ private Action projectGenerateKeyAction;
+
+ /** The file chooser. */
private JFileChooser pathChooser;
+
+ /** The project list model. */
private SortedListModel projectListModel;
+
+ /** The project list scroll pane. */
private JScrollPane projectScrollPane;
+
+ /** The project list. */
private JList projectList;
+
+ /** The project name textfield. */
private JTextField projectNameTextField;
+
+ /** The project description textfield. */
private JTextField projectDescriptionTextField;
+
+ /** The local path textfield. */
private JTextField projectLocalPathTextField;
+
+ /** The public key textfield. */
private JTextField projectPublicKeyTextField;
+
+ /** The private key textfield. */
private JTextField projectPrivateKeyTextField;
+
+ /** The project path textfield. */
private JTextField projectPathTextField;
+ /**
+ * Creates a new project page.
+ *
+ * @param wizard
+ * The wizard this page belongs to
+ */
public ProjectPage(final TWizard wizard) {
super(wizard);
setLayout(new BorderLayout(12, 12));
@@ -109,7 +147,10 @@
});
}
- protected void dialogInit() {
+ /**
+ * Initializes the page.
+ */
+ private void dialogInit() {
createActions();
pathChooser = new JFileChooser();
@@ -137,20 +178,32 @@
}
/**
+ * Adds the given listener to the list of listeners.
+ *
+ * @param listener
+ * The listener to add
*/
public void addListSelectionListener(ListSelectionListener listener) {
projectList.addListSelectionListener(listener);
}
/**
+ * Removes the given listener from the list of listeners.
+ *
+ * @param listener
+ * The listener to remove
*/
public void removeListSelectionListener(ListSelectionListener listener)
{
projectList.removeListSelectionListener(listener);
}
+ /**
+ * Creates all actions.
+ */
private void createActions() {
projectLocalPathBrowseAction = new
AbstractAction(I18n.getMessage("jsite.project.action.browse")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionLocalPathBrowse();
}
@@ -161,6 +214,7 @@
projectAddAction = new
AbstractAction(I18n.getMessage("jsite.project.action.add-project")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionAdd();
}
@@ -170,6 +224,7 @@
projectDeleteAction = new
AbstractAction(I18n.getMessage("jsite.project.action.delete-project")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionDelete();
}
@@ -180,6 +235,7 @@
projectCloneAction = new
AbstractAction(I18n.getMessage("jsite.project.action.clone-project")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionClone();
}
@@ -190,6 +246,7 @@
projectCopyURIAction = new
AbstractAction(I18n.getMessage("jsite.project.action.copy-uri")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionCopyURI();
}
@@ -200,6 +257,7 @@
projectGenerateKeyAction = new
AbstractAction(I18n.getMessage("jsite.project.action.generate-new-key")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
actionGenerateNewKey();
}
@@ -229,6 +287,11 @@
});
}
+ /**
+ * Creates the information panel.
+ *
+ * @return The information panel
+ */
private JComponent createInformationPanel() {
JPanel informationPanel = new JPanel(new BorderLayout(12, 12));
@@ -340,29 +403,54 @@
return informationPanel;
}
+ /**
+ * Sets the project list.
+ *
+ * @param projects
+ * The list of projects
+ */
public void setProjects(Project[] projects) {
projectListModel.clear();
- for (Project project: projects) {
+ for (Project project : projects) {
projectListModel.add(project);
}
}
+ /**
+ * Returns the list of projects.
+ *
+ * @return The list of projects
+ */
public Project[] getProjects() {
return (Project[]) projectListModel.toArray(new
Project[projectListModel.size()]);
}
/**
+ * Sets the freenet interface to use.
+ *
* @param freenetInterface
- * The freenetInterface to set.
+ * The freenetInterface to use
*/
public void setFreenetInterface(Freenet7Interface freenetInterface) {
this.freenetInterface = freenetInterface;
}
+ /**
+ * Returns the currently selected project.
+ *
+ * @return The currently selected project
+ */
public Project getSelectedProject() {
return (Project) projectList.getSelectedValue();
}
+ /**
+ * Updates the currently selected project with changed information from
a
+ * textfield.
+ *
+ * @param documentEvent
+ * The document event to process
+ */
private void setTextField(DocumentEvent documentEvent) {
Document document = documentEvent.getDocument();
String propertyName = (String) document.getProperty("name");
@@ -387,6 +475,7 @@
project.setPath(text);
}
} catch (BadLocationException e) {
+ /* ignore. */
}
}
@@ -394,7 +483,10 @@
// ACTIONS
//
- protected void actionLocalPathBrowse() {
+ /**
+ * Lets the user choose a local path for a project.
+ */
+ private void actionLocalPathBrowse() {
Project project = (Project) projectList.getSelectedValue();
if (project == null) {
return;
@@ -405,7 +497,10 @@
}
}
- protected void actionAdd() {
+ /**
+ * Adds a new project.
+ */
+ private void actionAdd() {
String[] keyPair = null;
if (!freenetInterface.hasNode()) {
JOptionPane.showMessageDialog(this,
I18n.getMessage("jsite.project-files.no-node-selected"), null,
JOptionPane.ERROR_MESSAGE);
@@ -428,7 +523,10 @@
projectList.setSelectedIndex(projectListModel.size() - 1);
}
- protected void actionDelete() {
+ /**
+ * Deletes the currently selected project.
+ */
+ private void actionDelete() {
int selectedIndex = projectList.getSelectedIndex();
if (selectedIndex > -1) {
if (JOptionPane.showConfirmDialog(this,
MessageFormat.format(I18n.getMessage("jsite.project.action.delete-project.confirm"),
((Project) projectList.getSelectedValue()).getName()), null,
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) ==
JOptionPane.OK_OPTION) {
@@ -441,7 +539,10 @@
}
}
- protected void actionClone() {
+ /**
+ * Clones the currently selected project.
+ */
+ private void actionClone() {
int selectedIndex = projectList.getSelectedIndex();
if (selectedIndex > -1) {
Project newProject = new Project((Project)
projectList.getSelectedValue());
@@ -451,7 +552,11 @@
}
}
- protected void actionCopyURI() {
+ /**
+ * Copies the request URI of the currently selected project to the
+ * clipboard.
+ */
+ private void actionCopyURI() {
int selectedIndex = projectList.getSelectedIndex();
if (selectedIndex > -1) {
Project selectedProject = (Project)
projectList.getSelectedValue();
@@ -460,7 +565,10 @@
}
}
- protected void actionGenerateNewKey() {
+ /**
+ * Generates a new key for the currently selected project.
+ */
+ private void actionGenerateNewKey() {
if (JOptionPane.showConfirmDialog(this,
I18n.getMessage("jsite.project.warning.generate-new-key"), null,
JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
return;
}
@@ -556,6 +664,7 @@
* {@inheritDoc}
*/
public void lostOwnership(Clipboard clipboard, Transferable contents) {
+ /* ignore. */
}
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18n.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18n.java 2008-06-22
20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18n.java 2008-06-22
23:52:45 UTC (rev 20627)
@@ -24,14 +24,23 @@
import java.util.ResourceBundle;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Maps i18n keys to translated texts, depending on a current locale.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class I18n {
+ /** The default locale, English. */
private static Locale defaultLocale = new Locale("en");
+
+ /** The current locale. */
private static Locale currentLocale;
+ /**
+ * Returns the currently set locale.
+ *
+ * @return The current locale
+ */
public static Locale getLocale() {
if (currentLocale == null) {
currentLocale = Locale.getDefault();
@@ -39,19 +48,47 @@
return currentLocale;
}
+ /**
+ * Sets the current locale.
+ *
+ * @param locale
+ * The new current locale
+ */
public static void setLocale(Locale locale) {
currentLocale = locale;
Locale.setDefault(locale);
}
+ /**
+ * Returns the resource bundle for the current locale.
+ *
+ * @return The resource bundle for the current locale
+ */
public static ResourceBundle getResourceBundle() {
return getResourceBundle(getLocale());
}
+ /**
+ * Returns the resource bundle for the given locale.
+ *
+ * @param locale
+ * The locale to get the resource bundle for
+ * @return The resource bundle for the given locale
+ */
public static ResourceBundle getResourceBundle(Locale locale) {
return
ResourceBundle.getBundle("de.todesbaum.jsite.i18n.jSite", locale);
}
+ /**
+ * Retrieves a translated text for the given i18n key. If the resource
+ * bundle for the current locale does not have a translation for the
given
+ * key, the default locale is tried. If that fails, the key is returned.
+ *
+ * @param key
+ * The key to get the translation for
+ * @return The translated value, or the key itself if not translation
can be
+ * found
+ */
public static String getMessage(String key) {
try {
return getResourceBundle().getString(key);
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18nContainer.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18nContainer.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/i18n/I18nContainer.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -24,27 +24,62 @@
import java.util.List;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Container that collects {@link Runnable}s that change the texts of GUI
+ * components when the current locale has changed.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class I18nContainer implements Iterable<Runnable> {
+ /** The container singleton. */
private static final I18nContainer singleton = new I18nContainer();
+
+ /** The list of runnables that change texts. */
private final List<Runnable> i18nRunnables =
Collections.synchronizedList(new ArrayList<Runnable>());
+
+ /**
+ * The list of runnables that change texts and run after
+ * {@link #i18nRunnables}.
+ */
private final List<Runnable> i18nPostRunnables =
Collections.synchronizedList(new ArrayList<Runnable>());
+ /**
+ * Returns the singleton instance.
+ *
+ * @return The singleton instance
+ */
public static I18nContainer getInstance() {
return singleton;
}
+ /**
+ * Registers an i18n runnable that is run when the current locale has
+ * changed.
+ *
+ * @param i18nRunnable
+ * The runnable to register
+ */
public void registerRunnable(Runnable i18nRunnable) {
i18nRunnables.add(i18nRunnable);
}
+ /**
+ * Registers a {@link Runnable} that changes texts when the current
locale
+ * has changed and runs after {@link #i18nRunnables} have run.
+ *
+ * @param i18nPostRunnable
+ * The runnable to register
+ */
public void registerPostRunnable(Runnable i18nPostRunnable) {
i18nPostRunnables.add(i18nPostRunnable);
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Returns a combined list of {@link #i18nRunnables} and
+ * {@link #i18nPostRunnables}, in that order.
+ */
public Iterator<Runnable> iterator() {
List<Runnable> allRunnables = new ArrayList<Runnable>();
allRunnables.addAll(i18nRunnables);
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/main/CLI.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/main/CLI.java 2008-06-22
20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/main/CLI.java 2008-06-22
23:52:45 UTC (rev 20627)
@@ -28,20 +28,42 @@
import de.todesbaum.jsite.application.ProjectInserter;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * Command-line interface for jSite.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class CLI implements InsertListener {
+ /** Object used for synchronization. */
private Object lockObject = new Object();
+
+ /** Writer for the console. */
private PrintWriter outputWriter = new PrintWriter(System.out, true);
+
+ /** The freenet interface. */
private Freenet7Interface freenetInterface;
+
+ /** The project inserter. */
private ProjectInserter projectInserter = new ProjectInserter();
+
+ /** The list of nodes. */
private Node[] nodes;
+
+ /** The projects. */
private Project[] projects;
+
+ /** Whether the insert has finished. */
private boolean finished = false;
+
+ /** Whether the insert finished successfully. */
private boolean success;
+ /**
+ * Creates a new command-line interface.
+ *
+ * @param args
+ * The command-line arguments
+ */
private CLI(String[] args) {
if ((args.length == 0) || args[0].equals("-h") ||
args[0].equals("--help")) {
@@ -74,7 +96,7 @@
projectInserter.setFreenetInterface(freenetInterface);
Project currentProject = null;
- for (String argument: args) {
+ for (String argument : args) {
String value = argument.substring(argument.indexOf('=')
+ 1).trim();
if (argument.startsWith("--node=")) {
Node newNode = getNode(value);
@@ -133,8 +155,15 @@
configuration.save();
}
+ /**
+ * Returns the project with the given name.
+ *
+ * @param name
+ * The name of the project
+ * @return The project, or <code>null</code> if no project could be
found
+ */
private Project getProject(String name) {
- for (Project project: projects) {
+ for (Project project : projects) {
if (project.getName().equals(name)) {
return project;
}
@@ -142,8 +171,15 @@
return null;
}
+ /**
+ * Returns the node with the given name.
+ *
+ * @param name
+ * The name of the node
+ * @return The node, or <code>null</code> if no node could be found
+ */
private Node getNode(String name) {
- for (Node node: nodes) {
+ for (Node node : nodes) {
if (node.getName().equals(name)) {
return node;
}
@@ -151,6 +187,14 @@
return null;
}
+ /**
+ * Inserts the given project.
+ *
+ * @param currentProject
+ * The project to insert
+ * @return <code>true</code> if the insert finished successfully,
+ * <code>false</code> otherwise
+ */
private boolean insertProject(Project currentProject) {
if (!freenetInterface.hasNode()) {
outputWriter.println("Node is not running!");
@@ -163,6 +207,7 @@
try {
lockObject.wait();
} catch (InterruptedException e) {
+ /* ignore, we're in a loop. */
}
}
}
@@ -180,6 +225,9 @@
outputWriter.println("Starting Insert of project \"" +
project.getName() + "\".");
}
+ /**
+ * {@inheritDoc}
+ */
public void projectURIGenerated(Project project, String uri) {
outputWriter.println("URI: " + uri);
}
@@ -207,6 +255,12 @@
// MAIN
//
+ /**
+ * Creates a new command-line interface with the given arguments.
+ *
+ * @param args
+ * The command-line arguments
+ */
public static void main(String[] args) {
new CLI(args);
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/main/Configuration.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/main/Configuration.java
2008-06-22 20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/main/Configuration.java
2008-06-22 23:52:45 UTC (rev 20627)
@@ -37,39 +37,77 @@
import de.todesbaum.jsite.application.FileOption;
import de.todesbaum.jsite.application.Node;
import de.todesbaum.jsite.application.Project;
+import de.todesbaum.util.io.Closer;
import de.todesbaum.util.io.StreamCopier;
import de.todesbaum.util.xml.SimpleXML;
import de.todesbaum.util.xml.XML;
/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
+ * The configuration.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Configuration {
+ /** The name of the file the configuration is stored to. */
private String filename;
+
+ /** The name of the lock file. */
private String lockFilename;
+
+ /** The root node of the configuration. */
private SimpleXML rootNode;
+ /**
+ * Creates a new configuration with the default name of the
configuration
+ * file.
+ */
public Configuration() {
this(System.getProperty("user.home") + "/.jSite/config7");
}
-
+
+ /**
+ * Creates a new configuration that is read from the given file.
+ *
+ * @param filename
+ * The name of the configuration file
+ */
public Configuration(String filename) {
this(filename, filename + ".lock");
}
-
+
+ /**
+ * Creates a new configuration that is read from the given file and
uses the
+ * given lock file.
+ *
+ * @param filename
+ * The name of the configuration file
+ * @param lockFilename
+ * The name of the lock file
+ */
public Configuration(String filename, String lockFilename) {
this.filename = filename;
this.lockFilename = lockFilename;
readConfiguration();
}
-
+
+ /**
+ * Creates the directory of the configuration file.
+ *
+ * @return <code>true</code> if the directory exists, or if it could be
+ * created, <code>false</code> otherwise
+ */
private boolean createConfigDirectory() {
File configDirectory = new
File(filename).getAbsoluteFile().getParentFile();
return (configDirectory.exists() &&
configDirectory.isDirectory()) || configDirectory.mkdirs();
}
+ /**
+ * Creates the lock file.
+ *
+ * @return <code>true</code> if the lock file did not already exist and
+ * could be created, <code>false</code> otherwise
+ */
public boolean createLockFile() {
if (!createConfigDirectory()) {
return false;
@@ -79,10 +117,14 @@
try {
return lockFile.createNewFile();
} catch (IOException e) {
+ /* ignore. */
}
return false;
}
+ /**
+ * Reads the configuration from the file.
+ */
private void readConfiguration() {
File configurationFile = new File(filename);
if (configurationFile.exists()) {
@@ -97,25 +139,23 @@
rootNode =
SimpleXML.fromDocument(XML.transformToDocument(fileBytes));
return;
} catch (FileNotFoundException e) {
+ /* ignore. */
} catch (IOException e) {
+ /* ignore. */
} finally {
- if (fileInputStream != null) {
- try {
- fileInputStream.close();
- } catch (IOException ioe1) {
- }
- }
- if (fileByteOutputStream != null) {
- try {
- fileByteOutputStream.close();
- } catch (IOException ioe1) {
- }
- }
+ Closer.close(fileInputStream);
+ Closer.close(fileByteOutputStream);
}
}
rootNode = new SimpleXML("configuration");
}
+ /**
+ * Saves the configuration.
+ *
+ * @return <code>true</code> if the configuration could be saved,
+ * <code>false</code> otherwise
+ */
public boolean save() {
File configurationFile = new File(filename);
if (!configurationFile.exists()) {
@@ -133,23 +173,24 @@
StreamCopier.copy(configurationInputStream,
fileOutputStream, configurationBytes.length);
return true;
} catch (IOException ioe1) {
+ /* ignore. */
} finally {
- if (configurationInputStream != null) {
- try {
- configurationInputStream.close();
- } catch (IOException ioe1) {
- }
- }
- if (fileOutputStream != null) {
- try {
- fileOutputStream.close();
- } catch (IOException ioe1) {
- }
- }
+ Closer.close(configurationInputStream);
+ Closer.close(fileOutputStream);
}
return false;
}
+ /**
+ * Returns the value of a node.
+ *
+ * @param nodeNames
+ * The name of all nodes in the chain
+ * @param defaultValue
+ * The default value to return if the node could not be found
+ * @return The value of the node, or the default value if the node
could not
+ * be found
+ */
private String getNodeValue(String[] nodeNames, String defaultValue) {
SimpleXML node = rootNode;
int nodeIndex = 0;
@@ -162,14 +203,35 @@
return node.getValue();
}
+ /**
+ * Returns the integer value of a node.
+ *
+ * @param nodeNames
+ * The names of all nodes in the chain
+ * @param defaultValue
+ * The default value to return if the node can not be found
+ * @return The parsed integer value, or the default value if the node
can
+ * not be found or the value can not be parsed into an integer
+ */
private int getNodeIntValue(String[] nodeNames, int defaultValue) {
try {
return Integer.parseInt(getNodeValue(nodeNames,
String.valueOf(defaultValue)));
} catch (NumberFormatException nfe1) {
+ /* ignore. */
}
return defaultValue;
}
+ /**
+ * Returns the boolean value of a node.
+ *
+ * @param nodeNames
+ * The names of all nodes in the chain
+ * @param defaultValue
+ * The default value to return if the node can not be found
+ * @return The parsed boolean value, or the default value if the node
can
+ * not be found
+ */
private boolean getNodeBooleanValue(String[] nodeNames, boolean
defaultValue) {
String nodeValue = getNodeValue(nodeNames, null);
if (nodeValue == null) {
@@ -180,6 +242,7 @@
/**
* Returns the hostname of the node.
+ *
* @return The hostname of the node
* @deprecated Use {@link #getSelectedNode()} instead
*/
@@ -190,7 +253,9 @@
/**
* Sets the hostname of the node.
- * @param nodeAddress The hostname of the node
+ *
+ * @param nodeAddress
+ * The hostname of the node
* @deprecated Use {@link #setSelectedNode(Node)} instead
*/
@Deprecated
@@ -200,8 +265,9 @@
/**
* The port number of the node
+ *
* @return The port number of the node
- * @deprecated Use {@link #getSelectedNode()} instead.
+ * @deprecated Use {@link #getSelectedNode()} instead.
*/
@Deprecated
public int getNodePort() {
@@ -210,7 +276,9 @@
/**
* Sets the port number of the node.
- * @param nodePort The port number of the node
+ *
+ * @param nodePort
+ * The port number of the node
* @deprecated Use {@link #setSelectedNode(Node)} instead
*/
@Deprecated
@@ -218,20 +286,38 @@
rootNode.replace("node-port", String.valueOf(nodePort));
}
+ /**
+ * Returns whether the node configuration page should be skipped on
startup.
+ *
+ * @return <code>true</code> to skip the node configuration page on
+ * startup, <code>false</code> to show it
+ */
public boolean isSkipNodePage() {
return getNodeBooleanValue(new String[] { "skip-node-page" },
false);
}
+ /**
+ * Sets whether the node configuration page should be skipped on
startup.
+ *
+ * @param skipNodePage
+ * <code>true</code> to skip the node configuration page on
+ * startup, <code>false</code> to show it
+ */
public void setSkipNodePage(boolean skipNodePage) {
rootNode.replace("skip-node-page",
String.valueOf(skipNodePage));
}
+ /**
+ * Returns all configured projects.
+ *
+ * @return A list of all projects
+ */
public Project[] getProjects() {
List<Project> projects = new ArrayList<Project>();
SimpleXML projectsNode = rootNode.getNode("project-list");
if (projectsNode != null) {
SimpleXML[] projectNodes =
projectsNode.getNodes("project");
- for (SimpleXML projectNode: projectNodes) {
+ for (SimpleXML projectNode : projectNodes) {
try {
Project project = new Project();
projects.add(project);
@@ -251,7 +337,7 @@
Map<String, FileOption> fileOptions =
new HashMap<String, FileOption>();
if (fileOptionsNode != null) {
SimpleXML[] fileOptionNodes =
fileOptionsNode.getNodes("file-option");
- for (SimpleXML fileOptionNode:
fileOptionNodes) {
+ for (SimpleXML fileOptionNode :
fileOptionNodes) {
String filename =
fileOptionNode.getNode("filename").getValue();
FileOption fileOption =
project.getFileOption(filename);
fileOption.setInsert(Boolean.parseBoolean(fileOptionNode.getNode("insert").getValue()));
@@ -274,9 +360,15 @@
return projects.toArray(new Project[projects.size()]);
}
+ /**
+ * Sets the list of all projects.
+ *
+ * @param projects
+ * The list of all projects
+ */
public void setProjects(Project[] projects) {
SimpleXML projectsNode = new SimpleXML("project-list");
- for (Project project: projects) {
+ for (Project project : projects) {
SimpleXML projectNode = projectsNode.append("project");
projectNode.append("edition",
String.valueOf(project.getEdition()));
projectNode.append("description",
project.getDescription());
@@ -307,6 +399,11 @@
rootNode.replace(projectsNode);
}
+ /**
+ * Returns the stored locale.
+ *
+ * @return The stored locale
+ */
public Locale getLocale() {
String language = getNodeValue(new String[] { "i18n",
"language" }, "en");
String country = getNodeValue(new String[] { "i18n", "country"
}, null);
@@ -316,6 +413,12 @@
return new Locale(language);
}
+ /**
+ * Sets the locale to store.
+ *
+ * @param locale
+ * The locale to store
+ */
public void setLocale(Locale locale) {
SimpleXML i18nNode = new SimpleXML("i18n");
if (locale.getCountry().length() != 0) {
@@ -325,7 +428,12 @@
rootNode.replace(i18nNode);
return;
}
-
+
+ /**
+ * Returns a list of configured nodes.
+ *
+ * @return The list of the configured nodes
+ */
public Node[] getNodes() {
SimpleXML nodesNode = rootNode.getNode("nodes");
if (nodesNode == null) {
@@ -340,7 +448,7 @@
SimpleXML[] nodeNodes = nodesNode.getNodes("node");
Node[] returnNodes = new Node[nodeNodes.length];
int nodeIndex = 0;
- for (SimpleXML nodeNode: nodeNodes) {
+ for (SimpleXML nodeNode : nodeNodes) {
String name = nodeNode.getNode("name").getValue();
String hostname =
nodeNode.getNode("hostname").getValue();
int port =
Integer.parseInt(nodeNode.getNode("port").getValue());
@@ -349,10 +457,16 @@
}
return returnNodes;
}
-
+
+ /**
+ * Sets the list of configured nodes.
+ *
+ * @param nodes
+ * The list of configured nodes
+ */
public void setNodes(Node[] nodes) {
SimpleXML nodesNode = new SimpleXML("nodes");
- for (Node node: nodes) {
+ for (Node node : nodes) {
SimpleXML nodeNode = nodesNode.append("node");
nodeNode.append("name", node.getName());
nodeNode.append("hostname", node.getHostname());
@@ -363,6 +477,12 @@
rootNode.remove("node-port");
}
+ /**
+ * Sets the selected node.
+ *
+ * @param selectedNode
+ * The selected node
+ */
public void setSelectedNode(Node selectedNode) {
SimpleXML selectedNodeNode = new SimpleXML("selected-node");
selectedNodeNode.append("name", selectedNode.getName());
@@ -370,7 +490,12 @@
selectedNodeNode.append("port",
String.valueOf(selectedNode.getPort()));
rootNode.replace(selectedNodeNode);
}
-
+
+ /**
+ * Returns the selected node.
+ *
+ * @return The selected node
+ */
public Node getSelectedNode() {
SimpleXML selectedNodeNode = rootNode.getNode("selected-node");
if (selectedNodeNode == null) {
@@ -387,5 +512,5 @@
int port =
Integer.valueOf(selectedNodeNode.getNode("port").getValue());
return new Node(hostname, port, name);
}
-
+
}
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/main/Main.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/main/Main.java 2008-06-22
20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/main/Main.java 2008-06-22
23:52:45 UTC (rev 20627)
@@ -60,33 +60,82 @@
import de.todesbaum.util.swing.WizardListener;
/**
- * @author <a href="mailto:droden at gmail.com">David Roden </a>
- * @version $Id$
+ * The main class that ties together everything.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Main implements ActionListener, ListSelectionListener,
WizardListener, NodeManagerListener {
+ /** Whether the debug mode is activated. */
private static boolean debug = false;
+
+ /** The configuration. */
private Configuration configuration;
+
+ /** The freenet interface. */
private Freenet7Interface freenetInterface = new Freenet7Interface();
- protected Icon jSiteIcon;
+ /** The jSite icon. */
+ private Icon jSiteIcon;
+
+ /**
+ * Enumeration for all possible pages.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
+ */
private static enum PageType {
- PAGE_NODE_MANAGER, PAGE_PROJECTS, PAGE_PROJECT_FILES,
PAGE_INSERT_PROJECT
+
+ /** The node manager page. */
+ PAGE_NODE_MANAGER,
+
+ /** The project page. */
+ PAGE_PROJECTS,
+
+ /** The project files page. */
+ PAGE_PROJECT_FILES,
+
+ /** The project insert page. */
+ PAGE_INSERT_PROJECT
+
}
+ /** The supported locales. */
private static final Locale[] SUPPORTED_LOCALES = new Locale[] {
Locale.ENGLISH, Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN, new Locale("pl")
};
- protected Map<Locale, Action> languageActions = new HashMap<Locale,
Action>();
- protected Action manageNodeAction;
- protected Action aboutAction;
- protected TWizard wizard;
- protected JMenu nodeMenu;
+
+ /** The actions that switch the language. */
+ private Map<Locale, Action> languageActions = new HashMap<Locale,
Action>();
+
+ /** The ?manage nodes? action. */
+ private Action manageNodeAction;
+
+ /** The ?about jSite? action. */
+ private Action aboutAction;
+
+ /** The wizard. */
+ private TWizard wizard;
+
+ /** The node menu. */
+ private JMenu nodeMenu;
+
+ /** The currently selected node. */
private Node selectedNode;
+
+ /** Mapping from page type to page. */
private final Map<PageType, TWizardPage> pages = new HashMap<PageType,
TWizardPage>();
+ /**
+ * Creates a new core with the default configuration file.
+ */
private Main() {
this(null);
}
+ /**
+ * Creates a new core with the given configuration from the given file.
+ *
+ * @param configFilename
+ * The name of the configuration file
+ */
private Main(String configFilename) {
if (configFilename != null) {
configuration = new Configuration(configFilename);
@@ -113,16 +162,22 @@
showPage(PageType.PAGE_PROJECTS);
}
+ /**
+ * Creates all actions.
+ */
private void createActions() {
- for (final Locale locale: SUPPORTED_LOCALES) {
+ for (final Locale locale : SUPPORTED_LOCALES) {
languageActions.put(locale, new
AbstractAction(I18n.getMessage("jsite.menu.language." + locale.getLanguage()),
IconLoader.loadIcon("/flag-" + locale.getLanguage() + ".png")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent
actionEvent) {
switchLanguage(locale);
}
});
}
manageNodeAction = new
AbstractAction(I18n.getMessage("jsite.menu.nodes.manage-nodes")) {
+
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent actionEvent) {
showPage(PageType.PAGE_NODE_MANAGER);
wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
@@ -131,12 +186,15 @@
};
aboutAction = new
AbstractAction(I18n.getMessage("jsite.menu.help.about")) {
+ @SuppressWarnings("synthetic-access")
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(wizard,
MessageFormat.format(I18n.getMessage("jsite.about.message"),
Version.getVersion()), null, JOptionPane.INFORMATION_MESSAGE, jSiteIcon);
}
};
I18nContainer.getInstance().registerRunnable(new Runnable() {
+
+ @SuppressWarnings("synthetic-access")
public void run() {
manageNodeAction.putValue(Action.NAME,
I18n.getMessage("jsite.menu.nodes.manage-nodes"));
aboutAction.putValue(Action.NAME,
I18n.getMessage("jsite.menu.help.about"));
@@ -144,12 +202,17 @@
});
}
+ /**
+ * Creates the menu bar.
+ *
+ * @return The menu bar
+ */
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
final JMenu languageMenu = new
JMenu(I18n.getMessage("jsite.menu.languages"));
menuBar.add(languageMenu);
ButtonGroup languageButtonGroup = new ButtonGroup();
- for (Locale locale: SUPPORTED_LOCALES) {
+ for (Locale locale : SUPPORTED_LOCALES) {
Action languageAction = languageActions.get(locale);
JRadioButtonMenuItem menuItem = new
JRadioButtonMenuItem(languageActions.get(locale));
if (locale.equals(Locale.getDefault())) {
@@ -174,11 +237,13 @@
helpMenu.add(aboutAction);
I18nContainer.getInstance().registerRunnable(new Runnable() {
+
+ @SuppressWarnings("synthetic-access")
public void run() {
languageMenu.setText(I18n.getMessage("jsite.menu.languages"));
nodeMenu.setText(I18n.getMessage("jsite.menu.nodes"));
helpMenu.setText(I18n.getMessage("jsite.menu.help"));
- for (Map.Entry<Locale, Action>
languageActionEntry: languageActions.entrySet()) {
+ for (Map.Entry<Locale, Action>
languageActionEntry : languageActions.entrySet()) {
languageActionEntry.getValue().putValue(Action.NAME,
I18n.getMessage("jsite.menu.language." +
languageActionEntry.getKey().getLanguage()));
}
}
@@ -187,6 +252,9 @@
return menuBar;
}
+ /**
+ * Initializes all pages.
+ */
private void initPages() {
NodeManagerPage nodeManagerPage = new NodeManagerPage(wizard);
nodeManagerPage.setName("page.node-manager");
@@ -212,13 +280,25 @@
pages.put(PageType.PAGE_INSERT_PROJECT, projectInsertPage);
}
- protected void showPage(PageType pageType) {
+ /**
+ * Shows the page with the given type.
+ *
+ * @param pageType
+ * The page type to show
+ */
+ private void showPage(PageType pageType) {
wizard.setPreviousEnabled(pageType.ordinal() > 0);
wizard.setNextEnabled(pageType.ordinal() < (pages.size() - 1));
wizard.setPage(pages.get(pageType));
wizard.setTitle(pages.get(pageType).getHeading() + " - jSite");
}
+ /**
+ * Saves the configuration.
+ *
+ * @return <code>true</code> if the configuration could be saved,
+ * <code>false</code> otherwise
+ */
private boolean saveConfiguration() {
NodeManagerPage nodeManagerPage = (NodeManagerPage)
pages.get(PageType.PAGE_NODE_MANAGER);
configuration.setNodes(nodeManagerPage.getNodes());
@@ -232,18 +312,26 @@
return configuration.save();
}
+ /**
+ * Finds a supported locale for the given locale.
+ *
+ * @param forLocale
+ * The locale to find a supported locale for
+ * @return The supported locale that was found, or the default locale
if no
+ * supported locale could be found
+ */
private Locale findSupportedLocale(Locale forLocale) {
- for (Locale locale: SUPPORTED_LOCALES) {
+ for (Locale locale : SUPPORTED_LOCALES) {
if (locale.equals(forLocale)) {
return locale;
}
}
- for (Locale locale: SUPPORTED_LOCALES) {
+ for (Locale locale : SUPPORTED_LOCALES) {
if (locale.getCountry().equals(forLocale.getCountry())
&& locale.getLanguage().equals(forLocale.getLanguage())) {
return locale;
}
}
- for (Locale locale: SUPPORTED_LOCALES) {
+ for (Locale locale : SUPPORTED_LOCALES) {
if
(locale.getLanguage().equals(forLocale.getLanguage())) {
return locale;
}
@@ -255,13 +343,19 @@
// ACTIONS
//
- protected void switchLanguage(Locale locale) {
+ /**
+ * Switches the language of the interface to the given locale.
+ *
+ * @param locale
+ * The locale to switch to
+ */
+ private void switchLanguage(Locale locale) {
Locale supportedLocale = findSupportedLocale(locale);
Action languageAction = languageActions.get(supportedLocale);
JRadioButtonMenuItem menuItem = (JRadioButtonMenuItem)
languageAction.getValue("menuItem");
menuItem.setSelected(true);
I18n.setLocale(supportedLocale);
- for (Runnable i18nRunnable: I18nContainer.getInstance()) {
+ for (Runnable i18nRunnable : I18nContainer.getInstance()) {
try {
i18nRunnable.run();
} catch (Throwable t) {
@@ -342,7 +436,7 @@
}
Map<String, FileOption> fileOptions =
project.getFileOptions();
Set<Entry<String, FileOption>> fileOptionEntries =
fileOptions.entrySet();
- for (Entry<String, FileOption> fileOptionEntry:
fileOptionEntries) {
+ for (Entry<String, FileOption> fileOptionEntry :
fileOptionEntries) {
FileOption fileOption =
fileOptionEntry.getValue();
if (!fileOption.isInsert() &&
((fileOption.getCustomKey().length() == 0) ||
"CHK@".equals(fileOption.getCustomKey()))) {
JOptionPane.showMessageDialog(wizard,
MessageFormat.format(I18n.getMessage("jsite.project-files.no-custom-key"),
fileOptionEntry.getKey()), null, JOptionPane.ERROR_MESSAGE);
@@ -353,6 +447,7 @@
try {
nodeRunning = freenetInterface.isNodePresent();
} catch (IOException e) {
+ /* ignore. */
}
if (!nodeRunning) {
JOptionPane.showMessageDialog(wizard,
I18n.getMessage("jsite.project-files.no-node-running"), null,
JOptionPane.ERROR_MESSAGE);
@@ -407,7 +502,7 @@
nodeMenu.removeAll();
ButtonGroup nodeButtonGroup = new ButtonGroup();
Node newSelectedNode = null;
- for (Node node: nodes) {
+ for (Node node : nodes) {
JRadioButtonMenuItem nodeMenuItem = new
JRadioButtonMenuItem(node.getName());
nodeMenuItem.putClientProperty("Node", node);
nodeMenuItem.addActionListener(this);
@@ -440,10 +535,17 @@
//
// MAIN METHOD
//
+
+ /**
+ * Main method that is called by the VM.
+ *
+ * @param args
+ * The command-line arguments
+ */
public static void main(String[] args) {
String configFilename = null;
boolean nextIsConfigFilename = false;
- for (String argument: args) {
+ for (String argument : args) {
if (nextIsConfigFilename) {
configFilename = argument;
nextIsConfigFilename = false;
@@ -464,6 +566,9 @@
new Main(configFilename);
}
+ /**
+ * Prints a small syntax help.
+ */
private static void printHelp() {
System.out.println("--help\tshows this cruft");
System.out.println("--debug\tenables some debug output");
Modified: trunk/apps/jSite/src/de/todesbaum/jsite/main/Version.java
===================================================================
--- trunk/apps/jSite/src/de/todesbaum/jsite/main/Version.java 2008-06-22
20:49:33 UTC (rev 20626)
+++ trunk/apps/jSite/src/de/todesbaum/jsite/main/Version.java 2008-06-22
23:52:45 UTC (rev 20627)
@@ -20,13 +20,20 @@
package de.todesbaum.jsite.main;
/**
- * @author <a href="mailto:droden at gmail.com">David Roden </a>
- * @version $Id$
+ * Container for version information.
+ *
+ * @author David ?Bombe? Roden <bombe at freenetproject.org>
*/
public class Version {
- private static final String VERSION = "0.4.12";
+ /** The version. */
+ private static final String VERSION = "0.4.12.2";
+ /**
+ * Returns the version.
+ *
+ * @return The version
+ */
public static final String getVersion() {
return VERSION;
}