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;
}
-
+
/**
*
* @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,150 @@ 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) {
+
+ public synchronized void logFile(String strFilename, String cText, int nLogLevel) {
try {
-
- if (nLogLevel <= getIntProp("loglevel")) {
+
+ 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 +319,253 @@ 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 log(String cText, int nLogLevel) {
- log("log.txt", cText, nLogLevel);
+
+ public void log(String cText, Object... args) {
+ logFile("log.txt", String.format(cText, args), 0);
}
-
+
+ public void log(String cText, int 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) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ return sw.toString();
+ }
+
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/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: |
+
+
+
+
|
From a6ce03c14a21385aa935ce8cde3bb4c4ddfd0069 Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Wed, 21 Dec 2022 18:09:58 +0100
Subject: [PATCH 2/9] optimized; old shortUri back; better fetch log output
---
.gitignore | 1 +
.settings/org.eclipse.buildship.core.prefs | 13 -
.settings/org.eclipse.jdt.core.prefs | 15 --
src/keepalive/Plugin.java | 44 +++-
src/keepalive/exceptions/DAOException.java | 2 +-
.../exceptions/DuplicateKeyException.java | 29 +++
.../exceptions/FetchFailedException.java | 2 +-
.../exceptions/PropertiesException.java | 2 +-
src/keepalive/model/PropertiesKey.java | 6 +-
src/keepalive/model/Segment.java | 6 +-
src/keepalive/repository/IDatabaseBlock.java | 6 +-
src/keepalive/repository/IDatabaseDAO.java | 20 +-
.../repository/impl/DatabaseBlock.java | 9 +-
.../repository/impl/H2DatabaseDAO.java | 79 +++---
src/keepalive/service/net/SingleFetch.java | 32 ++-
src/keepalive/service/net/SingleInsert.java | 12 +-
src/keepalive/service/net/SingleJob.java | 36 ++-
.../service/reinserter/FetchBlocksResult.java | 6 +-
.../service/reinserter/Reinserter.java | 232 ++++++++++--------
src/keepalive/urivalues/IUriValue.java | 18 +-
.../impl/PropertiesUriValuesDAO.java | 17 +-
src/keepalive/urivalues/impl/UriValue.java | 39 +--
src/keepalive/web/AdminPage.java | 16 +-
src/pluginbase/PageBase.java | 2 +-
src/pluginbase/PluginBase.java | 2 +-
25 files changed, 345 insertions(+), 301 deletions(-)
delete mode 100644 .settings/org.eclipse.buildship.core.prefs
delete mode 100644 .settings/org.eclipse.jdt.core.prefs
create mode 100644 src/keepalive/exceptions/DuplicateKeyException.java
diff --git a/.gitignore b/.gitignore
index 84d2250..edae0ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ build/
.gradle/
.idea/
*.iml
+/.settings
diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs
deleted file mode 100644
index a2e97ee..0000000
--- a/.settings/org.eclipse.buildship.core.prefs
+++ /dev/null
@@ -1,13 +0,0 @@
-arguments=
-auto.sync=false
-build.scans.enabled=false
-connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(4.10.3))
-connection.project.dir=
-eclipse.preferences.version=1
-gradle.user.home=
-java.home=C\:/Program Files/Eclipse Adoptium/jdk8u345-b01
-jvm.arguments=
-offline.mode=false
-override.workspace.settings=true
-show.console.view=true
-show.executions.view=true
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 0fee6a9..0000000
--- a/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,15 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/src/keepalive/Plugin.java b/src/keepalive/Plugin.java
index c7914a0..41fec9e 100644
--- a/src/keepalive/Plugin.java
+++ b/src/keepalive/Plugin.java
@@ -68,12 +68,11 @@ public void runPlugin(PluginRespirator pr) {
try {
hlsc = (HighLevelSimpleClientImpl) pluginContext.node.clientCore.makeClient((short) 5, false, true);
- // old 0.2 to 0.3 update
- updateProperties();
-
// initialize all common property keys with its default value
initPropKeys();
+ updateProperties();
+
// db migration
this.databaseDAO.pluginStart();
@@ -91,7 +90,6 @@ public void runPlugin(PluginRespirator pr) {
if (activeProp != -1) {
startReinserter(activeProp);
}
-
} catch (final Exception e) {
log("Plugin.runPlugin Exception: " + e.getMessage(), 0);
}
@@ -99,7 +97,7 @@ public void runPlugin(PluginRespirator pr) {
private void updateProperties() throws DAOException {
// migrate from 0.2 to 0.3
- if (getProp(PropertiesKey.VERSION) == null || !"0.3".equals(getProp(PropertiesKey.VERSION).substring(0, 3))) {
+ if (getProp(PropertiesKey.VERSION) != null && "0.2".equals(getProp(PropertiesKey.VERSION).substring(0, 3))) {
for (final IUriValue uriValue : uriPropsDAO.getAll()) {
// remove boost params
removeProp("boost_" + uriValue.getUriId());
@@ -110,6 +108,22 @@ private void updateProperties() throws DAOException {
}
setProp(PropertiesKey.VERSION, VERSION);
+ saveProp(true);
+ }
+
+ // rewrite update
+ if ("0.3.3.11-RW".equals(getProp(PropertiesKey.VERSION))) {
+ setProp(PropertiesKey.DB_VERSION, "199");
+ setProp(PropertiesKey.VERSION, VERSION);
+ saveProp(true);
+ return;
+ }
+
+ // new install
+ if (getProp(PropertiesKey.VERSION) == null) {
+ setProp(PropertiesKey.DB_VERSION, "206");
+ setProp(PropertiesKey.VERSION, VERSION);
+ saveProp(true);
}
}
@@ -229,14 +243,18 @@ public String getLogFilename(IUriValue uriValue) {
return String.format("log%s.txt", uriValue.getUriId());
}
- @Override
- public synchronized void saveProp() {
- if (propSavingTimestamp < System.currentTimeMillis() - 10 * 1000) {
+ public synchronized void saveProp(boolean force) {
+ if (force || propSavingTimestamp < System.currentTimeMillis() - 10 * 1000) {
super.saveProp();
propSavingTimestamp = System.currentTimeMillis();
}
}
+ @Override
+ public void saveProp() {
+ saveProp(false);
+ }
+
@Override
public void terminate() {
stopReinserter();
@@ -260,12 +278,13 @@ public void removeUriAndFiles(IUriValue uriValue) {
// remove log files
final File file = new File(getPluginDirectory() + getLogFilename(uriValue));
if (file.exists() && !file.delete()) {
- log("Plugin.removeUri(): remove log files was not successful.", 1);
+ log("Plugin.removeUriAndFiles(): remove log files was not successful.", 1);
+ return;
}
try {
// remove top block from db
- databaseDAO.delete(uriValue.getUriString());
+ databaseDAO.delete(uriValue.getUri());
// remove items
uriPropsDAO.delete(uriValue.getUriId());
@@ -278,11 +297,10 @@ public void removeUriAndFiles(IUriValue uriValue) {
* initialize all common property keys with its default value
*/
private void initPropKeys() {
- for (final PropertiesKey key : PropertiesKey.values()) {
+ for (final PropertiesKey key : PropertiesKey.values())
initPropKey(key);
- }
- saveProp();
+ saveProp(true);
}
/**
diff --git a/src/keepalive/exceptions/DAOException.java b/src/keepalive/exceptions/DAOException.java
index 6c82fe6..4c74a0a 100644
--- a/src/keepalive/exceptions/DAOException.java
+++ b/src/keepalive/exceptions/DAOException.java
@@ -2,7 +2,7 @@
public class DAOException extends Exception {
- private static final long serialVersionUID = 3156450661722048683L;
+ private static final long serialVersionUID = 87724461226632647L;
public DAOException() {}
diff --git a/src/keepalive/exceptions/DuplicateKeyException.java b/src/keepalive/exceptions/DuplicateKeyException.java
new file mode 100644
index 0000000..c8c2b37
--- /dev/null
+++ b/src/keepalive/exceptions/DuplicateKeyException.java
@@ -0,0 +1,29 @@
+package keepalive.exceptions;
+
+public class DuplicateKeyException extends Exception {
+
+ private static final long serialVersionUID = 4112466609861664685L;
+
+ public DuplicateKeyException() {}
+
+ public DuplicateKeyException(String message) {
+ super(message);
+ }
+
+ public DuplicateKeyException(String message, Object... args) {
+ super(String.format(message, args));
+ }
+
+ public DuplicateKeyException(Throwable cause) {
+ super(cause);
+ }
+
+ public DuplicateKeyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DuplicateKeyException(String message, Throwable cause, Object... args) {
+ super(String.format(message, args), cause);
+ }
+
+}
diff --git a/src/keepalive/exceptions/FetchFailedException.java b/src/keepalive/exceptions/FetchFailedException.java
index ea15e00..52e1101 100644
--- a/src/keepalive/exceptions/FetchFailedException.java
+++ b/src/keepalive/exceptions/FetchFailedException.java
@@ -2,7 +2,7 @@
public class FetchFailedException extends Exception {
- private static final long serialVersionUID = 3559707685208595270L;
+ private static final long serialVersionUID = -1746833000014867257L;
public FetchFailedException() {}
diff --git a/src/keepalive/exceptions/PropertiesException.java b/src/keepalive/exceptions/PropertiesException.java
index 3322063..541c327 100644
--- a/src/keepalive/exceptions/PropertiesException.java
+++ b/src/keepalive/exceptions/PropertiesException.java
@@ -2,7 +2,7 @@
public class PropertiesException extends Exception {
- private static final long serialVersionUID = 3156450661722048683L;
+ private static final long serialVersionUID = -2845555980331219730L;
public PropertiesException() {}
diff --git a/src/keepalive/model/PropertiesKey.java b/src/keepalive/model/PropertiesKey.java
index 685f7ea..4db7162 100644
--- a/src/keepalive/model/PropertiesKey.java
+++ b/src/keepalive/model/PropertiesKey.java
@@ -18,8 +18,6 @@
*/
package keepalive.model;
-import keepalive.Plugin;
-
/**
* enum for all property keys with default values
* they get automatically initialised
@@ -27,8 +25,8 @@
public enum PropertiesKey {
// common properties
- DB_VERSION("db_version", "199"),
- VERSION("version", Plugin.VERSION),
+ DB_VERSION("db_version"), //, "199"
+ VERSION("version"), //, Plugin.VERSION
LOGLEVEL("loglevel", 1),
IDS("ids", ""),
POWER("power", 6),
diff --git a/src/keepalive/model/Segment.java b/src/keepalive/model/Segment.java
index 890e3e8..7bcc85c 100644
--- a/src/keepalive/model/Segment.java
+++ b/src/keepalive/model/Segment.java
@@ -109,7 +109,7 @@ public boolean isFinished() {
if (size == 1) {
finished = getBlock(0).isInsertDone();
} else {
- for (IBlock block : blocks) {
+ for (final IBlock block : blocks) {
if (block != null && !block.isFetchSuccessful() && !block.isInsertDone()) {
finished = false;
break;
@@ -120,8 +120,8 @@ public boolean isFinished() {
// free blocks (especially buckets)
if (finished) {
- for (IBlock block : blocks) {
- if (block != null)
+ for (final IBlock block : blocks) {
+ if (block != null && block.getBucket() != null)
block.getBucket().free();
}
blocks = null;
diff --git a/src/keepalive/repository/IDatabaseBlock.java b/src/keepalive/repository/IDatabaseBlock.java
index 583a780..2ea0f26 100644
--- a/src/keepalive/repository/IDatabaseBlock.java
+++ b/src/keepalive/repository/IDatabaseBlock.java
@@ -1,10 +1,12 @@
package keepalive.repository;
+import freenet.keys.FreenetURI;
+
public interface IDatabaseBlock {
- String getUri();
+ FreenetURI getUri();
- void setUri(String uri);
+ void setUri(FreenetURI uri);
byte[] getData();
diff --git a/src/keepalive/repository/IDatabaseDAO.java b/src/keepalive/repository/IDatabaseDAO.java
index 3412fb1..c9f20db 100644
--- a/src/keepalive/repository/IDatabaseDAO.java
+++ b/src/keepalive/repository/IDatabaseDAO.java
@@ -18,6 +18,9 @@
*/
package keepalive.repository;
+import freenet.keys.FreenetURI;
+import keepalive.exceptions.DAOException;
+
/**
* Interface for a database
*/
@@ -33,21 +36,18 @@ default void pluginStart() {}
*/
default void pluginTerminate() {}
- /**
- *
- */
- IDatabaseBlock create(String uri, byte[] data);
+ IDatabaseBlock create(FreenetURI uri, byte[] data) throws DAOException;
- IDatabaseBlock read(String uri);
+ IDatabaseBlock read(FreenetURI uri) throws DAOException;
- void update(IDatabaseBlock databaseBlock);
+ void update(IDatabaseBlock databaseBlock) throws DAOException;
- void delete(String uri);
+ void delete(FreenetURI uri) throws DAOException;
- boolean exist(String uri);
+ boolean exist(FreenetURI uri) throws DAOException;
- long lastAccessDiff(String uri);
+ long lastAccessDiff(FreenetURI uri) throws DAOException;
- void lastAccessUpdate(String uri);
+ void lastAccessUpdate(FreenetURI uri) throws DAOException;
}
diff --git a/src/keepalive/repository/impl/DatabaseBlock.java b/src/keepalive/repository/impl/DatabaseBlock.java
index 18d8bda..e036d80 100644
--- a/src/keepalive/repository/impl/DatabaseBlock.java
+++ b/src/keepalive/repository/impl/DatabaseBlock.java
@@ -3,25 +3,26 @@
import java.util.Arrays;
import java.util.Objects;
+import freenet.keys.FreenetURI;
import keepalive.repository.IDatabaseBlock;
public class DatabaseBlock implements IDatabaseBlock {
- private String uri;
+ private FreenetURI uri;
private byte[] data;
- public DatabaseBlock(String uri, byte[] data) {
+ public DatabaseBlock(FreenetURI uri, byte[] data) {
this.uri = uri;
this.data = data;
}
@Override
- public String getUri() {
+ public FreenetURI getUri() {
return uri;
}
@Override
- public void setUri(String uri) {
+ public void setUri(FreenetURI uri) {
this.uri = uri;
}
diff --git a/src/keepalive/repository/impl/H2DatabaseDAO.java b/src/keepalive/repository/impl/H2DatabaseDAO.java
index d0b82ee..ab13f2a 100644
--- a/src/keepalive/repository/impl/H2DatabaseDAO.java
+++ b/src/keepalive/repository/impl/H2DatabaseDAO.java
@@ -23,13 +23,16 @@
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.h2.jdbc.JdbcSQLNonTransientException;
import org.h2.tools.Upgrade;
+import freenet.keys.FreenetURI;
import keepalive.Plugin;
+import keepalive.exceptions.DAOException;
import keepalive.exceptions.DatabaseException;
import keepalive.model.PropertiesKey;
import keepalive.repository.IDatabaseBlock;
@@ -115,94 +118,101 @@ private void upgradeDB() throws DatabaseException {
}
@Override
- public IDatabaseBlock create(String uri, byte[] data) {
- if (exist(uri) || data == null)
- return null;
+ public IDatabaseBlock create(FreenetURI uri, byte[] data) throws DAOException {
+ if (data == null)
+ throw new DAOException("The data need to be not null!");
+ if (exist(uri))
+ throw new DAOException("The block uri: '%s' is already saved", uri);
IDatabaseBlock result = null;
try (Connection connection = getConnection();
PreparedStatement savePreparedStatement = connection.prepareStatement(SQL_SAVE)) {
- savePreparedStatement.setString(1, uri);
+ savePreparedStatement.setString(1, uri.toString());
savePreparedStatement.setBytes(2, data);
savePreparedStatement.executeUpdate();
result = new DatabaseBlock(uri, data);
- } catch (final Exception e) {
- plugin.log(e.getMessage() + " " + uri, e);
+ } catch (SQLException | DatabaseException e) {
+ throw new DAOException("DatabaseBlock for uri: %s couldnt be created", e, uri);
}
return result;
}
@Override
- public IDatabaseBlock read(String uri) {
- IDatabaseBlock result = null;
+ public IDatabaseBlock read(FreenetURI uri) throws DAOException {
+ if (uri == null)
+ throw new DAOException("The uri need to be not null!");
+ IDatabaseBlock result = null;
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(SQL_FIND)) {
- preparedStatement.setString(1, uri);
+ preparedStatement.setString(1, uri.toString());
final ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
final byte[] data = resultSet.getBytes("data");
- if (resultSet.next()) {
- plugin.log("Not unique uri: " + uri);
- return null;
- }
+ if (resultSet.next())
+ throw new DAOException("DatabaseBlock for uri: %s is not unique", uri);
result = new DatabaseBlock(uri, data);
}
- } catch (final Exception e) {
- plugin.log(e.getMessage() + " " + uri, e);
+ } catch (SQLException | DatabaseException e) {
+ throw new DAOException("DatabaseBlock for uri: %s couldnt be loaded", e, uri);
}
return result;
}
@Override
- public void update(IDatabaseBlock databaseBlock) {
- if (databaseBlock == null || !exist(databaseBlock.getUri()))
- return;
+ public void update(IDatabaseBlock databaseBlock) throws DAOException {
+ if (databaseBlock == null)
+ throw new DAOException("The databaseBlock need to be not null!");
+ if (!exist(databaseBlock.getUri()))
+ throw new DAOException("The databaseBlock uri: '%s' doesnt exist", databaseBlock.getUri());
try (Connection connection = getConnection();
PreparedStatement updatePreparedStatement = connection.prepareStatement(SQL_UPDATE)) {
updatePreparedStatement.setBytes(1, databaseBlock.getData());
- updatePreparedStatement.setString(2, databaseBlock.getUri());
+ updatePreparedStatement.setString(2, databaseBlock.getUri().toString());
updatePreparedStatement.executeUpdate();
- } catch (final Exception e) {
- plugin.log(e.getMessage() + " " + databaseBlock.getUri(), e);
+ } catch (SQLException | DatabaseException e) {
+ throw new DAOException("DatabaseBlock for uri: %s couldnt be updated", e, databaseBlock.getUri());
}
}
@Override
- public void delete(String uri) {
+ public void delete(FreenetURI uri) throws DAOException {
if (!exist(uri))
return;
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(SQL_DELETE)) {
- preparedStatement.setString(1, uri);
+ preparedStatement.setString(1, uri.toString());
preparedStatement.executeUpdate();
- } catch (final Exception e) {
- plugin.log(e.getMessage() + " " + uri, e);
+ } catch (SQLException | DatabaseException e) {
+ throw new DAOException("DatabaseBlock for uri: %s couldnt be deleted", e, uri);
}
}
@Override
- public boolean exist(String uri) {
+ public boolean exist(FreenetURI uri) throws DAOException {
if (uri == null)
- return false;
+ throw new DAOException("The uri need to be not null!");
return read(uri) != null;
}
@Override
- public long lastAccessDiff(String uri) {
+ public long lastAccessDiff(FreenetURI uri) throws DAOException {
+ if (uri == null)
+ throw new DAOException("The uri need to be not null!");
+
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(SQL_LAST_ACCESS_DIFF)) {
- preparedStatement.setString(1, uri);
+ preparedStatement.setString(1, uri.toString());
final ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.next()) {
return 0;
@@ -216,20 +226,23 @@ public long lastAccessDiff(String uri) {
return diff;
} catch (final Exception e) {
- plugin.log(e.getMessage() + " " + uri, e);
+ plugin.log("%s %s", e, e.getMessage(), uri);
}
return 0;
}
@Override
- public void lastAccessUpdate(String uri) {
+ public void lastAccessUpdate(FreenetURI uri) throws DAOException {
+ if (uri == null)
+ throw new DAOException("The uri need to be not null!");
+
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(SQL_LAST_ACCESS_UPDATE)) {
- preparedStatement.setString(1, uri);
+ preparedStatement.setString(1, uri.toString());
preparedStatement.executeUpdate();
} catch (final Exception e) {
- plugin.log(e.getMessage() + " " + uri, e);
+ throw new DAOException("lastAccessUpdate error", e);
}
}
diff --git a/src/keepalive/service/net/SingleFetch.java b/src/keepalive/service/net/SingleFetch.java
index 5e77769..4cc6bcb 100644
--- a/src/keepalive/service/net/SingleFetch.java
+++ b/src/keepalive/service/net/SingleFetch.java
@@ -27,26 +27,43 @@
import freenet.support.io.ArrayBucket;
import keepalive.Plugin;
import keepalive.model.IBlock;
+import keepalive.service.reinserter.FetchBlocksResult;
import keepalive.service.reinserter.Reinserter;
public class SingleFetch extends SingleJob implements Callable {
- private final boolean persistenceCheck;
+ private boolean persistenceCheck;
+ private FetchBlocksResult fetchBlocksResult;
- public SingleFetch(Reinserter reinserter, IBlock block, boolean persistenceCheck) {
+ public SingleFetch(Reinserter reinserter, IBlock block) {
super(reinserter, "fetch", block);
- this.persistenceCheck = persistenceCheck;
+ this.persistenceCheck = false;
+ }
+
+ public SingleFetch(Reinserter reinserter, IBlock block, FetchBlocksResult fetchBlocksResult) {
+ this(reinserter, block);
+
+ this.persistenceCheck = true;
+ this.fetchBlocksResult = fetchBlocksResult;
}
@Override
public Boolean call() {
+ final Boolean result = fetch();
+
+ if (fetchBlocksResult != null)
+ fetchBlocksResult.addResult(result);
+
+ return result;
+ }
+
+ public Boolean fetch() {
Thread.currentThread().setName(Plugin.PLUGIN_NAME + " SingleFetch");
FetchResult fetchResult = null;
boolean fetchSuccessful = false;
try {
-
// init
final HLSCIgnoreStore hlscIgnoreStore = HLSCIgnoreStore.getInstance(plugin.getFreenetClient());
@@ -62,7 +79,7 @@ public Boolean call() {
fetchResult = hlscIgnoreStore.fetch(fetchUri);
}
} catch (final FetchException e) {
- block.setResultLog("-> fetch error: " + e.getMessage());
+ block.setResultLog("error: " + e.getMessage());
}
if (Thread.currentThread().isInterrupted()) {
@@ -72,11 +89,11 @@ public Boolean call() {
// log / success flag
if (block.getResultLog() == null) {
if (fetchResult == null) {
- block.setResultLog("-> fetch failed");
+ block.setResultLog("failed");
} else {
block.setBucket(new ArrayBucket(fetchResult.asByteArray()));
block.setFetchSuccessful(true);
- block.setResultLog("-> fetch successful");
+ block.setResultLog("successful");
fetchSuccessful = true;
}
}
@@ -84,7 +101,6 @@ public Boolean call() {
//finish
reinserter.registerBlockFetchSuccess(block);
block.setFetchDone(true);
-
} catch (final IOException e) {
log("SingleFetch.run(): " + e.getMessage(), 0);
} finally {
diff --git a/src/keepalive/service/net/SingleInsert.java b/src/keepalive/service/net/SingleInsert.java
index 211d302..6faae0b 100644
--- a/src/keepalive/service/net/SingleInsert.java
+++ b/src/keepalive/service/net/SingleInsert.java
@@ -49,7 +49,7 @@ public void run() {
try {
// fetch
if (block.getBucket() == null) {
- final SingleFetch singleFetch = new SingleFetch(reinserter, block, false);
+ final SingleFetch singleFetch = new SingleFetch(reinserter, block);
singleFetch.call();
if (!reinserter.isActive()) {
return;
@@ -59,7 +59,7 @@ public void run() {
final Segment segment = reinserter.getSegments().get(block.getSegmentId());
if (block.getBucket() == null) {
- block.setResultLog("-> insertion failed: fetch failed");
+ block.setResultLog("failed: fetch failed");
} else { // insert
if (Thread.currentThread().isInterrupted()) {
return;
@@ -96,16 +96,16 @@ public void run() {
if (insertUri != null) {
if (fetchUri.equals(insertUri)) {
block.setInsertSuccessful(true);
- block.setResultLog("-> inserted: " + insertUri.toString());
+ block.setResultLog("inserted: " + insertUri.toString());
} else {
- block.setResultLog("-> insertion failed - different uri: " + insertUri.toString());
+ block.setResultLog("failed - different uri: " + insertUri.toString());
}
} else {
- block.setResultLog("-> insertion failed");
+ block.setResultLog("failed");
}
} catch (final InsertException e) {
- block.setResultLog("-> insertion error: " + e.getMessage());
+ block.setResultLog("error: " + e.getMessage());
}
}
diff --git a/src/keepalive/service/net/SingleJob.java b/src/keepalive/service/net/SingleJob.java
index 5261aa4..941a1dd 100644
--- a/src/keepalive/service/net/SingleJob.java
+++ b/src/keepalive/service/net/SingleJob.java
@@ -28,22 +28,22 @@ public abstract class SingleJob {
public static final int MAX_LIFETIME = 30;
- Plugin plugin;
- Reinserter reinserter;
- IBlock block;
- byte[] uriExtra;
- String compressionAlgorithm;
+ protected Plugin plugin;
+ protected Reinserter reinserter;
+ protected IBlock block;
+ protected byte[] uriExtra;
+ protected String compressionAlgorithm;
private final String jobType;
- SingleJob(Reinserter reinserter, String jobType, IBlock block) {
+ protected SingleJob(Reinserter reinserter, String jobType, IBlock block) {
this.reinserter = reinserter;
this.jobType = jobType;
this.block = block;
this.plugin = reinserter.getPlugin();
}
- FreenetURI getUri() {
+ protected FreenetURI getUri() {
final FreenetURI uri = block.getUri().clone();
// modify the control flag of the URI to get always the raw data
@@ -57,24 +57,20 @@ FreenetURI getUri() {
compressionAlgorithm = "none";
}
- log("request: " + block.getUri().toString() +
- " (crypt=" + uriExtra[1] +
- ",control=" + block.getUri().getExtra()[2] +
- ",compress=" + uriExtra[4] + "=" + compressionAlgorithm + ")", 2);
+ log(String.format("request: %s (crypt=%s,control=%s,compress=%s=%s)", block.getUri(), uriExtra[1], block.getUri().getExtra()[2], uriExtra[4], compressionAlgorithm), 2);
return uri;
}
- void finish() {
+ protected void finish() {
if (reinserter.isActive() && !reinserter.isInterrupted()) {
- // log
- String firstLog = jobType + ": " + block.getUri();
- if (!block.isFetchSuccessful() && !block.isInsertSuccessful()) {
- firstLog = "" + firstLog + "";
- block.setResultLog("" + block.getResultLog() + "");
- }
- log(firstLog);
- log(block.getResultLog());
+ String msg = String.format("%s: %s -> %s", jobType, block.getResultLog(), block.getUri());
+
+ // error or problem
+ if (!block.isFetchSuccessful() && !block.isInsertSuccessful())
+ msg = String.format("%s", msg);
+
+ log(msg);
}
}
diff --git a/src/keepalive/service/reinserter/FetchBlocksResult.java b/src/keepalive/service/reinserter/FetchBlocksResult.java
index 610422f..1c85ecf 100644
--- a/src/keepalive/service/reinserter/FetchBlocksResult.java
+++ b/src/keepalive/service/reinserter/FetchBlocksResult.java
@@ -1,11 +1,11 @@
package keepalive.service.reinserter;
-class FetchBlocksResult {
+public class FetchBlocksResult {
private int successful = 0;
private int failed = 0;
- void addResult(boolean successful) {
+ public synchronized void addResult(boolean successful) {
if (successful) {
this.successful++;
} else {
@@ -13,7 +13,7 @@ void addResult(boolean successful) {
}
}
- double calculatePersistenceRate() {
+ public double calculatePersistenceRate() {
return (double) successful / (successful + failed);
}
diff --git a/src/keepalive/service/reinserter/Reinserter.java b/src/keepalive/service/reinserter/Reinserter.java
index 4444554..4fe216f 100644
--- a/src/keepalive/service/reinserter/Reinserter.java
+++ b/src/keepalive/service/reinserter/Reinserter.java
@@ -26,17 +26,18 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
+import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;
import org.apache.tools.tar.TarInputStream;
@@ -61,6 +62,7 @@
import freenet.support.io.ArrayBucket;
import keepalive.Plugin;
import keepalive.exceptions.DAOException;
+import keepalive.exceptions.DuplicateKeyException;
import keepalive.exceptions.FetchFailedException;
import keepalive.model.Block;
import keepalive.model.IBlock;
@@ -78,89 +80,42 @@ public final class Reinserter extends Thread {
private final Plugin plugin;
private final IUriValue uriValue;
private final CountDownLatch latch;
- private PluginRespirator pr;
+ private final PluginRespirator pr;
+ private final String logFilename;
+ private final Set manifestURIs = new LinkedHashSet<>();
+ private final List segments = new ArrayList<>();
private long lastActivityTime;
- private Map manifestURIs;
- //private Map blocks;
private int parsedSegmentId;
private int parsedBlockId;
- private final ArrayList segments = new ArrayList<>();
public Reinserter(Plugin plugin, IUriValue uriValue, CountDownLatch latch) {
this.plugin = plugin;
this.uriValue = uriValue;
this.latch = latch;
this.setName(Plugin.PLUGIN_NAME + " ReInserter " + uriValue.getUriId());
+ this.pr = plugin.pluginContext.pluginRespirator;
+ this.logFilename = plugin.getLogFilename(uriValue);
}
@Override
public void run() {
final int siteId = uriValue.getUriId();
+ FreenetURI uri = uriValue.getUri();
try {
// init
- pr = plugin.pluginContext.pluginRespirator;
- manifestURIs = new HashMap<>();
- //blocks = new HashMap<>();
- final String rawUri = uriValue.getUriString();
-
- plugin.log("start reinserter for site " + rawUri + " (" + siteId + ")", 1);
- plugin.clearLog(plugin.getLogFilename(uriValue));
+ plugin.logF(String.format("start reinserter for site %s (%s)", uri, siteId), 1);
+ plugin.clearLog(logFilename);
isActive(true);
long startedAt = System.currentTimeMillis();
long timeLeft = TimeUnit.HOURS.toMillis(plugin.getIntProp(PropertiesKey.SINGLE_URL_TIMESLOT));
- FreenetURI uri = new FreenetURI(rawUri);
-
// update if USK
- if (uri.isUSK()) {
- final FreenetURI newUri = updateUsk(uri);
- if (newUri != null && !newUri.equals(uri)) {
- plugin.log("received new uri: " + newUri, 1);
- if (plugin.uriPropsDAO.exist(newUri)) {
- plugin.log("remove uri as duplicate: " + newUri, 1);
- plugin.removeUriAndFiles(uriValue);
- return;
- }
-
- uriValue.setUri(newUri);
- uriValue.setBlockCount(-1);
- plugin.uriPropsDAO.update(uriValue);
-
- uri = newUri;
- }
- }
+ if (uri.isUSK())
+ uri = getNewUsk(uri);
// check top block availability
- final FreenetURI topBlockUri = Client.normalizeUri(uri.clone());
- if (plugin.databaseDAO.lastAccessDiff(topBlockUri.toString()) > TimeUnit.DAYS.toMillis(1)) {
- try {
- Client.fetch(topBlockUri, plugin.getFreenetClient());
- } catch (final FetchException e) {
- log(e.getShortMessage(), 0, 0);
- try {
- FreenetURI insertUri = null;
-
- final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(topBlockUri.toString());
- if (databaseBlock != null) {
- insertUri = Client.insert(topBlockUri, databaseBlock.getData(), plugin.getFreenetClient());
- }
-
- if (insertUri != null) {
- if (topBlockUri.equals(insertUri)) {
- log("Successfully inserted top block: " + insertUri.toString(), 0);
- } else {
- log("Top block insertion failed - different uri: " + insertUri.toString(), 0);
- }
- } else {
- log("Top block insertion failed (insertUri = null)", 0);
- }
- } catch (final InsertException e1) {
- log(e1.getMessage(), 0, 0);
- }
- }
- plugin.databaseDAO.lastAccessUpdate(topBlockUri.toString());
- }
+ checkTopBlockAndRepair(uri);
// register uri
registerManifestUri(uri, -1);
@@ -168,7 +123,6 @@ public void run() {
// load list of keys (if exists)
// skip if 1 because the manifest failed to fetch before.
final int numBlocks = uriValue.getBlockCount();
- plugin.log("numBlocks Check: %s", (Object) numBlocks);
if (numBlocks > 1) {
log("*** loading list of blocks ***", 0, 0);
} else {
@@ -176,47 +130,44 @@ public void run() {
log("*** parsing data structure ***", 0, 0);
parsedSegmentId = -1;
parsedBlockId = -1;
- while (manifestURIs.size() > 0) {
- if (isInterrupted()) {
+
+ while (!manifestURIs.isEmpty()) {
+ if (isInterrupted())
return;
- }
if (!isActive()) {
plugin.log("Stop after stuck state (metadata)", 0);
return;
}
- uri = (FreenetURI) manifestURIs.keySet().toArray()[0];
- log(uri.toString(), 0);
+ final FreenetURI manifestUri = manifestURIs.iterator().next();
+ log(manifestUri.toString(), 0);
+
try {
- parseMetadata(uri, null, 0);
+ parseMetadata(manifestUri, null, 0);
} catch (final FetchFailedException e) {
log(e.getMessage(), 0);
return;
}
- manifestURIs.remove(uri);
+
+ manifestURIs.remove(manifestUri);
}
if (isInterrupted()) {
return;
}
- plugin.log("Block update: Count: %s | Blocks: %s", uriValue.getBlockCount(), uriValue.getBlocks().size());
plugin.uriPropsDAO.update(uriValue);
}
// max segment id
- int maxSegmentId = -1;
- for (final IBlock block : uriValue.getBlocks().values()) {
- maxSegmentId = Math.max(maxSegmentId, block.getSegmentId());
- }
+ final int maxSegmentId = uriValue.getBlocks().values().stream().mapToInt(IBlock::getSegmentId).max().orElse(-1);
// init reinsertion
- if (uriValue.getSegment() == maxSegmentId) {
+ if (uriValue.getSegment() == maxSegmentId)
uriValue.setSegment(-1);
- }
+
if (uriValue.getSegment() == -1) {
-
log("*** starting reinsertion ***", 0, 0);
// reset success counter
@@ -231,10 +182,9 @@ public void run() {
}
uriValue.setSuccess(success.toString());
uriValue.setSuccessSegments(segmentsSuccess.toString());
- plugin.uriPropsDAO.update(uriValue);
+ plugin.uriPropsDAO.update(uriValue);
} else {
-
log("*** continuing reinsertion ***", 0, 0);
// add dummy segments
@@ -247,8 +197,8 @@ public void run() {
for (int i = (uriValue.getSegment() + 1) * 2; i < successProp.length; i++) {
successProp[i] = "0";
}
- saveSuccessToProp(successProp);
+ saveSuccessToProp(successProp);
}
// start reinsertion
@@ -558,8 +508,10 @@ public void run() {
}
log("*** reinsertion finished ***", 0, 0);
- plugin.log("reinsertion finished for " + uriValue.getUriString(), 1);
-
+ plugin.log("reinsertion finished for " + uriValue.getUri().toString(), 1);
+ } catch (final DuplicateKeyException e) {
+ // if getNewUsk find a new url and this is a duplicate
+ return;
} catch (final Exception e) {
plugin.log("Reinserter.run()", e);
} finally {
@@ -569,29 +521,98 @@ public void run() {
}
}
+ /**
+ * Checks for a new USK key edition and returns the key
+ */
+ private FreenetURI getNewUsk(FreenetURI uri) throws DAOException, DuplicateKeyException {
+ if (uri == null)
+ return null;
+
+ final FreenetURI newUri = updateUsk(uri);
+ if (newUri != null && !newUri.equals(uri)) {
+ plugin.log(String.format("received new uri: %s", newUri), 1);
+
+ // new usk already exists, delete the old
+ if (plugin.uriPropsDAO.exist(newUri)) {
+ plugin.log(String.format("remove uri as duplicate: %s", newUri), 1);
+ plugin.removeUriAndFiles(uriValue);
+ throw new DuplicateKeyException();
+ }
+
+ uriValue.setUri(newUri);
+ uriValue.setBlockCount(-1);
+ plugin.uriPropsDAO.update(uriValue);
+
+ return newUri;
+ }
+
+ return uri;
+ }
+
+ /**
+ * Every day this methode checks if the top block is fetchable.
+ * If it cant be fetched, it tries to insert it again.
+ */
+ private void checkTopBlockAndRepair(FreenetURI uri) throws DAOException {
+ // get url without any meta informations or ssk key with minus edition
+ final FreenetURI topBlockUri = Client.normalizeUri(uri.clone());
+
+ // check only every day
+ if (plugin.databaseDAO.lastAccessDiff(topBlockUri) <= TimeUnit.DAYS.toMillis(1))
+ return;
+
+ try {
+ Client.fetch(topBlockUri, plugin.getFreenetClient());
+ } catch (final FetchException e) {
+ log(e.getShortMessage(), 0, 0);
+
+ try {
+ // there was a problem fetching the top block, so we try to insert it again
+ final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(topBlockUri);
+ FreenetURI insertUri = null;
+ if (databaseBlock != null) {
+ insertUri = Client.insert(topBlockUri, databaseBlock.getData(), plugin.getFreenetClient());
+
+ if (insertUri != null) {
+ if (topBlockUri.equals(insertUri)) {
+ log("Successfully inserted top block: " + insertUri.toString(), 0);
+ } else {
+ log("Top block insertion failed - different uri: " + insertUri.toString(), 0);
+ }
+ } else {
+ log("Top block insertion failed (insertUri = null)", 0);
+ }
+ } else {
+ log("Top block insertion failed (no saved block)", 0);
+ }
+ } catch (final InsertException e1) {
+ log(e1.getMessage(), 0, 0);
+ }
+ }
+
+ plugin.databaseDAO.lastAccessUpdate(topBlockUri);
+ }
+
private FetchBlocksResult fetchBlocks(List requestedBlocks, Segment segment) {
final ExecutorService executor = Executors.newFixedThreadPool(plugin.getIntProp(PropertiesKey.POWER));
+
final FetchBlocksResult fetchBlocksResult = new FetchBlocksResult();
try {
- Stream> futures = requestedBlocks.stream().map(requestedBlock -> executor.submit(new SingleFetch(this, requestedBlock, true)));
+ final List tasks = requestedBlocks.stream().map(requestedBlock -> new SingleFetch(this, requestedBlock)).collect(Collectors.toList());
+ final List> results = executor.invokeAll(tasks, 1, TimeUnit.HOURS);
+ for (final Future future : results)
+ fetchBlocksResult.addResult(future.get());
+
executor.shutdown();
final boolean done = executor.awaitTermination(1, TimeUnit.HOURS);
if (!done) {
log(segment, "availability check failed", 0);
- return null;
+ return fetchBlocksResult;
}
-
- futures.forEach(x -> {
- try {
- fetchBlocksResult.addResult(x.get());
- } catch (InterruptedException | ExecutionException e) {
- fetchBlocksResult.addResult(false);
- plugin.log("Reinserter.fetchBlocks(): " + e.getMessage(), e);
- }
- });
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
- return null;
+ } catch (final ExecutionException e) {
+ plugin.log("Error fetchBlocks", e);
} finally {
if (!executor.isShutdown())
executor.shutdownNow();
@@ -599,7 +620,7 @@ private FetchBlocksResult fetchBlocks(List requestedBlocks, Segment segm
return fetchBlocksResult;
}
-
+
private void checkFinishedSegments() throws DAOException {
int segment;
while ((segment = uriValue.getSegment()) < segments.size() - 1) {
@@ -613,7 +634,7 @@ private void checkFinishedSegments() throws DAOException {
}
private void parseMetadata(FreenetURI uri, Metadata metadata, int level)
- throws FetchFailedException, MetadataParseException, FetchException, IOException {
+ throws FetchFailedException, MetadataParseException, FetchException, IOException, DAOException {
if (isInterrupted()) {
return;
}
@@ -625,9 +646,9 @@ private void parseMetadata(FreenetURI uri, Metadata metadata, int level)
if (metadata == null) {
final FetchResult fetchResult = Client.fetch(uri, plugin.getFreenetClient());
- final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(uri.toString());
+ final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(uri);
if (databaseBlock == null) {
- plugin.databaseDAO.create(uri.toString(), fetchResult.asByteArray());
+ plugin.databaseDAO.create(uri, fetchResult.asByteArray());
} else {
databaseBlock.setData(fetchResult.asByteArray());
plugin.databaseDAO.update(databaseBlock);
@@ -900,15 +921,18 @@ private FreenetURI updateUsk(FreenetURI uri) {
return uri;
}
+ /**
+ * Checks if a uri is already registered as manifest
+ */
private void registerManifestUri(FreenetURI uri, int level) {
- uri = Client.normalizeUri(uri);
- if (manifestURIs.containsKey(uri)) {
+ // get url without any meta informations or ssk key with minus edition
+ final FreenetURI normalizeUri = Client.normalizeUri(uri.clone());
+ if (manifestURIs.contains(normalizeUri)) {
log("-> already registered manifest", level, 2);
} else {
- manifestURIs.put(uri, null);
- if (level != -1) {
+ manifestURIs.add(normalizeUri);
+ if (level != -1)
log("-> registered manifest", level, 2);
- }
}
}
@@ -1010,7 +1034,7 @@ public void log(int segmentId, String message, int level, int logLevel) {
}
} catch (final Exception ex) {/* ignore */}
- plugin.logFile(plugin.getLogFilename(uriValue), buf.append(message).toString(), logLevel);
+ plugin.logFile(logFilename, buf.append(message).toString(), logLevel);
}
public void log(Segment segment, String message, int level, int logLevel) {
diff --git a/src/keepalive/urivalues/IUriValue.java b/src/keepalive/urivalues/IUriValue.java
index afba795..7f538e6 100644
--- a/src/keepalive/urivalues/IUriValue.java
+++ b/src/keepalive/urivalues/IUriValue.java
@@ -1,6 +1,5 @@
package keepalive.urivalues;
-import java.net.MalformedURLException;
import java.util.Map;
import freenet.keys.FreenetURI;
@@ -14,14 +13,6 @@ public interface IUriValue {
void setUri(FreenetURI uri);
- String getUriString();
-
- void setUriString(String uri) throws MalformedURLException;
-
- String getShortUri();
-
- void setShortUri(String shortUri);
-
int getBlockCount();
void setBlockCount(int blocks);
@@ -46,4 +37,13 @@ public interface IUriValue {
void setSegment(int segment);
+ default String getShortUri() {
+ FreenetURI uri = getUri();
+ if (uri == null)
+ return "";
+
+ String strUri = uri.toString();
+ return strUri.substring(0, 20) + "...." + strUri.substring(strUri.length() - 50);
+ }
+
}
diff --git a/src/keepalive/urivalues/impl/PropertiesUriValuesDAO.java b/src/keepalive/urivalues/impl/PropertiesUriValuesDAO.java
index a7b0742..366b0b6 100644
--- a/src/keepalive/urivalues/impl/PropertiesUriValuesDAO.java
+++ b/src/keepalive/urivalues/impl/PropertiesUriValuesDAO.java
@@ -47,7 +47,7 @@ public IUriValue create(FreenetURI uri) throws DAOException {
final IUriValue uriProps = new UriValue(getNewUriId(), uri);
final int uriId = uriProps.getUriId();
- setProp(PropertiesKey.URI, uriId, uriProps.getUriString());
+ setProp(PropertiesKey.URI, uriId, uriProps.getUri().toString());
setIntProp(PropertiesKey.BLOCKS, uriId, uriProps.getBlockCount());
setProp(PropertiesKey.SUCCESS, uriId, uriProps.getSuccess());
setIntProp(PropertiesKey.SEGMENT, uriId, uriProps.getSegment());
@@ -67,7 +67,7 @@ public UriValue read(int uriId) throws DAOException {
try {
final UriValue uriValue = new UriValue(uriId);
- uriValue.setUriString(getProp(PropertiesKey.URI, uriId));
+ uriValue.setUri(new FreenetURI(getProp(PropertiesKey.URI, uriId)));
uriValue.setBlockCount(getIntProp(PropertiesKey.BLOCKS, uriId));
loadBlockUris(uriValue);
uriValue.setSuccessSegments(getProp(PropertiesKey.SUCCESS_SEGMENTS, uriId));
@@ -87,12 +87,11 @@ public UriValue read(int uriId) throws DAOException {
public void update(IUriValue uriValue) throws DAOException {
if (uriValue == null)
throw new DAOException("The uriValue need to be not null!");
-
if (!exist(uriValue.getUri()))
throw new DAOException("The uri: '%s' doesnt exist", uriValue.getUri());
final int uriId = uriValue.getUriId();
- setProp(PropertiesKey.URI, uriId, uriValue.getUriString());
+ setProp(PropertiesKey.URI, uriId, uriValue.getUri().toString());
saveBlockUris(uriValue);
setIntProp(PropertiesKey.BLOCKS, uriId, uriValue.getBlocks().size() > 0 ? uriValue.getBlocks().size() : uriValue.getBlockCount());
setProp(PropertiesKey.SUCCESS_SEGMENTS, uriId, uriValue.getSuccessSegments());
@@ -139,7 +138,7 @@ public boolean exist(FreenetURI freenetUri) throws DAOException {
public List getAll() throws DAOException {
return getAllUriIds().parallelStream()
.map(this::readUnchecked)
- .filter(x -> x != null && x.getUriString() != null)
+ .filter(x -> x != null && x.getUri() != null)
.collect(Collectors.toList());
}
@@ -195,7 +194,7 @@ private void saveBlockUris(IUriValue uriValue) throws DAOException {
final List content = uriValue.getBlocks().values().stream().map(this::convertLine).collect(Collectors.toList());
try {
- OpenOption openOption = Files.exists(fileName) ? StandardOpenOption.WRITE : StandardOpenOption.CREATE;
+ final OpenOption openOption = Files.exists(fileName) ? StandardOpenOption.WRITE : StandardOpenOption.CREATE;
Files.write(fileName, content, StandardCharsets.UTF_8, openOption, StandardOpenOption.TRUNCATE_EXISTING);
} catch (final Exception e) {
throw new DAOException("Error saving blocks for: %s", e, uriValue.getUri());
@@ -217,12 +216,12 @@ private void loadBlockUris(IUriValue uriValue) throws DAOException {
throw new DAOException("Error loading blocks for: %s", e, uriValue.getUri());
}
}
-
+
private String convertLine(IBlock block) {
final String type = block.isDataBlock() ? "d" : "c";
- String msg = String.format("%s#%s#%s#%s", block.getUri(), block.getSegmentId(), block.getId(), type);
+ final String msg = String.format("%s#%s#%s#%s", block.getUri(), block.getSegmentId(), block.getId(), type);
if (msg.startsWith("HK"))
- plugin.log("convertLine: %s | %s", block.getUri(), msg);
+ plugin.logF("convertLine: %s | %s", block.getUri(), msg);
return msg;
}
diff --git a/src/keepalive/urivalues/impl/UriValue.java b/src/keepalive/urivalues/impl/UriValue.java
index 6f677bc..246d780 100644
--- a/src/keepalive/urivalues/impl/UriValue.java
+++ b/src/keepalive/urivalues/impl/UriValue.java
@@ -1,6 +1,5 @@
package keepalive.urivalues.impl;
-import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -20,8 +19,6 @@ public class UriValue implements IUriValue {
/** the freenet uri */
private FreenetURI uri = null;
- /** the short freenet uri for html display */
- private String shortUri = "";
/** block count or -1 if its need to be fetched */
private int blockCount = -1;
/** TODO */
@@ -57,32 +54,6 @@ public FreenetURI getUri() {
@Override
public void setUri(FreenetURI uri) {
this.uri = uri;
-
- final String uriString = getUriString();
- if (uriString.length() > 80)
- this.shortUri = uriString.substring(0, 20) + "...." + uriString.substring(uriString.length() - 50);
- else
- this.shortUri = uriString;
- }
-
- @Override
- public String getUriString() {
- return uri != null ? uri.toString() : null;
- }
-
- @Override
- public void setUriString(String uri) throws MalformedURLException {
- setUri(new FreenetURI(uri));
- }
-
- @Override
- public String getShortUri() {
- return shortUri;
- }
-
- @Override
- public void setShortUri(String shortUri) {
- this.shortUri = shortUri;
}
@Override
@@ -147,13 +118,13 @@ public void setSegment(int segment) {
@Override
public String toString() {
- return String.format("UriValue [uriId=%s, uri=%s, shortUri=%s, blockCount=%s, blocks=%s, successSegments=%s, success=%s, history=%s, segment=%s]", uriId, uri, shortUri, blockCount, blocks,
- successSegments, success, history, segment);
+ return String.format("UriValue [uriId=%s, uri=%s, blockCount=%s, blocks=%s, successSegments=%s, success=%s, history=%s, segment=%s]", uriId, uri, blockCount, blocks, successSegments, success,
+ history, segment);
}
@Override
public int hashCode() {
- return Objects.hash(blockCount, blocks, history, segment, shortUri, success, successSegments, uri, uriId);
+ return Objects.hash(blockCount, blocks, history, segment, success, successSegments, uri, uriId);
}
@Override
@@ -163,8 +134,8 @@ public boolean equals(Object obj) {
if ((obj == null) || (getClass() != obj.getClass()))
return false;
final UriValue other = (UriValue) obj;
- return blockCount == other.blockCount && Objects.equals(blocks, other.blocks) && Objects.equals(history, other.history) && segment == other.segment && Objects.equals(shortUri, other.shortUri)
- && Objects.equals(success, other.success) && Objects.equals(successSegments, other.successSegments) && Objects.equals(uri, other.uri) && uriId == other.uriId;
+ return blockCount == other.blockCount && Objects.equals(blocks, other.blocks) && Objects.equals(history, other.history) && segment == other.segment && Objects.equals(success, other.success)
+ && Objects.equals(successSegments, other.successSegments) && Objects.equals(uri, other.uri) && uriId == other.uriId;
}
}
diff --git a/src/keepalive/web/AdminPage.java b/src/keepalive/web/AdminPage.java
index 5138a2c..5dc19f1 100644
--- a/src/keepalive/web/AdminPage.java
+++ b/src/keepalive/web/AdminPage.java
@@ -221,7 +221,7 @@ private void sitesBox(List uriValues) throws Exception {
.append("");
for (final IUriValue uriValue : uriValues) {
- final String uri = uriValue.getUriString();
+ final String uri = uriValue.getUri().toString();
final SuccessValues successValues = ownPlugin.getSuccessValues(uriValue);
final int success = successValues.getSuccess();
@@ -294,7 +294,7 @@ private void unsupportedKeysBox(List uriValues) throws Exception {
if (zeroBlockSites.length() > 0)
zeroBlockSites.append("
");
- zeroBlockSites.append(uriValue.getUriString());
+ zeroBlockSites.append(uriValue.getUri().toString());
}
}
@@ -333,9 +333,10 @@ private void removeUri() throws Exception {
final IUriValue uriValue = ownPlugin.uriPropsDAO.read(getIntParam(UiKey.REMOVE));
if (uriValue != null)
ownPlugin.removeUriAndFiles(uriValue);
+
+ ownPlugin.saveProp(true);
}
- // TODO: test this
private void removeWithRegex() throws Exception {
final String regex = getParam(UiKey.REMOVE_REGEX);
if (regex == null || regex.trim().isEmpty()) {
@@ -345,7 +346,7 @@ private void removeWithRegex() throws Exception {
for (final IUriValue uriValue : ownPlugin.uriPropsDAO.getAll()) {
try {
- final String uri = uriValue.getUriString();
+ final String uri = uriValue.getUri().toString();
if (uri.matches(regex)) {
ownPlugin.removeUriAndFiles(uriValue);
}
@@ -353,12 +354,15 @@ private void removeWithRegex() throws Exception {
log("AdminPage.removeWithRegex(): " + e.getMessage());
}
}
+
+ ownPlugin.saveProp(true);
}
private void removeAllUris() throws DAOException {
- for (final IUriValue uriValue : ownPlugin.uriPropsDAO.getAll()) {
+ for (final IUriValue uriValue : ownPlugin.uriPropsDAO.getAll())
ownPlugin.removeUriAndFiles(uriValue);
- }
+
+ ownPlugin.saveProp(true);
}
private void setIntPropByParam(PropertiesKey cPropName, int nMinValue) {
diff --git a/src/pluginbase/PageBase.java b/src/pluginbase/PageBase.java
index d053698..924fb9d 100644
--- a/src/pluginbase/PageBase.java
+++ b/src/pluginbase/PageBase.java
@@ -252,7 +252,7 @@ public void log(String strText) {
}
public void log(String strText, Object... args) {
- plugin.log(strText, args);
+ plugin.logF(strText, args);
}
// methods to add this page to the plugins' menu (fproxy)
diff --git a/src/pluginbase/PluginBase.java b/src/pluginbase/PluginBase.java
index 865214c..8491def 100644
--- a/src/pluginbase/PluginBase.java
+++ b/src/pluginbase/PluginBase.java
@@ -364,7 +364,7 @@ public void log(String cText) {
logFile("log.txt", cText, 0);
}
- public void log(String cText, Object... args) {
+ public void logF(String cText, Object... args) {
logFile("log.txt", String.format(cText, args), 0);
}
From 5a2c696fc7afac99a2d4f744842929938959e4e6 Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Wed, 21 Dec 2022 18:19:06 +0100
Subject: [PATCH 3/9] Remove EclipseIDE Stuff
---
.classpath | 12 ------------
.gitignore | 4 ++++
.project | 22 ----------------------
3 files changed, 4 insertions(+), 34 deletions(-)
delete mode 100644 .classpath
delete mode 100644 .project
diff --git a/.classpath b/.classpath
deleted file mode 100644
index 4be791f..0000000
--- a/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
index edae0ad..74e95db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,8 @@ build/
.gradle/
.idea/
*.iml
+
+# Eclipse IDE stuff
/.settings
+/.project
+/.classpath
diff --git a/.project b/.project
deleted file mode 100644
index 893ab4e..0000000
--- a/.project
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
- plugin-KeepAlive
-
-
-
- org.eclipse.jdt.core.javanature
- org.eclipse.buildship.core.gradleprojectnature
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
- org.eclipse.buildship.core.gradleprojectbuilder
-
-
-
-
-
-
From dbc935eaae68417c973f05fa6332226754614a18 Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 3 Jan 2023 15:11:17 +0100
Subject: [PATCH 4/9] fix error with 1495 because negative maxsize on fetch;
getStacktrace close stream
---
src/keepalive/Plugin.java | 14 +++++++++-----
src/keepalive/service/net/Client.java | 2 +-
src/pluginbase/PluginBase.java | 11 +++++++----
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/keepalive/Plugin.java b/src/keepalive/Plugin.java
index 41fec9e..e80f979 100644
--- a/src/keepalive/Plugin.java
+++ b/src/keepalive/Plugin.java
@@ -19,6 +19,9 @@
package keepalive;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -276,10 +279,11 @@ public void removeUriAndFiles(IUriValue uriValue) {
}
// remove log files
- final File file = new File(getPluginDirectory() + getLogFilename(uriValue));
- if (file.exists() && !file.delete()) {
- log("Plugin.removeUriAndFiles(): remove log files was not successful.", 1);
- return;
+ try {
+ final File file = new File(getPluginDirectory(), getLogFilename(uriValue));
+ Files.deleteIfExists(file.toPath());
+ } catch (Exception e) {
+ log("Plugin.removeUriAndFiles(): remove log files was not successful.", e);
}
try {
@@ -289,7 +293,7 @@ public void removeUriAndFiles(IUriValue uriValue) {
// remove items
uriPropsDAO.delete(uriValue.getUriId());
} catch (final DAOException e) {
- log("Can't delete uriValues", e);
+ log("Plugin.removeUriAndFiles(): Can't delete uriValues", e);
}
}
diff --git a/src/keepalive/service/net/Client.java b/src/keepalive/service/net/Client.java
index 6475dfa..4a61906 100644
--- a/src/keepalive/service/net/Client.java
+++ b/src/keepalive/service/net/Client.java
@@ -42,7 +42,7 @@ public static FetchResult fetch(FreenetURI uri, HighLevelSimpleClientImpl hlsc)
final FetchContext fetchContext = hlsc.getFetchContext();
fetchContext.returnZIPManifests = true;
final FetchWaiter fetchWaiter = new FetchWaiter(rc);
- hlsc.fetch(uri, -1, fetchWaiter, fetchContext);
+ hlsc.fetch(uri, Long.MAX_VALUE, fetchWaiter, fetchContext); // TODO/FIXME: after Fred update (>1495) Long.MAX_VALUE to -1 again
return fetchWaiter.waitForCompletion();
}
diff --git a/src/pluginbase/PluginBase.java b/src/pluginbase/PluginBase.java
index 8491def..a4e431c 100644
--- a/src/pluginbase/PluginBase.java
+++ b/src/pluginbase/PluginBase.java
@@ -385,10 +385,13 @@ public void log(String info, Throwable e, Object... args) {
}
private String stackTraceToString(Throwable e) {
- final StringWriter sw = new StringWriter();
- final PrintWriter pw = new PrintWriter(sw);
- e.printStackTrace(pw);
- return sw.toString();
+ try (final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw)) {
+ e.printStackTrace(pw);
+ return sw.toString();
+ } catch (IOException e1) {
+ return String.format("Error in stackTraceToString: %s", e1.getMessage());
+ }
}
protected void clearLog() {
From ec04c726632e38bd82cddc10274a125de260c110 Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 3 Jan 2023 15:11:55 +0100
Subject: [PATCH 5/9] explanation of the two options
---
build.gradle | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/build.gradle b/build.gradle
index de37587..7cbd573 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,8 +16,12 @@ configurations {
}
dependencies {
+ // Option 1: use source code, you need to uncomment the two lines in the settings.gradle file
//compile project(':fred')
+
+ // Option 2: use JAR
compile files('../fred/build/libs/freenet.jar')
+
// only used for TarInputStream
compile group: 'org.apache.ant', name: 'ant', version: '1.10.12'
extraLibs group: 'com.h2database', name: 'h2', version: '2.0.206'
From 6d89944fce4ca2606c3dec5c27cda9b321f5ed2f Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 3 Jan 2023 15:46:08 +0100
Subject: [PATCH 6/9] return on error
---
src/keepalive/Plugin.java | 5 ++---
src/keepalive/urivalues/IUriValue.java | 4 ++--
src/pluginbase/PluginBase.java | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/keepalive/Plugin.java b/src/keepalive/Plugin.java
index e80f979..fbcb3fc 100644
--- a/src/keepalive/Plugin.java
+++ b/src/keepalive/Plugin.java
@@ -19,9 +19,7 @@
package keepalive;
import java.io.File;
-import java.io.IOException;
import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -282,8 +280,9 @@ public void removeUriAndFiles(IUriValue uriValue) {
try {
final File file = new File(getPluginDirectory(), getLogFilename(uriValue));
Files.deleteIfExists(file.toPath());
- } catch (Exception e) {
+ } catch (final Exception e) {
log("Plugin.removeUriAndFiles(): remove log files was not successful.", e);
+ return;
}
try {
diff --git a/src/keepalive/urivalues/IUriValue.java b/src/keepalive/urivalues/IUriValue.java
index 7f538e6..429c0ca 100644
--- a/src/keepalive/urivalues/IUriValue.java
+++ b/src/keepalive/urivalues/IUriValue.java
@@ -38,11 +38,11 @@ public interface IUriValue {
void setSegment(int segment);
default String getShortUri() {
- FreenetURI uri = getUri();
+ final FreenetURI uri = getUri();
if (uri == null)
return "";
- String strUri = uri.toString();
+ final String strUri = uri.toString();
return strUri.substring(0, 20) + "...." + strUri.substring(strUri.length() - 50);
}
diff --git a/src/pluginbase/PluginBase.java b/src/pluginbase/PluginBase.java
index a4e431c..fcd341e 100644
--- a/src/pluginbase/PluginBase.java
+++ b/src/pluginbase/PluginBase.java
@@ -389,7 +389,7 @@ private String stackTraceToString(Throwable e) {
final PrintWriter pw = new PrintWriter(sw)) {
e.printStackTrace(pw);
return sw.toString();
- } catch (IOException e1) {
+ } catch (final IOException e1) {
return String.format("Error in stackTraceToString: %s", e1.getMessage());
}
}
From dbcacd8dda0a39b5acd790ad6b9cf49b65ada6de Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 3 Jan 2023 15:54:50 +0100
Subject: [PATCH 7/9] use source code
---
README.md | 1 +
build.gradle | 6 +++---
settings.gradle | 4 ++--
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 323396f..064de68 100644
--- a/README.md
+++ b/README.md
@@ -18,4 +18,5 @@ If you would like to use Eclipse than import the project as "Existing Gradle Pro
- project specific
- specific gradle version to 4.10.3
- set gradle "Java home" to "*\Eclipse Adoptium\jdk8*" without "\bin"
+
Also you need to import "Fred" and do the same
diff --git a/build.gradle b/build.gradle
index 7cbd573..01dd5e8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,11 +16,11 @@ configurations {
}
dependencies {
- // Option 1: use source code, you need to uncomment the two lines in the settings.gradle file
- //compile project(':fred')
+ // Option 1: use source code
+ compile project(':fred')
// Option 2: use JAR
- compile files('../fred/build/libs/freenet.jar')
+ //compile files('../fred/build/libs/freenet.jar')
// only used for TarInputStream
compile group: 'org.apache.ant', name: 'ant', version: '1.10.12'
diff --git a/settings.gradle b/settings.gradle
index 50f6f71..39a8982 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
-//include ':fred'
-//project(':fred').projectDir = new File('../fred')
\ No newline at end of file
+include ':fred'
+project(':fred').projectDir = new File('../fred')
\ No newline at end of file
From 38b9b1aa30b62dd4abfe0c363eb6a18b1c384a44 Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 3 Jan 2023 17:28:23 +0100
Subject: [PATCH 8/9] free log file before deleting; MAX_SIZE for Blocks, some
keys are bigger
---
src/keepalive/Plugin.java | 4 +++-
src/keepalive/repository/IDatabaseBlock.java | 2 ++
src/keepalive/repository/impl/H2DatabaseDAO.java | 12 +++++++-----
src/keepalive/service/reinserter/Reinserter.java | 10 ++++++++--
src/pluginbase/PluginBase.java | 14 ++++++++++++--
5 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/keepalive/Plugin.java b/src/keepalive/Plugin.java
index fbcb3fc..7ffba35 100644
--- a/src/keepalive/Plugin.java
+++ b/src/keepalive/Plugin.java
@@ -278,7 +278,9 @@ public void removeUriAndFiles(IUriValue uriValue) {
// remove log files
try {
- final File file = new File(getPluginDirectory(), getLogFilename(uriValue));
+ String fileName = getLogFilename(uriValue);
+ removeLogFromMap(fileName);
+ final File file = new File(getPluginDirectory(), fileName);
Files.deleteIfExists(file.toPath());
} catch (final Exception e) {
log("Plugin.removeUriAndFiles(): remove log files was not successful.", e);
diff --git a/src/keepalive/repository/IDatabaseBlock.java b/src/keepalive/repository/IDatabaseBlock.java
index 2ea0f26..fc8678e 100644
--- a/src/keepalive/repository/IDatabaseBlock.java
+++ b/src/keepalive/repository/IDatabaseBlock.java
@@ -4,6 +4,8 @@
public interface IDatabaseBlock {
+ static final int MAX_SIZE = 32768;
+
FreenetURI getUri();
void setUri(FreenetURI uri);
diff --git a/src/keepalive/repository/impl/H2DatabaseDAO.java b/src/keepalive/repository/impl/H2DatabaseDAO.java
index ab13f2a..77496c3 100644
--- a/src/keepalive/repository/impl/H2DatabaseDAO.java
+++ b/src/keepalive/repository/impl/H2DatabaseDAO.java
@@ -86,10 +86,10 @@ public synchronized Connection getConnection() throws DatabaseException {
public void pluginStart() {
try (Connection connection = getConnection();
Statement statement = connection.createStatement()) {
- final String sql = "CREATE TABLE IF NOT EXISTS Block (" +
+ final String sql = String.format("CREATE TABLE IF NOT EXISTS Block (" +
"uri VARCHAR(256) PRIMARY KEY, " +
- "data VARBINARY(32768) not null, " +
- "last_access TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
+ "data VARBINARY(%s) not null, " +
+ "last_access TIMESTAMP DEFAULT CURRENT_TIMESTAMP)", IDatabaseBlock.MAX_SIZE);
statement.executeUpdate(sql);
} catch (final Exception e) {
plugin.log(e.getMessage(), e);
@@ -119,10 +119,12 @@ private void upgradeDB() throws DatabaseException {
@Override
public IDatabaseBlock create(FreenetURI uri, byte[] data) throws DAOException {
- if (data == null)
- throw new DAOException("The data need to be not null!");
if (exist(uri))
throw new DAOException("The block uri: '%s' is already saved", uri);
+ if (data == null)
+ throw new DAOException("The data need to be not null for block uri: %s", uri);
+ if (data.length > IDatabaseBlock.MAX_SIZE)
+ throw new DAOException("The data is bigger (size: %s) as allowed for block uri: %s", data.length, uri);
IDatabaseBlock result = null;
diff --git a/src/keepalive/service/reinserter/Reinserter.java b/src/keepalive/service/reinserter/Reinserter.java
index 4fe216f..20b4dff 100644
--- a/src/keepalive/service/reinserter/Reinserter.java
+++ b/src/keepalive/service/reinserter/Reinserter.java
@@ -645,12 +645,18 @@ private void parseMetadata(FreenetURI uri, Metadata metadata, int level)
// constructs top level simple manifest (= first action on a new uri)
if (metadata == null) {
final FetchResult fetchResult = Client.fetch(uri, plugin.getFreenetClient());
+ byte[] fetchBytes = fetchResult.asByteArray();
+
+ if (fetchBytes.length > IDatabaseBlock.MAX_SIZE) {
+ log("parseMetadata: block is to big", level);
+ return;
+ }
final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(uri);
if (databaseBlock == null) {
- plugin.databaseDAO.create(uri, fetchResult.asByteArray());
+ plugin.databaseDAO.create(uri, fetchBytes);
} else {
- databaseBlock.setData(fetchResult.asByteArray());
+ databaseBlock.setData(fetchBytes);
plugin.databaseDAO.update(databaseBlock);
}
diff --git a/src/pluginbase/PluginBase.java b/src/pluginbase/PluginBase.java
index fcd341e..9e9149f 100644
--- a/src/pluginbase/PluginBase.java
+++ b/src/pluginbase/PluginBase.java
@@ -266,18 +266,28 @@ private void loadProp() {
// log files
private synchronized void initLog(String strFilename) {
try {
-
if (!mLogFiles.containsKey(strFilename)) {
final RandomAccessFile file = new RandomAccessFile(strPath + "/" + strFilename, "rw");
file.seek(file.length());
mLogFiles.put(strFilename, file);
}
-
} catch (final IOException e) {
log("PluginBase.initLog() - file: %s", e, strFilename);
}
}
+ protected synchronized void removeLogFromMap(String strFilename) {
+ try {
+ 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 {
From 58033855a0075efe632d5a8163f71ed168359b7e Mon Sep 17 00:00:00 2001
From: PlantEater <113092912+ThePlantEater@users.noreply.github.com>
Date: Tue, 23 Apr 2024 19:30:51 +0200
Subject: [PATCH 9/9] 0.3.4.3-PlantEater - not commited code from long ago
---
settings.gradle | 2 +-
src/keepalive/Plugin.java | 4 +-
src/keepalive/model/PropertiesKey.java | 2 +-
src/keepalive/model/Segment.java | 12 ++-
src/keepalive/repository/IDatabaseBlock.java | 2 +-
src/keepalive/service/net/Client.java | 11 ++-
.../service/reinserter/Reinserter.java | 88 +++++++++----------
src/keepalive/web/AdminPage.java | 65 ++++----------
src/pluginbase/PluginBase.java | 4 +-
src/resources/static/style.css | 8 ++
src/resources/templates/overview_table.html | 12 +++
src/resources/templates/url_entry.html | 15 ++++
12 files changed, 116 insertions(+), 109 deletions(-)
create mode 100644 src/resources/templates/overview_table.html
create mode 100644 src/resources/templates/url_entry.html
diff --git a/settings.gradle b/settings.gradle
index 39a8982..bc1b41f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
include ':fred'
-project(':fred').projectDir = new File('../fred')
\ No newline at end of file
+project(':fred').projectDir = new File('../fred')
diff --git a/src/keepalive/Plugin.java b/src/keepalive/Plugin.java
index 7ffba35..785b9f9 100644
--- a/src/keepalive/Plugin.java
+++ b/src/keepalive/Plugin.java
@@ -42,7 +42,7 @@
*/
public class Plugin extends PluginBase {
- public static final String VERSION = "0.3.4.0-PlantEater";
+ public static final String VERSION = "0.3.4.3-PlantEater";
public static final String PLUGIN_NAME = "KeepAlive";
private Thread reinserterRunner;
@@ -278,7 +278,7 @@ public void removeUriAndFiles(IUriValue uriValue) {
// remove log files
try {
- String fileName = getLogFilename(uriValue);
+ final String fileName = getLogFilename(uriValue);
removeLogFromMap(fileName);
final File file = new File(getPluginDirectory(), fileName);
Files.deleteIfExists(file.toPath());
diff --git a/src/keepalive/model/PropertiesKey.java b/src/keepalive/model/PropertiesKey.java
index 4db7162..6f4dbbb 100644
--- a/src/keepalive/model/PropertiesKey.java
+++ b/src/keepalive/model/PropertiesKey.java
@@ -36,7 +36,7 @@ public enum PropertiesKey {
LOG_LINKS("log_links", 1),
LOG_UTC("log_utc", 1),
SINGLE_URL_TIMESLOT("single_url_timeslot", 4),
- STACKTRACE("stackTrace", "false"),
+ STACKTRACE("stackTrace", "true"),
// uri specific
URI("uri"),
diff --git a/src/keepalive/model/Segment.java b/src/keepalive/model/Segment.java
index 7bcc85c..d5ad1c4 100644
--- a/src/keepalive/model/Segment.java
+++ b/src/keepalive/model/Segment.java
@@ -41,18 +41,22 @@ public Segment(Reinserter reinserter, int id, int size) {
this.reinserter = reinserter;
this.id = id;
this.size = size;
- this.blocks = new Block[size];
+ this.blocks = new IBlock[size];
}
public IBlock getBlock(int id) {
return blocks[id];
}
- public void addBlock(IBlock block) {
+ public boolean addBlock(IBlock block) {
+ if (block.getId() > size)
+ return false;
+
blocks[block.getId()] = block;
- if (block.isDataBlock()) {
+ if (block.isDataBlock())
dataBlocksCount++;
- }
+
+ return true;
}
public IBlock getDataBlock(int id) {
diff --git a/src/keepalive/repository/IDatabaseBlock.java b/src/keepalive/repository/IDatabaseBlock.java
index fc8678e..13b36df 100644
--- a/src/keepalive/repository/IDatabaseBlock.java
+++ b/src/keepalive/repository/IDatabaseBlock.java
@@ -4,7 +4,7 @@
public interface IDatabaseBlock {
- static final int MAX_SIZE = 32768;
+ int MAX_SIZE = 32768;
FreenetURI getUri();
diff --git a/src/keepalive/service/net/Client.java b/src/keepalive/service/net/Client.java
index 4a61906..a1d966e 100644
--- a/src/keepalive/service/net/Client.java
+++ b/src/keepalive/service/net/Client.java
@@ -35,9 +35,8 @@ public static FetchResult fetch(FreenetURI uri, HighLevelSimpleClientImpl hlsc)
if (uri == null)
return null;
- if (uri.isCHK()) {
+ if (uri.isCHK())
uri.getExtra()[2] = 0; // deactivate control flag
- }
final FetchContext fetchContext = hlsc.getFetchContext();
fetchContext.returnZIPManifests = true;
@@ -52,12 +51,12 @@ public static FreenetURI insert(FreenetURI uri, byte[] data, HighLevelSimpleClie
}
public static FreenetURI normalizeUri(FreenetURI uri) {
- if (uri.isUSK()) {
+ if (uri.isUSK())
uri = uri.sskForUSK();
- }
- if (uri.hasMetaStrings()) {
+
+ if (uri.hasMetaStrings())
uri = uri.setMetaString(null);
- }
+
return uri;
}
diff --git a/src/keepalive/service/reinserter/Reinserter.java b/src/keepalive/service/reinserter/Reinserter.java
index 20b4dff..01bbb2e 100644
--- a/src/keepalive/service/reinserter/Reinserter.java
+++ b/src/keepalive/service/reinserter/Reinserter.java
@@ -104,7 +104,7 @@ public void run() {
try {
// init
- plugin.logF(String.format("start reinserter for site %s (%s)", uri, siteId), 1);
+ plugin.log(String.format("start reinserter for site %s (%s)", uri, siteId), 1);
plugin.clearLog(logFilename);
isActive(true);
long startedAt = System.currentTimeMillis();
@@ -223,10 +223,11 @@ public void run() {
}
final Segment segment = new Segment(this, segments.size(), segmentSize);
for (final IBlock block : uriValue.getBlocks().values()) {
- if (block.getSegmentId() == segments.size()) {
- segment.addBlock(block);
- }
+ // TODO/FIXME: why is that so that the id is bigger than the size?!?
+ if ((block.getSegmentId() == segments.size()) && !segment.addBlock(block))
+ log(String.format("The BlockId: %s is bigger as the segmentSize: %s -> Block skipped!", block.getId(), segmentSize), 2);
}
+
segments.add(segment);
log(segment, "*** segment size: " + segment.size(), 0);
doReinsertions = true;
@@ -561,6 +562,8 @@ private void checkTopBlockAndRepair(FreenetURI uri) throws DAOException {
if (plugin.databaseDAO.lastAccessDiff(topBlockUri) <= TimeUnit.DAYS.toMillis(1))
return;
+ log("checkTopBlockAndRepair", 2);
+
try {
Client.fetch(topBlockUri, plugin.getFreenetClient());
} catch (final FetchException e) {
@@ -633,11 +636,9 @@ private void checkFinishedSegments() throws DAOException {
plugin.uriPropsDAO.update(uriValue);
}
- private void parseMetadata(FreenetURI uri, Metadata metadata, int level)
- throws FetchFailedException, MetadataParseException, FetchException, IOException, DAOException {
- if (isInterrupted()) {
+ private void parseMetadata(FreenetURI uri, Metadata metadata, int level) throws FetchFailedException, MetadataParseException, FetchException, IOException, DAOException {
+ if (isInterrupted())
return;
- }
// register uri
registerBlockUri(uri, true, true, level);
@@ -645,26 +646,28 @@ private void parseMetadata(FreenetURI uri, Metadata metadata, int level)
// constructs top level simple manifest (= first action on a new uri)
if (metadata == null) {
final FetchResult fetchResult = Client.fetch(uri, plugin.getFreenetClient());
- byte[] fetchBytes = fetchResult.asByteArray();
+ final byte[] fetchBytes = fetchResult.asByteArray();
if (fetchBytes.length > IDatabaseBlock.MAX_SIZE) {
- log("parseMetadata: block is to big", level);
- return;
- }
-
- final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(uri);
- if (databaseBlock == null) {
- plugin.databaseDAO.create(uri, fetchBytes);
+ log(String.format("parseMetadata: block is too big (%s) skipped -> Mime: %s", fetchBytes.length, fetchResult.getMimeType()), level);
} else {
- databaseBlock.setData(fetchBytes);
- plugin.databaseDAO.update(databaseBlock);
+ // create or update block
+ final IDatabaseBlock databaseBlock = plugin.databaseDAO.read(uri);
+ if (databaseBlock == null) {
+ plugin.databaseDAO.create(uri, fetchBytes);
+ } else {
+ databaseBlock.setData(fetchBytes);
+ plugin.databaseDAO.update(databaseBlock);
+ }
}
- metadata = fetchManifest(uri, null, null);
+ metadata = fetchManifest(fetchBytes, null, null);
if (metadata == null) {
log("no metadata", level);
return;
}
+
+ log(String.format("parseMetadata: metadata: %s", metadata.dump()), level);
}
// internal manifest (simple manifest)
@@ -847,11 +850,10 @@ private Metadata fetchManifest(FreenetURI uri, ARCHIVE_TYPE archiveType, String
private Metadata fetchManifest(byte[] data, ARCHIVE_TYPE archiveType, String manifestName) throws IOException {
Metadata metadata = null;
+
try (ByteArrayInputStream fetchedDataStream = new ByteArrayInputStream(data)) {
-
- if (manifestName == null) {
+ if (manifestName == null)
manifestName = ".metadata";
- }
if (archiveType == null) {
// try to construct metadata directly
@@ -897,7 +899,6 @@ private Metadata fetchManifest(byte[] data, ARCHIVE_TYPE archiveType, String man
entryName = ((ZipInputStream) inStream).getNextEntry().getName();
}
}
-
} catch (final Exception e) {
if (archiveType != null)
log("unzip and construct metadata: " + e.getMessage(), 0, 2);
@@ -908,10 +909,11 @@ private Metadata fetchManifest(byte[] data, ARCHIVE_TYPE archiveType, String man
if (archiveType != null) {
manifestName += " (" + archiveType.name() + ")";
}
+
metadata.resolve(manifestName);
}
- return metadata;
+ return metadata;
}
}
@@ -943,27 +945,25 @@ private void registerManifestUri(FreenetURI uri, int level) {
}
private void registerBlockUri(FreenetURI uri, boolean newSegment, boolean isDataBlock, int logTabLevel) {
- if (uri != null) { // uri is null if metadata is created from splitfile
-
- // no reinsertion for SSK but go to sublevel
- if (!uri.isCHK()) {
- log("-> no reinsertion of USK, SSK or KSK", logTabLevel, 2);
-
- // check if uri already reinserted during this session
- } else if (uriValue.getBlocks().containsKey(Client.normalizeUri(uri))) {
- log("-> already registered block", logTabLevel, 2);
-
- // register
- } else {
- if (newSegment) {
- parsedSegmentId++;
- parsedBlockId = -1;
- }
- uri = Client.normalizeUri(uri);
- uriValue.getBlocks().put(uri, new Block(uri, parsedSegmentId, ++parsedBlockId, isDataBlock));
- log("-> registered block", logTabLevel, 2);
+ // uri is null if metadata is created from splitfile
+ if (uri == null)
+ return;
+
+ // no reinsertion for SSK but go to sublevel
+ if (!uri.isCHK()) {
+ log("-> no reinsertion of USK, SSK or KSK", logTabLevel, 2);
+ } else if (uriValue.getBlocks().containsKey(Client.normalizeUri(uri))) {
+ // check if uri already reinserted during this session
+ log("-> already registered block", logTabLevel, 2);
+ } else {
+ // register
+ if (newSegment) {
+ parsedSegmentId++;
+ parsedBlockId = -1;
}
-
+ uri = Client.normalizeUri(uri);
+ uriValue.getBlocks().put(uri, new Block(uri, parsedSegmentId, ++parsedBlockId, isDataBlock));
+ log("-> registered block", logTabLevel, 2);
}
}
diff --git a/src/keepalive/web/AdminPage.java b/src/keepalive/web/AdminPage.java
index 5dc19f1..83cfd8b 100644
--- a/src/keepalive/web/AdminPage.java
+++ b/src/keepalive/web/AdminPage.java
@@ -212,14 +212,9 @@ private void logBox() throws Exception {
}
private void sitesBox(List uriValues) throws Exception {
- final StringBuilder html = new StringBuilder(html("add_key", formPassword))
- .append("
")
- .append("| URI | total blocks | ")
- .append("available blocks | missed blocks | ")
- .append("blocks availability | segments availability | ")
- .append("Actions | ")
- .append("
");
+ final StringBuilder html = new StringBuilder(html("add_key", formPassword)).append("
");
+ final StringBuilder htmlEntries = new StringBuilder();
for (final IUriValue uriValue : uriValues) {
final String uri = uriValue.getUri().toString();
@@ -240,48 +235,22 @@ private void sitesBox(List uriValues) throws Exception {
segmentsAvailability = (int) ((double) availableSegments / finishedSegmentsCount * 100);
}
- final String tdAndCenter = "";
- html.append(" | " + "| ")
- .append(uriValue.getShortUri())
- .append("" + tdAndCenter)
- .append(uriValue.getBlocks().size())
- .append(tdAndCenter)
- .append(success)
- .append(tdAndCenter)
- .append(failure)
- .append(tdAndCenter)
- .append(persistence)
- .append(" %" + tdAndCenter)
- .append(segmentsAvailability)
- .append(" % | remove | log | ");
-
- if (uriValue.getUriId() == getIntProp(PropertiesKey.ACTIVE)) {
- html.append("stop | active | ");
- } else {
- html.append("start | | ");
- }
-
- html.append("
");
+ final boolean isActive = uriValue.getUriId() == getIntProp(PropertiesKey.ACTIVE);
+ final String entryHtml = html("url_entry", formPassword)
+ .replace("${url_full}", uri)
+ .replace("${url_short}", uriValue.getShortUri())
+ .replace("${url_blockSize}", Integer.toString(uriValue.getBlocks().size()))
+ .replace("${url_success}", Integer.toString(success))
+ .replace("${url_failure}", Integer.toString(failure))
+ .replace("${url_persistence}", Integer.toString(persistence))
+ .replace("${url_segmentsAvailability}", Integer.toString(segmentsAvailability))
+ .replace("${url_id}", Integer.toString(uriValue.getUriId()))
+ .replace("${url_modus}", isActive ? "stop" : "start")
+ .replace("${url_active}", isActive ? "active" : "");
+ htmlEntries.append(entryHtml);
}
- html.append("
");
+
+ html.append(html("overview_table", formPassword).replace("${url_entries}", htmlEntries.toString()));
addBox("Add or remove a key", html.toString(), "page-kp-keys");
}
diff --git a/src/pluginbase/PluginBase.java b/src/pluginbase/PluginBase.java
index 9e9149f..bd5ff66 100644
--- a/src/pluginbase/PluginBase.java
+++ b/src/pluginbase/PluginBase.java
@@ -130,7 +130,7 @@ public void runPlugin(PluginRespirator pr) { // FredPlugin
@Override
public String getVersion() { // FredPluginVersioned
- return strTitle + " " + strVersion;
+ return strVersion;
}
/**
@@ -278,7 +278,7 @@ private synchronized void initLog(String strFilename) {
protected synchronized void removeLogFromMap(String strFilename) {
try {
- RandomAccessFile fileHandle = mLogFiles.get(strFilename);
+ final RandomAccessFile fileHandle = mLogFiles.get(strFilename);
if (fileHandle != null) {
fileHandle.close();
mLogFiles.remove(strFilename);
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/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} |
+