mLogFiles = new TreeMap<>();
+ private final boolean stackTrace = true;// FIXME "true".equals(getProp(PropertiesKey.STACKTRACE));
+
+ protected PluginBase(String strPath, String strTitle, String strPropFilename) {
try {
-
this.strPath = strPath;
this.strTitle = strTitle;
this.strPropFilename = strPropFilename;
-
+
// prepare and clear log file
(new File(strPath)).mkdir();
initLog("log.txt");
- dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm_ss");
+
dateFormat.setTimeZone(TimeZone.getDefault());
-
+
// load properties
loadProp();
- if (getProp("loglevel") == null) {
- setIntProp("loglevel", 0);
+ if (getProp(PropertiesKey.LOGLEVEL) == null) {
+ setIntProp(PropertiesKey.LOGLEVEL, 0);
}
-
- } catch (Exception e) {
- log("PluginBase(): " + e.getMessage(), 1);
+
+ } catch (final Exception e) {
+ log("PluginBase(): " + e.getMessage(), e);
}
}
-
+
String getCategory() {
- return strTitle.replaceAll(" ", "_");
+ return strTitle.replace(' ', '_');
}
-
+
String getPath() {
return "/" + strPath;
}
-
+
public String getPluginDirectory() {
return strPath + "/";
}
-
+
@Override
public void runPlugin(PluginRespirator pr) { // FredPlugin
try {
-
log(getVersion() + " started");
-
+
// init plugin context
pagemaker = pr.getPageMaker();
pluginContext = new PluginContext(pr);
webInterface = new WebInterface(pluginContext);
-
+
// fcp connection
connectFcp();
-
+
// add menu
pagemaker.removeNavigationCategory(getCategory());
if (strMenuTitle != null) {
webInterface.addNavigationCategory(getPath() + "/", getCategory(), strMenuTooltip, this);
}
-
- } catch (Exception e) {
+ } catch (final Exception e) {
log("PluginBase.runPlugin(): " + e.getMessage(), 1);
}
}
-
+
@Override
public String getVersion() { // FredPluginVersioned
- return strTitle + " " + strVersion;
+ return strVersion;
}
-
+
/**
*
* @param strKey
@@ -138,7 +142,7 @@ public String getVersion() { // FredPluginVersioned
public String getString(String strKey) { // FredPluginL10n
return strKey;
}
-
+
/**
*
* @param language
@@ -147,11 +151,11 @@ public String getString(String strKey) { // FredPluginL10n
public void setLanguage(LANGUAGE language) { // FredPluginL10n
nodeLanguage = language;
}
-
+
@Override
public void terminate() { // FredPlugin
try {
-
+
log("plugin base terminates");
saveProp();
fcpConnection.disconnect();
@@ -160,152 +164,160 @@ public void terminate() { // FredPlugin
webInterface = null;
pagemaker.removeNavigationCategory(getCategory());
log("plugin base terminated");
- for (RandomAccessFile file : mLogFiles.values()) {
+ for (final RandomAccessFile file : mLogFiles.values()) {
file.close();
}
-
- } catch (IOException e) {
+
+ } catch (final IOException e) {
log("PluginBase.terminate(): " + e.getMessage(), 1);
}
}
-
+
@Override
public void messageReceived(Connection connection, Message message) { // ConnectionListener
try {
-
// errors
- if (message.getName().equals("ProtocolError"))
+ if ("ProtocolError".equals(message.getName())) {
log("ProtocolError: " + message.get("CodeDescription"));
- else if (message.getName().equals("IdentifierCollision"))
+ } else if ("IdentifierCollision".equals(message.getName())) {
log("IdentifierCollision");
-
- // redirect deprecated usk edition
- else if (message.getName().equals("GetFailed") &&
- (message.get("RedirectUri") != null) && !message.get("RedirectUri").equals("")) {
+ } else if ("GetFailed".equals(message.getName()) &&
+ (message.get("RedirectUri") != null) && !"".equals(message.get("RedirectUri"))) {
+ // redirect deprecated usk edition
log("USK redirected (" + message.getIdentifier() + ")");
-
+
// reg new edition
- String pageName = message.getIdentifier().split("_")[0];
- PageBase page = (PageBase) mPages.get(pageName);
+ final String pageName = message.getIdentifier().split("_")[0];
+ final PageBase page = mPages.get(pageName);
if (page != null)
page.updateRedirectUri(message);
-
+
// redirect
- FcpCommands fcpCommand = new FcpCommands(fcpConnection, null);
+ final FcpCommands fcpCommand = new FcpCommands(fcpConnection, null);
fcpCommand.setCommandName("ClientGet");
fcpCommand.field("Identifier", message.getIdentifier());
fcpCommand.field("URI", message.get("RedirectUri"));
fcpCommand.send();
- }
-
- // register message
- else {
+ } else {
+ // register message
log("fcp: " + message.getName() + " (" + message.getIdentifier() + ")");
- String pageName = message.getIdentifier().split("_")[0];
- PageBase page = (PageBase) mPages.get(pageName);
+ final String pageName = message.getIdentifier().split("_")[0];
+ final PageBase page = mPages.get(pageName);
if (page != null)
page.addMessage(message);
}
-
- } catch (Exception e) {
+
+ } catch (final Exception e) {
log("PluginBase.messageReceived(): " + e.getMessage(), 1);
}
}
-
+
@Override
public void connectionTerminated(Connection connection) { // ConnectionListener
log("fcp connection terminated");
}
-
+
private synchronized void connectFcp() {
try {
-
+
if (fcpConnection == null || !fcpConnection.isConnected()) {
fcpConnection = new Connection(new Node("localhost"), "connection_" + System.currentTimeMillis());
fcpConnection.addConnectionListener(this);
fcpConnection.connect();
}
-
- } catch (IOException e) {
+
+ } catch (final IOException e) {
log("PluginBase.connectFcp(): " + e.getMessage(), 1);
}
}
-
+
private void loadProp() {
try {
-
if (strPropFilename != null) {
prop = new Properties();
- File file = new File(strPath + "/" + strPropFilename);
- File oldFile = new File(strPath + "/" + strPropFilename + ".old");
-
- FileInputStream is;
- //always load from the backup if it exists, it is (almost?)
- //guaranteed to be good.
- if (oldFile.exists()) {
- is = new FileInputStream(oldFile);
- } else if (file.exists()) {
- is = new FileInputStream(file);
- } else {
- throw new Exception("No Prop file found.");
+ final File file = new File(strPath, strPropFilename);
+ final File oldFile = new File(strPath, strPropFilename + ".old");
+
+ FileInputStream is = null;
+ try {
+ //always load from the backup if it exists, it is (almost?)
+ //guaranteed to be good.
+ if (oldFile.exists()) {
+ is = new FileInputStream(oldFile);
+ } else if (file.exists()) {
+ is = new FileInputStream(file);
+ } else {
+ throw new Exception("No Prop file found.");
+ }
+ prop.load(is);
+ } finally {
+ if (is != null)
+ is.close();
}
- prop.load(is);
- is.close();
}
-
- } catch (Exception e) {
+ } catch (final Exception e) {
log("PluginBase.loadProp(): " + e.getMessage(), 1);
}
}
-
+
// ******************************************
// methods to use in the derived page class:
// ******************************************
// log files
private synchronized void initLog(String strFilename) {
try {
-
if (!mLogFiles.containsKey(strFilename)) {
- RandomAccessFile file = new RandomAccessFile(strPath + "/" + strFilename, "rw");
+ final RandomAccessFile file = new RandomAccessFile(strPath + "/" + strFilename, "rw");
file.seek(file.length());
mLogFiles.put(strFilename, file);
}
-
- } catch (IOException e) {
- log("PluginBase.initLog(): " + e.getMessage());
+ } catch (final IOException e) {
+ log("PluginBase.initLog() - file: %s", e, strFilename);
}
}
-
- public synchronized void log(String strFilename, String cText, int nLogLevel) {
+
+ protected synchronized void removeLogFromMap(String strFilename) {
try {
-
- if (nLogLevel <= getIntProp("loglevel")) {
+ final RandomAccessFile fileHandle = mLogFiles.get(strFilename);
+ if (fileHandle != null) {
+ fileHandle.close();
+ mLogFiles.remove(strFilename);
+ }
+ } catch (final Exception e) {
+ log("PluginBase.removeLogFromMap() - file: %s", e, strFilename);
+ }
+ }
+
+ public synchronized void logFile(String strFilename, String cText, int nLogLevel) {
+ try {
+
+ if (nLogLevel <= getIntProp(PropertiesKey.LOGLEVEL)) {
initLog(strFilename);
mLogFiles.get(strFilename).writeBytes(dateFormat.format(new Date()) + " " + cText + "\n");
}
-
- } catch (Exception e) {
- if (!strFilename.equals("log.txt")) // to avoid infinite loop when log.txt was closed on shutdown
+
+ } catch (final Exception e) {
+ if (!"log.txt".equals(strFilename)) // to avoid infinite loop when log.txt was closed on shutdown
{
- log("PluginBase.log(): " + e.getMessage());
+ log("PluginBase.log():", e);
}
}
}
-
- public void log(String strFilename, String strText) {
- log(strFilename, strText, 0);
+
+ public void logFile(String strFilename, String strText) {
+ logFile(strFilename, strText, 0);
}
-
+
public synchronized String getLog(String filename) {
try {
-
+
initLog(filename);
- RandomAccessFile file = mLogFiles.get(filename);
- int MAX_LOG_LENGTH = 2_000_000; // around 10k lines
- StringBuilder buffer = new StringBuilder();
- long fileLength = file.length();
+ final RandomAccessFile file = mLogFiles.get(filename);
+ final int MAX_LOG_LENGTH = 2_000_000; // around 10k lines
+ final StringBuilder buffer = new StringBuilder();
+ final long fileLength = file.length();
if (fileLength > MAX_LOG_LENGTH) {
- long skip = fileLength - MAX_LOG_LENGTH;
+ final long skip = fileLength - MAX_LOG_LENGTH;
file.seek(skip);
file.readLine();
buffer.append("log contains ").append(skip).append(" preceding bytes (~").append(skip / 200).append(" lines)").append("\n");
@@ -317,192 +329,256 @@ public synchronized String getLog(String filename) {
buffer.append(line).append("\n");
}
return buffer.toString();
-
- } catch (IOException e) {
+
+ } catch (final IOException e) {
log("PluginBase.getLog(): " + e.getMessage());
return null;
}
}
-
+
public void clearLog(String strFilename) {
try {
-
+
initLog(strFilename);
mLogFiles.get(strFilename).setLength(0);
-
- } catch (IOException e) {
+
+ } catch (final IOException e) {
log("PluginBase.clearLog(): " + e.getMessage());
}
}
-
+
public void clearAllLogs() {
try {
-
- for (RandomAccessFile file : mLogFiles.values()) {
+
+ for (final RandomAccessFile file : mLogFiles.values()) {
file.setLength(0);
}
-
- } catch (IOException e) {
+
+ } catch (final IOException e) {
log("PluginBase.clearAllLogs(): " + e.getMessage());
}
}
-
+
public void setLogLevel(int nLevel) throws Exception {
try {
-
- setIntProp("loglevel", nLevel);
-
- } catch (Exception e) {
- throw new Exception("PluginBase.setLogLevel(): " + e.getMessage());
+
+ setIntProp(PropertiesKey.LOGLEVEL, nLevel);
+
+ } catch (final Exception e) {
+ throw new Exception("PluginBase.setLogLevel(): " + e.getMessage(), e);
}
}
-
+
// standard log
public void log(String cText) {
- log("log.txt", cText, 0);
+ logFile("log.txt", cText, 0);
}
-
+
+ public void logF(String cText, Object... args) {
+ logFile("log.txt", String.format(cText, args), 0);
+ }
+
public void log(String cText, int nLogLevel) {
- log("log.txt", cText, nLogLevel);
+ logFile("log.txt", cText, nLogLevel);
+ }
+
+ public void log(String info, Throwable e) {
+ final StringBuilder message = new StringBuilder(String.format("%s: %s %s", info, e.getClass().getName(), e.getMessage()));
+ if (stackTrace)
+ message.append(System.lineSeparator()).append(stackTraceToString(e));
+
+ log(message.toString());
+ }
+
+ public void log(String info, Throwable e, Object... args) {
+ log(String.format(info, args), e);
+ }
+
+ private String stackTraceToString(Throwable e) {
+ try (final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw)) {
+ e.printStackTrace(pw);
+ return sw.toString();
+ } catch (final IOException e1) {
+ return String.format("Error in stackTraceToString: %s", e1.getMessage());
+ }
}
-
+
protected void clearLog() {
clearLog("log.txt");
}
-
+
public String getLog() {
return getLog("log.txt");
}
-
+
// methods to set the version of the plugin
protected void setVersion(String strVersion) {
this.strVersion = strVersion;
}
-
+
// methods to add the plugin to the nodes' main menu (fproxy)
protected void addPluginToMenu(String strMenuTitle, String strMenuTooltip) {
this.strMenuTitle = strMenuTitle;
this.strMenuTooltip = strMenuTooltip;
}
-
+
// methods to add menu items to the plugins menu (fproxy)
protected void addMenuItem(String strTitle, String strTooltip, String strUri, boolean isFullAccessHostsOnly) {
try {
-
+
pagemaker.addNavigationLink(getCategory(), strUri, strTitle, strTooltip, isFullAccessHostsOnly, null, this);
log("item '" + strTitle + "' added to menu");
-
- } catch (Exception e) {
+
+ } catch (final Exception e) {
log("PluginBase.addMenuItem(): " + e.getMessage());
}
}
-
+
// methods to build the plugin
protected void addPage(PageBase page) {
try {
-
+
mPages.put(page.getName(), page);
-
- } catch (Exception e) {
+
+ } catch (final Exception e) {
log("PluginBase.addPage(): " + e.getMessage());
}
}
-
+
// methods to set and get persistent properties
public synchronized void saveProp() {
+ if (prop == null)
+ return;
+
try {
-
- if (prop != null) {
- File file = new File(strPath + "/" + strPropFilename);
- File oldFile = new File(strPath + "/" + strPropFilename + ".old");
- File newFile = new File(strPath + "/" + strPropFilename + ".new");
-
- if (newFile.exists()) {
- newFile.delete();
- }
-
- try (FileOutputStream stream = new FileOutputStream(newFile)) {
- prop.store(stream, strTitle);
- stream.flush();
- }
-
- if (oldFile.exists()) {
- oldFile.delete();
- }
-
- if (file.exists()) {
- file.renameTo(oldFile);
- }
-
- newFile.renameTo(file);
+ final File file = new File(strPath, strPropFilename);
+ final File oldFile = new File(strPath, strPropFilename + ".old");
+ final File newFile = new File(strPath, strPropFilename + ".new");
+
+ if (newFile.exists()) {
+ Files.delete(newFile.toPath());
}
-
- } catch (IOException e) {
+
+ try (FileOutputStream stream = new FileOutputStream(newFile)) {
+ prop.store(stream, strTitle);
+ stream.flush();
+ }
+
+ if (oldFile.exists()) {
+ Files.delete(oldFile.toPath());
+ }
+
+ if (file.exists()) {
+ file.renameTo(oldFile);
+ }
+
+ newFile.renameTo(file);
+ } catch (final IOException e) {
log("PluginBase.saveProp(): " + e.getMessage());
}
}
-
- public void setProp(String strKey, String strValue) throws Exception {
- try {
-
- prop.setProperty(strKey, strValue);
-
- } catch (Exception e) {
- throw new Exception("PluginBase.setProp(): " + e.getMessage());
- }
+
+ /**
+ * {@link Properties#setProperty(String, String)}
+ * @param key
+ * @param value
+ */
+ public void setProp(PropertiesKey key, String value) {
+ if (key == null || value == null)
+ return;
+
+ prop.setProperty(key.toString(), value);
}
-
- public String getProp(String strKey) throws Exception {
- try {
-
- return prop.getProperty(strKey);
-
- } catch (Exception e) {
- throw new Exception("PluginBase.getProp(): " + e.getMessage());
- }
+
+ /**
+ * {@link Properties#getProperty(String)}
+ */
+ public String getProp(PropertiesKey key) {
+ return key != null ? prop.getProperty(key.toString()) : null;
}
-
- public void setIntProp(String strKey, int nValue) throws Exception {
- try {
-
- prop.setProperty(strKey, String.valueOf(nValue));
-
- } catch (Exception e) {
- throw new Exception("PluginBase.setIntProp(): " + e.getMessage());
- }
+
+ /**
+ * {@link Properties#getProperty(String)}
+ * @param key
+ * @param value
+ */
+ public void setIntProp(PropertiesKey key, int value) {
+ final String strValue = String.valueOf(value);
+ if (key == null || strValue == null)
+ return;
+
+ setProp(key, strValue);
+ }
+
+ /**
+ * get a value and parse it to an integer
+ * @param key
+ * @return a parsed number from the key or 0
+ */
+ public int getIntProp(PropertiesKey key) {
+ final String value = getProp(key);
+ return parseInt(value);
}
-
- public int getIntProp(String strKey) throws Exception {
- try {
-
- String strValue = getProp(strKey);
- if (strValue != null && !strValue.equals("")) {
- return Integer.parseInt(strValue);
- } else {
- return 0;
- }
-
- } catch (Exception e) {
- throw new Exception("PluginBase.getIntProp(): " + e.getMessage());
+
+ /**
+ * {@link Integer#parseInt(String)}
+ * @param value a number as string
+ * @return a parsed number from the input or 0
+ */
+ public int parseInt(String value) {
+ int result = -1;
+
+ if (value != null && !value.trim().isEmpty()) {
+ try {
+ result = Integer.parseInt(value);
+ } catch (final NumberFormatException e) {/* ignore */}
}
+
+ return result;
}
-
- protected void removeProp(String strKey) {
- try {
-
- prop.remove(strKey);
-
- } catch (Exception e) {
- log("PluginBase.removeProp(): " + e.getMessage());
- }
+
+ /**
+ * {@link Properties#remove(Object)}
+ * @param key
+ */
+ protected void removeProp(PropertiesKey key) {
+ if (key == null)
+ return;
+
+ prop.remove(key.toString());
}
-
+
+ /**
+ * {@link Properties#remove(Object)}
+ * @param key
+ */
+ protected void removeProp(String key) {
+ if (key == null)
+ return;
+
+ prop.remove(key);
+ }
+
+ /**
+ * {@link Properties#clear()}
+ */
protected void clearProp() {
prop.clear();
}
-
+
+ /**
+ * Returns the Properties
+ */
+ protected Properties getProperties() {
+ return prop;
+ }
+
+ /**
+ * set the timezone to utc
+ */
protected void setTimezoneUTC() {
- dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm_ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/ClientHello.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/ClientHello.java
index 2f97c4d..fea9ace 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/ClientHello.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/ClientHello.java
@@ -33,24 +33,24 @@
* @version $Id$
*/
public class ClientHello extends Command {
-
+
/**
* The name of the client.
*/
protected String name;
-
+
/**
* The version of the FCP protocol the client expects.
*/
private String expectedVersion = "2.0";
-
+
/**
* Creates a new ClientHello command.
*/
protected ClientHello() {
super("ClientHello", "ClientHello-" + System.currentTimeMillis());
}
-
+
/**
* Returns the value of the ExpectedVersion parameter of this
* command. At the moment this value is not used by the node but in the
@@ -61,7 +61,7 @@ protected ClientHello() {
public String getExpectedVersion() {
return expectedVersion;
}
-
+
/**
* Sets the value of the ExpectedVersion parameter of this
* command. At the moment this value is not used by the node but in the
@@ -72,7 +72,7 @@ public String getExpectedVersion() {
protected void setExpectedVersion(String expectedVersion) {
this.expectedVersion = expectedVersion;
}
-
+
/**
* Returns the name of the client that is connecting.
*
@@ -81,7 +81,7 @@ protected void setExpectedVersion(String expectedVersion) {
public String getName() {
return name;
}
-
+
/**
* Sets the name of the client that is connecting.
*
@@ -90,7 +90,7 @@ public String getName() {
public void setName(String name) {
this.name = name;
}
-
+
/**
* {@inheritDoc}
*
@@ -101,5 +101,5 @@ protected void write(Writer writer) throws IOException {
writer.write("Name=" + name + LINEFEED);
writer.write("ExpectedVersion=" + expectedVersion + LINEFEED);
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Closer.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Closer.java
index 942f494..58704e1 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Closer.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Closer.java
@@ -40,7 +40,7 @@
* @version $Id$
*/
public class Closer {
-
+
/**
* Closes the given result set.
*
@@ -51,11 +51,10 @@ public static void close(ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
- } catch (SQLException ioe1) {
- }
+ } catch (final SQLException ioe1) {}
}
}
-
+
/**
* Closes the given statement.
*
@@ -66,11 +65,10 @@ public static void close(Statement statement) {
if (statement != null) {
try {
statement.close();
- } catch (SQLException ioe1) {
- }
+ } catch (final SQLException ioe1) {}
}
}
-
+
/**
* Closes the given connection.
*
@@ -81,11 +79,10 @@ public static void close(Connection connection) {
if (connection != null) {
try {
connection.close();
- } catch (SQLException ioe1) {
- }
+ } catch (final SQLException ioe1) {}
}
}
-
+
/**
* Closes the given server socket.
*
@@ -96,11 +93,10 @@ public static void close(ServerSocket serverSocket) {
if (serverSocket != null) {
try {
serverSocket.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
/**
* Closes the given socket.
*
@@ -111,11 +107,10 @@ public static void close(Socket socket) {
if (socket != null) {
try {
socket.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
/**
* Closes the given input stream.
*
@@ -126,11 +121,10 @@ static void close(InputStream inputStream) {
if (inputStream != null) {
try {
inputStream.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
/**
* Closes the given output stream.
*
@@ -141,11 +135,10 @@ public static void close(OutputStream outputStream) {
if (outputStream != null) {
try {
outputStream.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
/**
* Closes the given reader.
*
@@ -156,11 +149,10 @@ public static void close(Reader reader) {
if (reader != null) {
try {
reader.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
/**
* Closes the given writer.
*
@@ -171,9 +163,8 @@ public static void close(Writer writer) {
if (writer != null) {
try {
writer.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Command.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Command.java
index 9e910fc..29dcbe7 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Command.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Command.java
@@ -37,24 +37,24 @@
* @version $Id$
*/
public abstract class Command {
-
+
/**
* The line feed sequence used by the library.
*/
static final String LINEFEED = "\r\n";
-
+
/**
* The name of the command. The name is sent to the node so it can not be
* chosen arbitrarily!
*/
private final String commandName;
-
+
/**
* The identifier of the command. This identifier is used to identify
* replies that are caused by a command.
*/
private final String identifier;
-
+
/**
* Creates a new command with the specified name and identifier.
*
@@ -65,7 +65,7 @@ public Command(String name, String identifier) {
this.commandName = name;
this.identifier = identifier;
}
-
+
/**
* Returns the name of this command.
*
@@ -74,7 +74,7 @@ public Command(String name, String identifier) {
public String getCommandName() {
return commandName;
}
-
+
/**
* Return the identifier of this command.
*
@@ -83,7 +83,7 @@ public String getCommandName() {
public String getIdentifier() {
return identifier;
}
-
+
/**
* Writes all parameters to the specified writer.
*
@@ -99,7 +99,7 @@ protected void write(Writer writer) throws IOException {
writer.write("Identifier=" + identifier + LINEFEED);
}
}
-
+
/**
* Returns whether this command has payload to send after the message.
* Subclasses need to return true here if they need to send
@@ -111,7 +111,7 @@ protected void write(Writer writer) throws IOException {
protected boolean hasPayload() {
return false;
}
-
+
/**
* Returns the payload of this command as an {@link InputStream}. This
* method is never called if {@link #hasPayload()} returns
@@ -122,7 +122,7 @@ protected boolean hasPayload() {
protected InputStream getPayload() {
return null;
}
-
+
/**
* Returns the length of the payload. This method is never called if
* {@link #hasPayload()} returns false.
@@ -132,5 +132,5 @@ protected InputStream getPayload() {
protected long getPayloadLength() {
return -1;
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Connection.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Connection.java
index 0679a98..d921db0 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Connection.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Connection.java
@@ -30,6 +30,8 @@
import java.util.ArrayList;
import java.util.List;
+import keepalive.Plugin;
+
/**
* A physical connection to a Freenet node.
*
@@ -37,57 +39,57 @@
* @version $Id$
*/
public class Connection {
-
+
/**
* The listeners that receive events from this connection.
*/
private final List connectionListeners = new ArrayList<>();
-
+
/**
* The node this connection is connected to.
*/
private final Node node;
-
+
/**
* The name of this connection.
*/
private final String name;
-
+
/**
* The network socket of this connection.
*/
private Socket nodeSocket;
-
+
/**
* The input stream that reads from the socket.
*/
private InputStream nodeInputStream;
-
+
/**
* The output stream that writes to the socket.
*/
private OutputStream nodeOutputStream;
-
+
/**
* The thread that reads from the socket.
*/
private NodeReader nodeReader;
-
+
/**
* A writer for the output stream.
*/
private Writer nodeWriter;
-
+
/**
* The NodeHello message sent by the node on connect.
*/
protected Message nodeHello;
-
+
/**
* The temp directory to use.
*/
private String tempDirectory;
-
+
/**
* Creates a new connection to the specified node with the specified name.
*
@@ -98,7 +100,7 @@ public Connection(Node node, String name) {
this.node = node;
this.name = name;
}
-
+
/**
* Adds a listener that gets notified on connection events.
*
@@ -107,7 +109,7 @@ public Connection(Node node, String name) {
public void addConnectionListener(ConnectionListener connectionListener) {
connectionListeners.add(connectionListener);
}
-
+
/**
* Removes a listener from the list of registered listeners. Only the first
* matching listener is removed.
@@ -118,27 +120,27 @@ public void addConnectionListener(ConnectionListener connectionListener) {
public void removeConnectionListener(ConnectionListener connectionListener) {
connectionListeners.remove(connectionListener);
}
-
+
/**
* Notifies listeners about a received message.
*
* @param message The received message
*/
protected void fireMessageReceived(Message message) {
- for (ConnectionListener connectionListener : connectionListeners) {
+ for (final ConnectionListener connectionListener : connectionListeners) {
connectionListener.messageReceived(this, message);
}
}
-
+
/**
* Notifies listeners about the loss of the connection.
*/
protected void fireConnectionTerminated() {
- for (ConnectionListener connectionListener : connectionListeners) {
+ for (final ConnectionListener connectionListener : connectionListeners) {
connectionListener.connectionTerminated(this);
}
}
-
+
/**
* Returns the name of the connection.
*
@@ -147,7 +149,7 @@ protected void fireConnectionTerminated() {
public String getName() {
return name;
}
-
+
/**
* Sets the temp directory to use for creation of temporary files.
*
@@ -157,7 +159,7 @@ public String getName() {
public void setTempDirectory(String tempDirectory) {
this.tempDirectory = tempDirectory;
}
-
+
/**
* Connects to the node.
*
@@ -179,27 +181,26 @@ public synchronized boolean connect() throws IOException {
nodeOutputStream = nodeSocket.getOutputStream();
nodeWriter = new OutputStreamWriter(nodeOutputStream, Charset.forName("UTF-8"));
nodeReader = new NodeReader(nodeInputStream);
- Thread nodeReaderThread = new Thread(nodeReader);
+ final Thread nodeReaderThread = new Thread(nodeReader);
nodeReaderThread.setDaemon(true);
- nodeReaderThread.setName("KeepAlive FCP Thread");
+ nodeReaderThread.setName(Plugin.PLUGIN_NAME + " FCP Thread");
nodeReaderThread.start();
- ClientHello clientHello = new ClientHello();
+ final ClientHello clientHello = new ClientHello();
clientHello.setName(name);
clientHello.setExpectedVersion("2.0");
execute(clientHello);
synchronized (this) {
try {
wait(10000);
- } catch (InterruptedException e) {
- }
+ } catch (final InterruptedException e) {}
}
return nodeHello != null;
- } catch (IOException ioe1) {
+ } catch (final IOException ioe1) {
disconnect();
throw ioe1;
}
}
-
+
/**
* Returns whether this connection is still connected to the node.
*
@@ -209,7 +210,7 @@ public synchronized boolean connect() throws IOException {
public boolean isConnected() {
return (nodeHello != null) && (nodeSocket != null) && (nodeSocket.isConnected());
}
-
+
/**
* Returns the NodeHello message the node sent on connection.
*
@@ -218,7 +219,7 @@ public boolean isConnected() {
public Message getNodeHello() {
return nodeHello;
}
-
+
/**
* Disconnects from the node.
*/
@@ -226,29 +227,25 @@ public void disconnect() {
if (nodeWriter != null) {
try {
nodeWriter.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
nodeWriter = null;
}
if (nodeOutputStream != null) {
try {
nodeOutputStream.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
nodeOutputStream = null;
}
if (nodeInputStream != null) {
try {
nodeInputStream.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
nodeInputStream = null;
}
if (nodeSocket != null) {
try {
nodeSocket.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
nodeSocket = null;
}
synchronized (this) {
@@ -256,7 +253,7 @@ public void disconnect() {
}
fireConnectionTerminated();
}
-
+
/**
* Executes the specified command.
*
@@ -283,7 +280,7 @@ public synchronized void execute(Command command) throws IllegalStateException,
nodeOutputStream.flush();
}
}
-
+
/**
* The reader thread for this connection. This is essentially a thread that
* reads lines from the node, creates messages from them and notifies
@@ -293,13 +290,13 @@ public synchronized void execute(Command command) throws IllegalStateException,
* @version $Id$
*/
protected class NodeReader implements Runnable { // changed by jeriadoc 11/2011: private -> protected
-
+
/**
* The input stream to read from.
*/
@SuppressWarnings("hiding")
private final InputStream nodeInputStream;
-
+
/**
* Creates a new reader that reads from the specified input stream.
*
@@ -308,7 +305,7 @@ protected class NodeReader implements Runnable { // changed by jeriadoc 1
public NodeReader(InputStream nodeInputStream) {
this.nodeInputStream = nodeInputStream;
}
-
+
/**
* Main loop of the reader. Lines are read and converted into
* {@link Message} objects.
@@ -337,16 +334,16 @@ public void run() {
tempFile = File.createTempFile("fcpv2", "data", (tempDirectory != null) ? new File(tempDirectory) : null);
tempFile.deleteOnExit();
try (FileOutputStream tempFileOutputStream = new FileOutputStream(tempFile)) {
- long dataLength = Long.parseLong(message.get("DataLength"));
+ final long dataLength = Long.parseLong(message.get("DataLength"));
StreamCopier.copy(nodeInputStream, tempFileOutputStream, dataLength);
}
message.setPayloadInputStream(new TempFileInputStream(tempFile));
- } catch (IOException ioe1) {
+ } catch (final IOException ioe1) {
ioe1.printStackTrace();
}
}
if ("Data".equals(line) || "EndMessage".equals(line)) {
- if (message.getName().equals("NodeHello")) {
+ if ("NodeHello".equals(message.getName())) {
nodeHello = message;
synchronized (Connection.this) {
Connection.this.notify();
@@ -357,11 +354,11 @@ public void run() {
message = null;
continue;
}
- int equalsPosition = line.indexOf('=');
+ final int equalsPosition = line.indexOf('=');
if (equalsPosition > -1) {
- String key = line.substring(0, equalsPosition).trim();
- String value = line.substring(equalsPosition + 1).trim();
- if (key.equals("Identifier")) {
+ final String key = line.substring(0, equalsPosition).trim();
+ final String value = line.substring(equalsPosition + 1).trim();
+ if ("Identifier".equals(key)) {
message.setIdentifier(value);
} else {
message.put(key, value);
@@ -375,25 +372,23 @@ public void run() {
/* if we got here, some error occured! */
throw new IOException("Unexpected line: " + line);
}
- } catch (IOException ioe1) {
+ } catch (final IOException ioe1) {
// ioe1.printStackTrace();
} finally {
if (nodeReader != null) {
try {
nodeReader.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
if (nodeInputStream != null) {
try {
nodeInputStream.close();
- } catch (IOException ioe1) {
- }
+ } catch (final IOException ioe1) {}
}
}
Connection.this.disconnect();
}
-
+
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/ConnectionListener.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/ConnectionListener.java
index 0dcc9df..5a9e4ac 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/ConnectionListener.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/ConnectionListener.java
@@ -27,7 +27,7 @@
* @version $Id$
*/
public interface ConnectionListener extends EventListener {
-
+
/**
* Notifies a client that a message was received.
*
@@ -35,12 +35,12 @@ public interface ConnectionListener extends EventListener {
* @param message The message that was received
*/
void messageReceived(Connection connection, Message message);
-
+
/**
* Notifies a client that the connection to the node has been lost.
*
* @param connection The connection that was lost
*/
void connectionTerminated(Connection connection);
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/LineInputStream.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/LineInputStream.java
index 09c3e80..3694e55 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/LineInputStream.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/LineInputStream.java
@@ -29,17 +29,17 @@
* @version $Id$
*/
public class LineInputStream extends FilterInputStream {
-
+
private boolean skipLinefeed;
private final StringBuffer lineBuffer = new StringBuffer();
-
+
/**
* @param in
*/
public LineInputStream(InputStream in) {
super(in);
}
-
+
public synchronized String readLine() {
try {
lineBuffer.setLength(0);
@@ -61,9 +61,9 @@ public synchronized String readLine() {
}
}
return lineBuffer.toString();
- } catch (IOException e) {
+ } catch (final IOException e) {
return null;
}
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Message.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Message.java
index 495962f..898a7aa 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Message.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Message.java
@@ -21,8 +21,8 @@
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
/**
* Contains replies sent by the Freenet node. A message always has a name, and
@@ -35,27 +35,27 @@
* @see de.todesbaum.util.freenet.fcp2.Client
*/
public class Message {
-
+
/**
* The name of this message.
*/
private final String name;
-
+
/**
* The identifier of this message.
*/
private String identifier = "";
-
+
/**
* The parameters of this message.
*/
private final Map parameters = new HashMap<>();
-
+
/**
* The payload.
*/
private InputStream payloadInputStream;
-
+
/**
* Creates a new message with the specified name.
*
@@ -64,7 +64,7 @@ public class Message {
public Message(String name) {
this.name = name;
}
-
+
/**
* Returns the identifier of this message.
*
@@ -73,7 +73,7 @@ public Message(String name) {
public String getIdentifier() {
return identifier;
}
-
+
/**
* Sets the identifier of this message.
*
@@ -82,7 +82,7 @@ public String getIdentifier() {
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
-
+
/**
* Returns the name of this message.
*
@@ -91,7 +91,7 @@ public void setIdentifier(String identifier) {
public String getName() {
return name;
}
-
+
/**
* Tests whether this message contains the parameter with the specified key.
* Key names are compared ignoring case.
@@ -103,7 +103,7 @@ public String getName() {
public boolean containsKey(String key) {
return parameters.containsKey(key.toLowerCase());
}
-
+
/**
* Returns all parameters of this message. The keys of the entries are all
* lower case so if you want to match the parameter names you have to watch
@@ -114,7 +114,7 @@ public boolean containsKey(String key) {
public Set> entrySet() {
return parameters.entrySet();
}
-
+
/**
* Returns the value of the parameter with the name specified by
* key.
@@ -125,7 +125,7 @@ public Set> entrySet() {
public String get(String key) {
return parameters.get(key.toLowerCase());
}
-
+
/**
* Stores the specified value as parameter with the name specified by
* key.
@@ -138,7 +138,7 @@ public String get(String key) {
public String put(String key, String value) {
return parameters.put(key.toLowerCase(), value);
}
-
+
/**
* Returns the number of parameters in this message.
*
@@ -147,21 +147,21 @@ public String put(String key, String value) {
public int size() {
return parameters.size();
}
-
+
/**
* @return Returns the payloadInputStream.
*/
public InputStream getPayloadInputStream() {
return payloadInputStream;
}
-
+
/**
* @param payloadInputStream The payloadInputStream to set.
*/
public void setPayloadInputStream(InputStream payloadInputStream) {
this.payloadInputStream = payloadInputStream;
}
-
+
/**
* Returns a textual representation of this message, containing its name,
* the identifier, and the parameters.
@@ -172,5 +172,5 @@ public void setPayloadInputStream(InputStream payloadInputStream) {
public String toString() {
return name + "[identifier=" + identifier + ",parameters=" + parameters.toString() + "]";
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Node.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Node.java
index e27668b..67df2d3 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/Node.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/Node.java
@@ -25,22 +25,22 @@
* @version $Id$
*/
public class Node {
-
+
/**
* The default port of FCPv2.
*/
public static final int DEFAULT_PORT = 9481;
-
+
/**
* The hostname of the node.
*/
protected String hostname;
-
+
/**
* The port number of the node.
*/
protected int port;
-
+
/**
* Creates a new node with the specified hostname and the default port
* number.
@@ -51,7 +51,7 @@ public class Node {
public Node(String hostname) {
this(hostname, DEFAULT_PORT);
}
-
+
/**
* Creates a new node with the specified hostname and port number.
*
@@ -62,7 +62,7 @@ public Node(String hostname, int port) {
this.hostname = hostname;
this.port = port;
}
-
+
/**
* Returns the hostname of the node.
*
@@ -71,7 +71,7 @@ public Node(String hostname, int port) {
public String getHostname() {
return hostname;
}
-
+
/**
* Returns the port number of the node.
*
@@ -80,5 +80,5 @@ public String getHostname() {
public int getPort() {
return port;
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/StreamCopier.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/StreamCopier.java
index c3bcb9b..7b5d0d2 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/StreamCopier.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/StreamCopier.java
@@ -27,32 +27,32 @@
* @version $Id$
*/
public class StreamCopier {
-
+
/**
* The default size of the buffer.
*/
private static final int BUFFER_SIZE = 64 * 1024;
-
+
/**
* The {@link InputStream} to read from.
*/
- private InputStream inputStream;
-
+ private final InputStream inputStream;
+
/**
* The {@link OutputStream} to write to.
*/
- private OutputStream outputStream;
-
+ private final OutputStream outputStream;
+
/**
* The number of bytes to copy.
*/
- private long length;
-
+ private final long length;
+
/**
* The size of the buffer.
*/
- private int bufferSize;
-
+ private final int bufferSize;
+
/**
* Creates a new StreamCopier with the specified parameters and the default
* buffer size.
@@ -64,7 +64,7 @@ public class StreamCopier {
public StreamCopier(InputStream inputStream, OutputStream outputStream, long length) {
this(inputStream, outputStream, length, BUFFER_SIZE);
}
-
+
/**
* Creates a new StreamCopier with the specified parameters and the default
* buffer size.
@@ -80,7 +80,7 @@ public StreamCopier(InputStream inputStream, OutputStream outputStream, long len
this.length = length;
this.bufferSize = bufferSize;
}
-
+
/**
* Copies the stream data. If the input stream is depleted before the
* requested number of bytes have been read an {@link EOFException} is
@@ -93,7 +93,7 @@ public StreamCopier(InputStream inputStream, OutputStream outputStream, long len
public void copy() throws EOFException, IOException {
copy(inputStream, outputStream, length, bufferSize);
}
-
+
/**
* Copies length bytes from the inputStream to the
* outputStream.
@@ -106,7 +106,7 @@ public void copy() throws EOFException, IOException {
public static void copy(InputStream inputStream, OutputStream outputStream, long length) throws IOException {
copy(inputStream, outputStream, length, BUFFER_SIZE);
}
-
+
/**
* Copies length bytes from the inputStream to the
* outputStream using a buffer with the specified size
@@ -119,9 +119,9 @@ public static void copy(InputStream inputStream, OutputStream outputStream, long
*/
public static void copy(InputStream inputStream, OutputStream outputStream, long length, int bufferSize) throws IOException {
long remaining = length;
- byte[] buffer = new byte[bufferSize];
+ final byte[] buffer = new byte[bufferSize];
while (remaining > 0) {
- int read = inputStream.read(buffer, 0, (int) Math.min(Integer.MAX_VALUE, Math.min(bufferSize, remaining)));
+ final int read = inputStream.read(buffer, 0, (int) Math.min(Integer.MAX_VALUE, Math.min(bufferSize, remaining)));
if (read == -1) {
throw new EOFException();
}
@@ -129,5 +129,5 @@ public static void copy(InputStream inputStream, OutputStream outputStream, long
remaining -= read;
}
}
-
+
}
diff --git a/src/pluginbase/de/todesbaum/util/freenet/fcp2/TempFileInputStream.java b/src/pluginbase/de/todesbaum/util/freenet/fcp2/TempFileInputStream.java
index f691260..642a93a 100644
--- a/src/pluginbase/de/todesbaum/util/freenet/fcp2/TempFileInputStream.java
+++ b/src/pluginbase/de/todesbaum/util/freenet/fcp2/TempFileInputStream.java
@@ -28,9 +28,9 @@
* @version $Id$
*/
public class TempFileInputStream extends FileInputStream {
-
- private File tempFile;
-
+
+ private final File tempFile;
+
/**
* @param name
* @throws FileNotFoundException
@@ -38,7 +38,7 @@ public class TempFileInputStream extends FileInputStream {
public TempFileInputStream(String name) throws FileNotFoundException {
this(new File(name));
}
-
+
/**
* @param file
* @throws FileNotFoundException
@@ -47,11 +47,11 @@ protected TempFileInputStream(File file) throws FileNotFoundException {
super(file);
tempFile = file;
}
-
+
@Override
public void close() throws IOException {
super.close();
tempFile.delete();
}
-
+
}
diff --git a/src/resources/static/style.css b/src/resources/static/style.css
index 330ab31..166264c 100644
--- a/src/resources/static/style.css
+++ b/src/resources/static/style.css
@@ -157,3 +157,11 @@ input[type="text"] {
padding-bottom: 8em;
}
}
+
+/* for the entry table anchors, because the freenet header */
+a.anchor {
+ display: block;
+ position: relative;
+ top: -100px;
+ visibility: hidden;
+}
diff --git a/src/resources/templates/overview_table.html b/src/resources/templates/overview_table.html
new file mode 100644
index 0000000..9bcbd62
--- /dev/null
+++ b/src/resources/templates/overview_table.html
@@ -0,0 +1,12 @@
+
+
+ | URI |
+ total blocks |
+ available blocks |
+ missed blocks |
+ blocks availability |
+ segments availability |
+ Actions |
+
+ ${url_entries}
+
diff --git a/src/resources/templates/properties.html b/src/resources/templates/properties.html
index 6a08bb0..0cb4775 100644
--- a/src/resources/templates/properties.html
+++ b/src/resources/templates/properties.html
@@ -40,7 +40,18 @@
-
+
+
+
+
+
+
+
+ | Remove: |
+
+
+
+
|
diff --git a/src/resources/templates/url_entry.html b/src/resources/templates/url_entry.html
new file mode 100644
index 0000000..cea1556
--- /dev/null
+++ b/src/resources/templates/url_entry.html
@@ -0,0 +1,15 @@
+
+ |
+
+ ${url_short}
+ |
+ ${url_blockSize} |
+ ${url_success} |
+ ${url_failure} |
+ ${url_persistence} % |
+ ${url_segmentsAvailability} % |
+ remove |
+ log |
+ ${url_modus} |
+ ${url_active} |
+