Update Tiddlywiki Java Saver
Sunday, December 3, 2006 2:39:16 PM
I was poking around the TiddlyWiki Trac site and noticed a new ticket #253 opened on my Java saving code.
Apparently one or more of Gentoo Linux, the Linux JVM, or Opera for Linux require the saving code (and probably the loading code too) to be wrapping in a PrivilegedAction class into order to execute, regardless of Java security policy settings.
The ticket included some code, but sorry "thomaskammeyer", I don't like your style!
Here's my new Java code:
To Jeremy: If you're reading this, the build script needs a small change: The jar command needs to refer to all class files, i.e. "TiddlySaver*.class".
I've tested this on my WinXP machine using the standard policy and it worked fine, but could not test on MacOS or any flavour of Linux.
Apparently one or more of Gentoo Linux, the Linux JVM, or Opera for Linux require the saving code (and probably the loading code too) to be wrapping in a PrivilegedAction class into order to execute, regardless of Java security policy settings.
The ticket included some code, but sorry "thomaskammeyer", I don't like your style!

Here's my new Java code:
import java.io.*;
import java.security.*;
public class TiddlySaver extends java.applet.Applet {
class PrivilegedLoad implements PrivilegedAction {
private String filename;
private String charset;
public PrivilegedLoad(String filename, String charset) {
this.filename = filename;
this.charset = charset;
}
public Object run() {
try {
if (charset.length() == 0) {
StringBuffer data = new StringBuffer();
BufferedReader r = new BufferedReader(new FileReader(filename));
String line;
while ((line = r.readLine()) != null) data.append(line).append("\n");
r.close();
return data.toString();
} else {
File f = new File(filename);
FileInputStream i = new FileInputStream(f);
byte[] b = new byte[(f.length() > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)f.length()];
int offset = 0;
int num = 0;
while (offset < b.length && (num = i.read(b, offset, b.length - offset)) >= 0) {
offset += num;
}
i.close();
return new String(b, 0, offset, charset);
}
} catch (Exception x) {
x.printStackTrace();
return null;
}
}
}
class PrivilegedSave implements PrivilegedAction {
private String filename;
private String charset;
private String data;
public PrivilegedSave(String filename, String charset, String data) {
this.filename = filename;
this.charset = charset;
this.data = data;
}
public Object run() {
try {
File f = new File(filename).getCanonicalFile();
f.getParentFile().mkdirs();
if (charset.length() == 0) {
int e, s = 0;
BufferedWriter w = new BufferedWriter(new FileWriter(f));
do {
e = data.indexOf('\n', s);
if (e == -1) e = data.length();
w.write(data, s, e - s);
w.newLine();
s = e + 1;
} while (s < data.length());
w.close();
return Boolean.TRUE;
} else {
FileOutputStream o = new FileOutputStream(f);
o.write(data.getBytes(charset));
o.close();
return Boolean.TRUE;
}
} catch (Exception x) {
x.printStackTrace();
return Boolean.FALSE;
}
}
}
public String loadFile(String filename, String charset) {
return (String)AccessController.doPrivileged(new PrivilegedLoad(filename, charset));
}
public int saveFile(String filename, String charset, String data) {
return ((Boolean)AccessController.doPrivileged(new PrivilegedSave(filename, charset, data))).booleanValue() ? 1 : 0;
}
}Here's the above compiled into a new JAR: TiddlySaver.jarTo Jeremy: If you're reading this, the build script needs a small change: The jar command needs to refer to all class files, i.e. "TiddlySaver*.class".
I've tested this on my WinXP machine using the standard policy and it worked fine, but could not test on MacOS or any flavour of Linux.









LuanaLuaCaron # Monday, February 25, 2008 12:26:34 AM
I am new to Opera but have been using TiddlyWikis for a long time as lab journals.
I saw your java solution to enable Opera to save TiddlyWikis, but I could not make it work.
I am using Opera 9.36 and TiddlyWiki 2.3.0 on windows XP.
I set the following .java.policy file:
grant codeBase "file:C:/Documents and Settings/Owner/My Documents/wikis/*" { permission java.io.FilePermission "C:${/}Documents and Settings${/}Owner${/}My Documents${/}wikis${/}*", "read,write";
};
Saved on C:/Documents and Settings/Owner.
And put a copy of your TiddlySaver.jar on my wikis folder.
Any clue on what I am missing?
Andrew Gregory # Monday, February 25, 2008 3:36:35 AM
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" { permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder", "read,write"; permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}-", "read,write"; };LuanaLuaCaron # Wednesday, February 27, 2008 3:57:12 PM
It works now, and I guess it was working before, it is just that I was not aware of the 3-min delay...
Thank you!
Andrew Gregory # Thursday, February 28, 2008 2:07:11 AM
LuanaLuaCaron # Friday, February 29, 2008 2:43:13 PM
Andrew Gregory # Saturday, March 1, 2008 2:32:51 AM
1. In the wrong folder (C:\Documents and Settings\your-username-here\)
2. The wrong name (.java.policy) - if you have Windows "hide extensions of known files types" turned on, then the file might really be named ".java.policy.txt". Open your policy file in Notepad, then resave it with double-quotes around the file name. That forces Windows to save using the exact name specified and it won't add a default extension.
3. The policy file data is malformed in some way. eg misplaced curly brace, missing semi-colon, etc. Every permission line must end with a semi-colon and the closing brace of every grant must have a semi-colon after it. See http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html
LuanaLuaCaron # Saturday, March 1, 2008 11:44:11 PM
Thank you very much!
(and sorry for bothering you so many times
Andrew Gregory # Sunday, March 2, 2008 3:20:08 AM