You should put each BookmarkItem as a sub-fieldset, not a string. Then you can 
cleanly extend it and record key, name, etc.

On Tuesday 20 November 2007 19:15, you wrote:
> Author: nextgens
> Date: 2007-11-20 19:15:58 +0000 (Tue, 20 Nov 2007)
> New Revision: 15881
> 
> Modified:
>    trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java
>    trunk/freenet/src/freenet/clients/http/StartupToadletServer.java
>    trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
>    trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java
>    trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java
>    trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java
>    trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java
>    trunk/freenet/src/freenet/node/Node.java
>    trunk/freenet/src/freenet/node/NodeClientCore.java
> Log:
> BookmarkToadlet: Save bookmarks in a different file so that they don't get 
clobbered for no reason anymore.
> 
> THE MIGRATION TOOL DOESN'T WORK... yet.
> 
> Modified: trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java 
2007-11-20 19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java 
2007-11-20 19:15:58 UTC (rev 15881)
> @@ -129,7 +129,7 @@
>                       
actions.addChild("a", "href", "?action=paste&bookmark=/").addChild("img", new 
String[] {"src", "alt", "title"}, new String[] {"/static/icon/paste.png", 
paste, paste});
>  
>               root.addChild(actions);
> -             addCategoryToList(bookmarkManager.getMainCategory(), "/", 
root.addChild("ul"));
> +             addCategoryToList(BookmarkManager.MAIN_CATEGORY, "/", 
root.addChild("ul"));
>  
>               return bookmarks;
>       }
> 
> Modified: trunk/freenet/src/freenet/clients/http/StartupToadletServer.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/StartupToadletServer.java  
2007-11-20 19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/StartupToadletServer.java  
2007-11-20 19:15:58 UTC (rev 15881)
> @@ -118,13 +118,12 @@
>        * Create a SimpleToadletServer, using the settings from the SubConfig 
(the fproxy.*
>        * config).
>        */
> -    public StartupToadletServer(Executor executor, PersistentConfig conf) {
> +    public StartupToadletServer(Executor executor, SimpleFieldSet config) {
>          this.executor = executor;
>          formPassword = String.valueOf(this.getClass().hashCode());
>  
>          // hack ... we don't have the config framework yet
>          try {
> -            SimpleFieldSet config = conf.getSimpleFieldSet();
>              port = config.getInt("fproxy.port");
>              bindTo = config.get("fproxy.bindTo");
>              // Yeah, only FullAccess hosts here, it's on purpose.
> 
> Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java        
> 2007-11-20 
19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java        
> 2007-11-20 
19:15:58 UTC (rev 15881)
> @@ -540,7 +540,8 @@
>  
>               HTMLNode bookmarkBoxContent = 
bookmarkBox.addChild("div", "class", "infobox-content");
>               HTMLNode bookmarksList = 
bookmarkBoxContent.addChild("ul", "id", "bookmarks");
> -             addCategoryToList(bookmarkManager.getMainCategory(), 
> bookmarksList);
> +             addCategoryToList(BookmarkManager.PROTECTED_CATEGORY, 
> bookmarksList);
> +                addCategoryToList(BookmarkManager.MAIN_CATEGORY, 
bookmarksList);
>  
>               // Fetch-a-key box
>               HTMLNode fetchKeyBox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-normal", 
l10n("fetchKeyLabel")));
> 
> Modified: trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java     
> 2007-11-20 
19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java     
> 2007-11-20 
19:15:58 UTC (rev 15881)
> @@ -33,6 +33,7 @@
>               if(o == this) return true;
>               if(o instanceof Bookmark) {
>                       Bookmark b = (Bookmark) o;
> +                        if(b.name == null || b.desc == null) return false;
>                       if(!b.name.equals(name)) return false;
>                       // Compensate for nulls
>                       
> if(!String.valueOf(b.desc).equals(String.valueOf(desc))) return false;
> 
> Modified: 
trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java     
2007-11-20 19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java     
2007-11-20 19:15:58 UTC (rev 15881)
> @@ -1,5 +1,6 @@
>  package freenet.clients.http.bookmark;
>  
> +import freenet.support.SimpleFieldSet;
>  import java.util.Vector;
>  
>  import freenet.support.StringArray;
> @@ -18,6 +19,7 @@
>       }
>  
>       protected synchronized Bookmark addBookmark(Bookmark b) {
> +                if(b == null) return null;
>               int x = bookmarks.indexOf(b);
>               if(x >= 0) return (Bookmark) bookmarks.get(x);
>               bookmarks.add(b);
> @@ -118,6 +120,26 @@
>  
>       }
>  
> +        public SimpleFieldSet toSimpleFieldSet() {
> +            SimpleFieldSet sfs = new SimpleFieldSet(true);
> +
> +            BookmarkItems items = getItems();
> +            for (int i = 0; i < items.size(); i++) {
> +                BookmarkItem item = items.get(i);
> +                sfs.putSingle(String.valueOf(i), item.toString());
> +            }
> +
> +            BookmarkCategories subCategories = getSubCategories();
> +            for (int i = 0; i < subCategories.size(); i++) {
> +                BookmarkCategory category = subCategories.get(i);
> +                SimpleFieldSet toPut = category.toSimpleFieldSet();
> +                if("".equals(category.name) || toPut.isEmpty()) continue;
> +                sfs.put(category.name, toPut);
> +            }
> +
> +            return sfs;
> +        }
> +
>       public void setPrivate(boolean bool) {
>               privateBookmark = bool;
>  
> 
> Modified: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java 
2007-11-20 19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java 
2007-11-20 19:15:58 UTC (rev 15881)
> @@ -10,9 +10,11 @@
>  import freenet.node.useralerts.AbstractUserAlert;
>  import freenet.node.useralerts.UserAlert;
>  import freenet.node.useralerts.UserAlertManager;
> +import freenet.support.Fields;
>  import freenet.support.HTMLEncoder;
>  import freenet.support.HTMLNode;
>  
> +import freenet.support.SimpleFieldSet;
>  import java.net.MalformedURLException;
>  
>  public class BookmarkItem extends Bookmark {
> @@ -42,6 +44,16 @@
>               this.alerts = uam;
>               alert = new BookmarkUpdatedUserAlert();
>       }
> +        
> +        public BookmarkItem(String line, UserAlertManager uam) throws 
MalformedURLException {
> +            String[] result = line.split("###");
> +            this.name = result[0];
> +            this.desc = result[1];
> +            this.hasAnActivelink = Fields.stringToBool(result[2], false);
> +            this.key = new FreenetURI(result[3]);
> +            this.alerts = uam;
> +            this.alert = new BookmarkUpdatedUserAlert();
> +        }
>  
>       private class BookmarkUpdatedUserAlert extends AbstractUserAlert {
>  
> @@ -137,7 +149,7 @@
>       }
>  
>       public String toString() {
> -             return this.name + '=' + (hasAnActivelink ? "|=" : "=") + 
this.key.toString();
> +             return this.name + "###" + this.desc + "###" + 
> this.hasAnActivelink 
+ "###" + this.key.toString();
>       }
>  
>       public synchronized void setEdition(long ed, NodeClientCore node) {
> 
> Modified: 
trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java
> ===================================================================
> --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java      
2007-11-20 19:05:06 UTC (rev 15880)
> +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java      
2007-11-20 19:15:58 UTC (rev 15881)
> @@ -1,7 +1,6 @@
>  /* This code is part of Freenet. It is distributed under the GNU General
>   * Public License, version 2 (or at your option any later version). See
>   * http://www.gnu.org/ for further details of the GPL. */
> -
>  package freenet.clients.http.bookmark;
>  
>  import java.net.MalformedURLException;
> @@ -10,332 +9,390 @@
>  import java.util.regex.Pattern;
>  
>  import freenet.client.async.USKCallback;
> -import freenet.config.InvalidConfigValueException;
> -import freenet.config.SubConfig;
>  import freenet.keys.FreenetURI;
>  import freenet.keys.USK;
>  import freenet.l10n.L10n;
>  import freenet.node.NodeClientCore;
> -import freenet.support.api.StringArrCallback;
> +import freenet.support.Logger;
> +import freenet.support.SimpleFieldSet;
> +import java.io.File;
> +import java.io.FileWriter;
> +import java.io.IOException;
> +import java.util.Iterator;
>  
>  public class BookmarkManager {
>  
> -     private final NodeClientCore node;
> -     private final USKUpdatedCallback uskCB = new USKUpdatedCallback();
> -     private final StringArrCallback configCB = new BookmarkCallback();
> -     private static final BookmarkCategory MAIN_CATEGORY = new 
BookmarkCategory("/");;
> -     private final HashMap bookmarks = new HashMap();
> +    private final NodeClientCore node;
> +    private final USKUpdatedCallback uskCB = new USKUpdatedCallback();
> +    public static final BookmarkCategory MAIN_CATEGORY = new 
BookmarkCategory("/");
> +    public static final BookmarkCategory PROTECTED_CATEGORY = new 
BookmarkCategory("/protected");
> +    private final HashMap bookmarks = new HashMap();
> +    private final File bookmarksFile = new 
File("bookmarks.dat").getAbsoluteFile();
> +    private boolean isSavingBookmarks = false;
>  
> -     public BookmarkManager(NodeClientCore n, SubConfig sc) {
> -             bookmarks.put("/", MAIN_CATEGORY);
> -             this.node = n;
> +    public BookmarkManager(NodeClientCore n, SimpleFieldSet oldConfig) {
> +        bookmarks.put("/", MAIN_CATEGORY);
> +        this.node = n;
>  
> -             try {
> -                     BookmarkCategory defaultRoot = new 
> BookmarkCategory("/");
> -                     BookmarkCategory indexes = (BookmarkCategory) 
defaultRoot.addBookmark(new BookmarkCategory("Indexes"));
> -                     indexes.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> zQyF2O1o8B4y40w7Twz8y2I9haW3d2DTlxjTHPu7zc8,h2mhQNNE9aQvF~2yKAmKV1uorr7141-QOroBf5hrlbw,AQACAAE/AnotherIndex/33/"),
> -                                                     "Another Index (large 
> categorised index, many sites have no 
description)", false,
> -                                                     node.alerts));
> +        try {
> +            BookmarkCategory indexes = (BookmarkCategory) 
PROTECTED_CATEGORY.addBookmark(new BookmarkCategory("Indexes"));
> +            indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
zQyF2O1o8B4y40w7Twz8y2I9haW3d2DTlxjTHPu7zc8,h2mhQNNE9aQvF~2yKAmKV1uorr7141-QOroBf5hrlbw,AQACAAE/AnotherIndex/33/"),
> +                    "Another Index (large categorised index, many sites 
have no description)", false,
> +                    node.alerts));
>  
> -                     indexes.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> RJnh1EnvOSPwOWVRS2nyhC4eIQkKoNE5hcTv7~yY-sM,pOloLxnKWM~AL24iDMHOAvTvCqMlB-p2BO9zK96TOZA,AQACAAE/index_fr/21/"),
> -                                                     "Index des sites 
> Fran?ais (small French index with descriptions)", 
false,
> -                                                     node.alerts));
> +            indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
RJnh1EnvOSPwOWVRS2nyhC4eIQkKoNE5hcTv7~yY-sM,pOloLxnKWM~AL24iDMHOAvTvCqMlB-p2BO9zK96TOZA,AQACAAE/index_fr/21/"),
> +                    "Index des sites Fran?ais (small French index with 
descriptions)", false,
> +                    node.alerts));
>  
> -                     indexes.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> cvZEZFWynx~4hmakaimts4Ruusl9mEUpU6mSvNvZ9p8,K2Xopc6GWPkKrs27EDuqzTcca2bE5H2YAXw0qKnkON4,AQACAAE/TSOF/2/"),
> -                                                     "The Start Of Freenet 
> (another human-maintained index, so far 
relatively small)", true,
> -                                                     node.alerts));
> +            indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
cvZEZFWynx~4hmakaimts4Ruusl9mEUpU6mSvNvZ9p8,K2Xopc6GWPkKrs27EDuqzTcca2bE5H2YAXw0qKnkON4,AQACAAE/TSOF/2/"),
> +                    "The Start Of Freenet (another human-maintained index, 
so far relatively small)", true,
> +                    node.alerts));
>  
> -                     indexes.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> 7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/36/"),
> -                                                     "Entry point (old, 
> large index, hasn't been updated for a while)", 
true,
> -                                                     node.alerts));
> -                     
> -                     indexes.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> 0I8gctpUE32CM0iQhXaYpCMvtPPGfT4pjXm01oid5Zc,3dAcn4fX2LyxO6uCnWFTx-2HKZ89uruurcKwLSCxbZ4,AQACAAE/Ultimate-Freenet-Index/1/"),
> -                                                     "The Ultimate FreeNet 
> Index (new one page index)", false,
> -                                                     node.alerts));
> +            indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/36/"),
> +                    "Entry point (old, large index, hasn't been updated for 
a while)", true,
> +                    node.alerts));
>  
> -                     
> -                     BookmarkCategory flog = (BookmarkCategory) 
> defaultRoot.addBookmark(new 
BookmarkCategory("Freenet devel's flogs"));
> -                     flog.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> yGvITGZzrY1vUZK-4AaYLgcjZ7ysRqNTMfdcO8gS-LY,-ab5bJVD3Lp-LXEQqBAhJpMKrKJ19RnNaZMIkusU79s,AQACAAE/toad/7/"),
> -                                                     "Toad", true, 
> node.alerts));
> -                     flog.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> hM9XRwjXIzU8xTSBXNZvTn2KuvTSRFnVn4EER9FQnpM,gsth24O7ud4gL4NwNuYJDUqfaWASOG2zxZY~ChtgPxc,AQACAAE/Flog/7/"),
> -                                                     "Nextgen$", true, 
> node.alerts));
> +            indexes.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
0I8gctpUE32CM0iQhXaYpCMvtPPGfT4pjXm01oid5Zc,3dAcn4fX2LyxO6uCnWFTx-2HKZ89uruurcKwLSCxbZ4,AQACAAE/Ultimate-Freenet-Index/1/"),
> +                    "The Ultimate FreeNet Index (new one page index)", 
false,
> +                    node.alerts));
>  
> -                     BookmarkCategory apps = (BookmarkCategory) 
> defaultRoot.addBookmark(new 
BookmarkCategory("Freenet related software"));
> -                     apps.addBookmark(new BookmarkItem(
> -                                     new FreenetURI(
> -                                                     "USK at 
> QRZAI1nSm~dAY2hTdzVWXmEhkaI~dso0OadnppBR7kE,wq5rHGBI7kpChBe4yRmgBChIGDug7Xa5SG9vYGXdxR0,AQACAAE/frost/4"),
> -                                                     "Frost", true, 
> node.alerts));
>  
> -                     sc.register("bookmarks", defaultRoot.toStrings(), 0, 
> true, 
false,"BookmarkManager.list", "BookmarkManager.listLong", configCB);
> -                     configCB.set(sc.getStringArr("bookmarks"));
> -             } catch (MalformedURLException mue) {
> -             } catch (InvalidConfigValueException icve) {
> -                     icve.printStackTrace();
> -             }
> -     }
> +            BookmarkCategory flog = (BookmarkCategory) 
PROTECTED_CATEGORY.addBookmark(new BookmarkCategory("Freenet devel's 
flogs"));
> +            flog.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
yGvITGZzrY1vUZK-4AaYLgcjZ7ysRqNTMfdcO8gS-LY,-ab5bJVD3Lp-LXEQqBAhJpMKrKJ19RnNaZMIkusU79s,AQACAAE/toad/7/"),
> +                    "Toad", true, node.alerts));
> +            flog.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
hM9XRwjXIzU8xTSBXNZvTn2KuvTSRFnVn4EER9FQnpM,gsth24O7ud4gL4NwNuYJDUqfaWASOG2zxZY~ChtgPxc,AQACAAE/Flog/7/"),
> +                    "Nextgen$", true, node.alerts));
>  
> -     public class BookmarkCallback implements StringArrCallback {
> -             private final Pattern pattern = 
> Pattern.compile("/(.*/)([^/]*)=([A-Z]
{3}@.*).*");
> +            BookmarkCategory apps = (BookmarkCategory) 
PROTECTED_CATEGORY.addBookmark(new BookmarkCategory("Freenet related 
software"));
> +            apps.addBookmark(new BookmarkItem(new 
FreenetURI("USK at 
QRZAI1nSm~dAY2hTdzVWXmEhkaI~dso0OadnppBR7kE,wq5rHGBI7kpChBe4yRmgBChIGDug7Xa5SG9vYGXdxR0,AQACAAE/frost/4"),
> +                    "Frost", true, node.alerts));
>  
> -             public String[] get() {
> -                     synchronized (BookmarkManager.this) {
> -                             return MAIN_CATEGORY.toStrings();
> -                     }
> -             }
> +            //TODO: remove
> +            String[] oldBookmarks = oldConfig.getAll("bookmarks");
> +            if (oldBookmarks != null) {
> +                migrateOldBookmarks(oldBookmarks);
> +            }
>  
> -             public void set(String[] newVals) throws 
> InvalidConfigValueException {
> -                     FreenetURI key;
> -                     clear();
> -                     for (int i = 0; i < newVals.length; i++) {
> -                             try {
> -                                     Matcher matcher = 
> pattern.matcher(newVals[i]);
> -                                     // FIXME: remove
> -                                     if (matcher.matches() && 
> matcher.groupCount() == 3) {
> -                                             
> -                                             boolean hasAnActiveLink = false;
> -                                             makeParents(matcher.group(1));
> -                                             key = new 
> FreenetURI(matcher.group(3));
> -                                             String title = matcher.group(2);
> -                                             if(title.endsWith("=|")) {
> -                                                     title = 
> title.substring(0, title.length()-2);
> -                                                     hasAnActiveLink = true;
> -                                             } else if(title.endsWith("=")) {
> -                                                     title = 
> title.substring(0, title.length()-1);
> -                                             }
> -                                             addBookmark(matcher.group(1), 
> new BookmarkItem(key,
> -                                                             title, 
> hasAnActiveLink, node.alerts), false);
> -                                             
> -                                     } else {
> -                                             throw new 
> InvalidConfigValueException(l10n("malformedBookmark"));
> -                                     }
> +            if (bookmarksFile.exists() && bookmarksFile.canRead() && 
bookmarksFile.length() > 0) {
> +                Logger.normal(this, "Attempting to read the bookmark file 
from " + bookmarksFile.toString());
> +                SimpleFieldSet sfs = SimpleFieldSet.readFrom(bookmarksFile, 
false, true);
> +                readBookmarks(MAIN_CATEGORY, sfs);
> +            }
>  
> -                             } catch (MalformedURLException mue) {
> -                                     throw new 
> InvalidConfigValueException(mue.getMessage());
> -                             }
> -                     }
> -             }
> -     }
> +        } catch (MalformedURLException mue) {
> +        } catch (IOException ioe) {
> +            Logger.error(this, "Error reading the bookmark file (" + 
bookmarksFile.toString() + "):" + ioe.getMessage(), ioe);
> +        }
> +    }
>  
> -     private class USKUpdatedCallback implements USKCallback {
> -             public void onFoundEdition(long edition, USK key) {
> -                     BookmarkItems items = MAIN_CATEGORY.getAllItems();
> -                     for (int i = 0; i < items.size(); i++) {
> -                             if (!"USK".equals(items.get(i).getKeyType()))
> -                                     continue;
> +    private void migrateOldBookmarks(String[] newVals) {
> +        //FIXME: for some reason that doesn't work... if someone wants to 
fix it ;)
> +        Pattern pattern = Pattern.compile("/(.*/)([^/]*)=(|=)*([A-Z]
{3}@.*).*");
> +        FreenetURI key;
> +        clear();
> +        for (int i = 0; i < newVals.length; i++) {
> +            try {
> +                Matcher matcher = pattern.matcher(newVals[i]);
> +                if (matcher.matches() && matcher.groupCount() == 4) {
> +                    makeParents(matcher.group(1));
> +                    key = new FreenetURI(matcher.group(4));
> +                    String title = matcher.group(2);
> +                    boolean hasAnActiveLink = matcher.group(3).indexOf('|') 
> -1;
> +                    addBookmark(matcher.group(1), new BookmarkItem(key,
> +                            title, hasAnActiveLink, node.alerts), false);
> +                }
> +            } catch (MalformedURLException e) {}
> +        }
> +    }
>  
> -                             try {
> -                                     FreenetURI furi = new 
> FreenetURI(items.get(i).getKey());
> -                                     USK usk = USK.create(furi);
> +    private class USKUpdatedCallback implements USKCallback {
>  
> -                                     if (usk.equals(key, false)) {
> -                                             
> items.get(i).setEdition(key.suggestedEdition, node);
> -                                             break;
> -                                     }
> -                             } catch (MalformedURLException mue) {
> -                             }
> -                     }
> -                     node.storeConfig();
> -             }
> -     }
> +        public void onFoundEdition(long edition, USK key) {
> +            BookmarkItems items = MAIN_CATEGORY.getAllItems();
> +            for (int i = 0; i < items.size(); i++) {
> +                if (!"USK".equals(items.get(i).getKeyType())) {
> +                    continue;
> +                }
>  
> -     public String l10n(String key) {
> -             return L10n.getString("BookmarkManager."+key);
> -     }
> +                try {
> +                    FreenetURI furi = new 
FreenetURI(items.get(i).getKey());
> +                    USK usk = USK.create(furi);
>  
> -     public BookmarkCategory getMainCategory() {
> -             return MAIN_CATEGORY;
> -     }
> +                    if (usk.equals(key, false)) {
> +                        items.get(i).setEdition(key.suggestedEdition, 
node);
> +                        break;
> +                    }
> +                } catch (MalformedURLException mue) {
> +                }
> +            }
> +            storeBookmarks();
> +        }
> +    }
>  
> -     public String parentPath(String path) {
> -             if (path.equals("/"))
> -                     return "/";
> +    public String l10n(String key) {
> +        return L10n.getString("BookmarkManager." + key);
> +    }
>  
> -             return path.substring(0, path.substring(0, path.length() - 1)
> -                             .lastIndexOf("/"))
> -                             + "/";
> -     }
> +    public String parentPath(String path) {
> +        if (path.equals("/")) {
> +            return "/";
> +        }
>  
> -     public Bookmark getBookmarkByPath(String path) {
> -             return (Bookmark) bookmarks.get(path);
> -     }
> +        return path.substring(0, path.substring(0, path.length() - 
1).lastIndexOf("/")) + "/";
> +    }
>  
> -     public BookmarkCategory getCategoryByPath(String path) {
> -             if (getBookmarkByPath(path) instanceof BookmarkCategory)
> -                     return (BookmarkCategory) getBookmarkByPath(path);
> +    public Bookmark getBookmarkByPath(String path) {
> +        synchronized (bookmarks) {
> +            return (Bookmark) bookmarks.get(path);
> +        }
> +    }
>  
> -             return null;
> -     }
> +    public BookmarkCategory getCategoryByPath(String path) {
> +        if (getBookmarkByPath(path.trim()) instanceof BookmarkCategory)
> +            return (BookmarkCategory) getBookmarkByPath(path);
>  
> -     public BookmarkItem getItemByPath(String path) {
> -             if (getBookmarkByPath(path) instanceof BookmarkItem)
> -                     return (BookmarkItem) getBookmarkByPath(path);
> +        return null;
> +    }
>  
> -             return null;
> -     }
> +    public BookmarkItem getItemByPath(String path) {
> +        if (getBookmarkByPath(path.trim()) instanceof BookmarkItem) {
> +            return (BookmarkItem) getBookmarkByPath(path);
> +        }
>  
> -     public void addBookmark(String parentPath, Bookmark bookmark, boolean 
store) {
> -             BookmarkCategory parent = getCategoryByPath(parentPath);
> -             parent.addBookmark(bookmark);
> -             putPaths(parentPath + bookmark.getName()
> -                             + ((bookmark instanceof BookmarkCategory) ? "/" 
> : ""),
> -                             bookmark);
> +        return null;
> +    }
>  
> -             if (bookmark instanceof BookmarkItem && ((BookmarkItem) 
bookmark).getKeyType().equals("USK")) {
> -                     try {
> -                             USK u = ((BookmarkItem) bookmark).getUSK();
> -                             this.node.uskManager.subscribe(u, this.uskCB, 
> true, this);
> -                     } catch (MalformedURLException mue) {
> -                     }
> -             }
> -             if (store)
> -                     node.storeConfig();
> -     }
> +    public void addBookmark(BookmarkCategory parent, Bookmark bookmark, 
boolean store) {
> +        if (bookmark instanceof BookmarkItem && ((BookmarkItem) 
bookmark).getKeyType().equals("USK")) {
> +            try {
> +                USK u = ((BookmarkItem) bookmark).getUSK();
> +                this.node.uskManager.subscribe(u, this.uskCB, true, this);
> +            } catch (MalformedURLException mue) {
> +            }
> +        }
> +        if (store) {
> +            storeBookmarks();
> +        }
> +    }
> +    
> +    public void addBookmark(String parentPath, Bookmark bookmark, boolean 
store) {
> +        BookmarkCategory parent = getCategoryByPath(parentPath);
> +        parent.addBookmark(bookmark);
> +        putPaths(parentPath + bookmark.getName() + ((bookmark instanceof 
BookmarkCategory) ? "/" : ""),
> +                bookmark);
> +        addBookmark(parent, bookmark, store);
> +    }
>  
> -     public void renameBookmark(String path, String newName) {
> -             Bookmark bookmark = getBookmarkByPath(path);
> -             
> -             String oldName = bookmark.getName();
> -             String oldPath = '/' + oldName + '/';
> -             String newPath = oldPath.substring(0, oldPath.indexOf(oldName)) 
> + 
newName;
> +    public void renameBookmark(String path, String newName) {
> +        Bookmark bookmark = getBookmarkByPath(path);
>  
> -             bookmark.setName(newName);
> -             bookmarks.remove(path);
> -                if(path.charAt(path.length()-1) != '/') {
> -                    int lastIndexOfSlash = path.lastIndexOf('/');
> -                    newPath = path.substring(0,lastIndexOfSlash)+newPath;
> -                } else
> -                    newPath += '/';
> +        String oldName = bookmark.getName();
> +        String oldPath = '/' + oldName + '/';
> +        String newPath = oldPath.substring(0, oldPath.indexOf(oldName)) + 
newName;
>  
> -                bookmarks.put(newPath, bookmark);
> -                
> -             node.storeConfig();
> -     }
> +        bookmark.setName(newName);
> +        synchronized (bookmarks) {
> +            bookmarks.remove(path);
> +        }
> +        if (path.charAt(path.length() - 1) != '/') {
> +            int lastIndexOfSlash = path.lastIndexOf('/');
> +            newPath = path.substring(0, lastIndexOfSlash) + newPath;
> +        } else {
> +            newPath += '/';
> +        }
> +        synchronized (bookmarks) {
> +            bookmarks.put(newPath, bookmark);
> +        }
> +        storeBookmarks();
> +    }
>  
> -     public void moveBookmark(String bookmarkPath, String newParentPath, 
boolean store) {
> -             Bookmark b = getBookmarkByPath(bookmarkPath);
> -             addBookmark(newParentPath, b, false);
> +    public void moveBookmark(String bookmarkPath, String newParentPath, 
boolean store) {
> +        Bookmark b = getBookmarkByPath(bookmarkPath);
> +        addBookmark(newParentPath, b, false);
>  
> -             getCategoryByPath(parentPath(bookmarkPath)).removeBookmark(b);
> -             removePaths(bookmarkPath);
> +        getCategoryByPath(parentPath(bookmarkPath)).removeBookmark(b);
> +        removePaths(bookmarkPath);
>  
> -             if (store)
> -                     node.storeConfig();
> -     }
> +        if (store) {
> +            storeBookmarks();
> +        }
> +    }
>  
> -     public void removeBookmark(String path, boolean store) {
> -             Bookmark bookmark = getBookmarkByPath(path);
> -             if (bookmark == null)
> -                     return;
> +    public void removeBookmark(String path, boolean store) {
> +        Bookmark bookmark = getBookmarkByPath(path);
> +        if (bookmark == null) {
> +            return;
> +        }
>  
> -             if (bookmark instanceof BookmarkCategory) {
> -                     BookmarkCategory cat = (BookmarkCategory) bookmark;
> -                     for (int i = 0; i < cat.size(); i++) {
> -                             removeBookmark(
> -                                             path
> -                                             + cat.get(i).getName()
> -                                             + ((cat.get(i) instanceof 
> BookmarkCategory) ? "/"
> -                                                             : ""), false);
> -                     }
> -             } else {
> -                     if (((BookmarkItem) 
> bookmark).getKeyType().equals("USK")) {
> -                             try {
> -                                     USK u = ((BookmarkItem) 
> bookmark).getUSK();
> -                                     this.node.uskManager.unsubscribe(u, 
> this.uskCB, true);
> -                             } catch (MalformedURLException mue) {
> -                             }
> -                     }
> -             }
> +        if (bookmark instanceof BookmarkCategory) {
> +            BookmarkCategory cat = (BookmarkCategory) bookmark;
> +            for (int i = 0; i < cat.size(); i++) {
> +                removeBookmark(path + cat.get(i).getName() + ((cat.get(i) 
instanceof BookmarkCategory) ? "/"
> +                        : ""), false);
> +            }
> +        } else {
> +            if (((BookmarkItem) bookmark).getKeyType().equals("USK")) {
> +                try {
> +                    USK u = ((BookmarkItem) bookmark).getUSK();
> +                    this.node.uskManager.unsubscribe(u, this.uskCB, true);
> +                } catch (MalformedURLException mue) {
> +                }
> +            }
> +        }
>  
> -             getCategoryByPath(parentPath(path)).removeBookmark(bookmark);
> -             bookmarks.remove(path);
> +        getCategoryByPath(parentPath(path)).removeBookmark(bookmark);
> +        synchronized (bookmarks) {
> +            bookmarks.remove(path);
> +        }
>  
> -             if (store)
> -                     node.storeConfig();
> -     }
> +        if (store) {
> +            storeBookmarks();
> +        }
> +    }
>  
> -     public void moveBookmarkUp(String path, boolean store) {
> -             BookmarkCategory parent = getCategoryByPath(parentPath(path));
> -             parent.moveBookmarkUp(getBookmarkByPath(path));
> +    public void moveBookmarkUp(String path, boolean store) {
> +        BookmarkCategory parent = getCategoryByPath(parentPath(path));
> +        parent.moveBookmarkUp(getBookmarkByPath(path));
>  
> -             if (store)
> -                     node.storeConfig();
> -     }
> +        if (store) {
> +            storeBookmarks();
> +        }
> +    }
>  
> -     public void moveBookmarkDown(String path, boolean store) {
> -             BookmarkCategory parent = getCategoryByPath(parentPath(path));
> -             parent.moveBookmarkDown(getBookmarkByPath(path));
> +    public void moveBookmarkDown(String path, boolean store) {
> +        BookmarkCategory parent = getCategoryByPath(parentPath(path));
> +        parent.moveBookmarkDown(getBookmarkByPath(path));
>  
> -             if (store)
> -                     node.storeConfig();
> -     }
> +        if (store) {
> +            storeBookmarks();
> +        }
> +    }
>  
> -     private BookmarkCategory makeParents(String path) {
> -             if (bookmarks.containsKey(path))
> -                     return getCategoryByPath(path);
> -             else {
> +    private BookmarkCategory makeParents(String path) {
> +        boolean isInPath = false;
> +        synchronized (bookmarks) {
> +            isInPath = bookmarks.containsKey(path);
> +        }
> +        if (isInPath) {
> +            return getCategoryByPath(path);
> +        } else {
>  
> -                     int index = path.substring(0, path.length() - 
> 1).lastIndexOf("/");
> -                     String name = path.substring(index + 1, path.length() - 
> 1);
> +            int index = path.substring(0, path.length() - 
1).lastIndexOf("/");
> +            String name = path.substring(index + 1, path.length() - 1);
>  
> -                     BookmarkCategory cat = new BookmarkCategory(name);
> -                     makeParents(parentPath(path));
> -                     addBookmark(parentPath(path), cat, false);
> +            BookmarkCategory cat = new BookmarkCategory(name);
> +            makeParents(parentPath(path));
> +            addBookmark(parentPath(path), cat, false);
>  
> -                     return cat;
> -             }
> -     }
> +            return cat;
> +        }
> +    }
>  
> -     private void putPaths(String path, Bookmark b) {
> +    private void putPaths(String path, Bookmark b) {
> +        synchronized (bookmarks) {
> +            bookmarks.put(path, b);
> +        }
> +        if (b instanceof BookmarkCategory) {
> +            for (int i = 0; i < ((BookmarkCategory) b).size(); i++) {
> +                Bookmark child = ((BookmarkCategory) b).get(i);
> +                putPaths(path + child.getName() + (child instanceof 
BookmarkItem ? "" : "/"), child);
> +            }
> +        }
>  
> -             bookmarks.put(path, b);
> -             if (b instanceof BookmarkCategory) {
> -                     for (int i = 0; i < ((BookmarkCategory) b).size(); i++) 
> {
> -                             Bookmark child = ((BookmarkCategory) b).get(i);
> -                             putPaths(path + child.getName()
> -                                             + (child instanceof 
> BookmarkItem ? "" : "/"), child);
> -                     }
> -             }
> +    }
>  
> -     }
> +    private void removePaths(String path) {
> +        if (getBookmarkByPath(path) instanceof BookmarkCategory) {
> +            BookmarkCategory cat = getCategoryByPath(path);
> +            for (int i = 0; i < cat.size(); i++) {
> +                removePaths(path + cat.get(i).getName() + (cat.get(i) 
instanceof BookmarkCategory ? "/" : ""));
> +            }
> +        }
> +        bookmarks.remove(path);
> +    }
>  
> -     private void removePaths(String path) {
> -             if (getBookmarkByPath(path) instanceof BookmarkCategory) {
> -                     BookmarkCategory cat = getCategoryByPath(path);
> -                     for (int i = 0; i < cat.size(); i++) {
> -                             removePaths(path + cat.get(i).getName()
> -                                             + (cat.get(i) instanceof 
> BookmarkCategory ? "/" : ""));
> -                     }
> -             }
> -             bookmarks.remove(path);
> -     }
> +    public void clear() {
> +        removeBookmark("/", false);
> +        synchronized (bookmarks) {
> +            bookmarks.clear();
> +            bookmarks.put("/", MAIN_CATEGORY);
> +        }
> +    }
>  
> -     public void clear() {
> -             removeBookmark("/", false);
> -             bookmarks.clear();
> -             bookmarks.put("/", MAIN_CATEGORY);
> -     }
> +    public FreenetURI[] getBookmarkURIs() {
> +        BookmarkItems items = MAIN_CATEGORY.getAllItems();
> +        FreenetURI[] uris = new FreenetURI[items.size()];
> +        for (int i = 0; i < items.size(); i++) {
> +            uris[i] = items.get(i).getURI();
> +        }
>  
> -     public FreenetURI[] getBookmarkURIs() {
> -             BookmarkItems items = MAIN_CATEGORY.getAllItems();
> -             FreenetURI[] uris = new FreenetURI[items.size()];
> -             for (int i = 0; i < items.size(); i++) {
> -                     uris[i] = items.get(i).getURI();
> -             }
> +        return uris;
> +    }
>  
> -             return uris;
> -     }
> +    private void storeBookmarks() {
> +        Logger.normal(this, "Attempting to save bookmarks to " + 
bookmarksFile.toString());
> +        SimpleFieldSet sfs;
> +        synchronized (bookmarks) {
> +            if (isSavingBookmarks) {
> +                return;
> +            }
> +            isSavingBookmarks = true;
> +            
> +            SimpleFieldSet toSave = MAIN_CATEGORY.toSimpleFieldSet();
> +            if(toSave.isEmpty()) {
> +                isSavingBookmarks = false;
> +                return;
> +            }
> +            sfs = toSave;
> +        }
> +        FileWriter fw = null;
> +        try {
> +            File tmp = File.createTempFile("bookmark", ".bak", 
bookmarksFile.getParentFile());
> +            fw = new FileWriter(tmp);
> +            sfs.writeTo(fw);
> +            if (!tmp.renameTo(bookmarksFile)) {
> +                Logger.error(this, "Unable to rename " + tmp.toString() + " 
to " + bookmarksFile.toString());
> +            }
> +        } catch (IOException ioe) {
> +            Logger.error(this, "An error has occured saving the bookmark 
file :" + ioe.getMessage(), ioe);
> +        } finally {
> +            try {
> +                if (fw != null) {
> +                    fw.close();
> +                }
> +            } catch (IOException e) {
> +            }
> +        }
> +
> +        synchronized (bookmarks) {
> +            isSavingBookmarks = false;
> +        }
> +    }
> +
> +    private void readBookmarks(BookmarkCategory category, SimpleFieldSet 
sfs) {
> +        synchronized (bookmarks) {
> +            String[] categories = sfs.namesOfDirectSubsets();
> +            for (int i = 0; i < categories.length; i++) {
> +                SimpleFieldSet subset = sfs.subset(categories[i]);
> +                BookmarkCategory currentCategory = new 
BookmarkCategory(categories[i]);
> +                category.addBookmark(currentCategory);
> +                addBookmark(currentCategory, currentCategory, false);
> +                readBookmarks(currentCategory, subset);
> +            }
> +
> +            Iterator it = sfs.keyIterator();
> +            while (it.hasNext()) {
> +                String key = (String) it.next();
> +                String line = sfs.get(key);
> +                try {
> +                    BookmarkItem item = new BookmarkItem(line, 
node.alerts);
> +                    category.addBookmark(item);
> +                    addBookmark(category, item, false);
> +                } catch (MalformedURLException e) {
> +                    Logger.error(this, "Error while adding one of the 
bookmarks :"+e.getMessage(), e);
> +                }
> +            }
> +        }
> +        storeBookmarks();
> +    }
>  }
> 
> Modified: trunk/freenet/src/freenet/node/Node.java
> ===================================================================
> --- trunk/freenet/src/freenet/node/Node.java  2007-11-20 19:05:06 UTC (rev 
15880)
> +++ trunk/freenet/src/freenet/node/Node.java  2007-11-20 19:15:58 UTC (rev 
15881)
> @@ -547,7 +547,8 @@
>               startupTime = System.currentTimeMillis();
>                  // Will be set up properly afterwards
>                  L10n.setLanguage(L10n.FALLBACK_DEFAULT);
> -                startupPageHolder = new StartupToadletServer(executor, 
config);
> +                SimpleFieldSet oldConfig = config.getSimpleFieldSet();
> +                startupPageHolder = new StartupToadletServer(executor, 
oldConfig);
>               nodeNameUserAlert = new MeaningfulNodeNameUserAlert(this);
>               recentlyCompletedIDs = new LRUQueue();
>               this.config = config;
> @@ -1265,7 +1266,7 @@
>               
>               nodeStats = new NodeStats(this, sortOrder, new 
> SubConfig("node.load", 
config), oldThrottleFS, obwLimit, ibwLimit);
>               
> -             clientCore = new NodeClientCore(this, config, nodeConfig, 
> nodeDir, 
getDarknetPortNumber(), sortOrder, oldThrottleFS == null ? null : 
oldThrottleFS.subset("RequestStarters"));
> +             clientCore = new NodeClientCore(this, config, nodeConfig, 
> nodeDir, 
getDarknetPortNumber(), sortOrder, oldThrottleFS == null ? null : 
oldThrottleFS.subset("RequestStarters"), oldConfig);
>  
>               nodeConfig.register("disableHangCheckers", false, sortOrder++, 
> true, 
false, "Node.disableHangCheckers", "Node.disableHangCheckersLong", new 
BooleanCallback() {
>  
> 
> Modified: trunk/freenet/src/freenet/node/NodeClientCore.java
> ===================================================================
> --- trunk/freenet/src/freenet/node/NodeClientCore.java        2007-11-20 
> 19:05:06 
UTC (rev 15880)
> +++ trunk/freenet/src/freenet/node/NodeClientCore.java        2007-11-20 
> 19:15:58 
UTC (rev 15881)
> @@ -113,7 +113,7 @@
>       static final long MAX_ARCHIVED_FILE_SIZE = 1024*1024; // arbitrary... 
FIXME
>       static final int MAX_CACHED_ELEMENTS = 256*1024; // equally arbitrary! 
FIXME hopefully we can cache many of these though
>  
> -     NodeClientCore(Node node, Config config, SubConfig nodeConfig, File 
nodeDir, int portNumber, int sortOrder, SimpleFieldSet oldThrottleFS) throws 
NodeInitException {
> +     NodeClientCore(Node node, Config config, SubConfig nodeConfig, File 
nodeDir, int portNumber, int sortOrder, SimpleFieldSet oldThrottleFS, 
SimpleFieldSet oldConfig) throws NodeInitException {
>               this.node = node;
>               this.nodeStats = node.nodeStats;
>               this.random = node.random;
> @@ -346,7 +346,7 @@
>               }
>               
>               SubConfig fproxyConfig = new SubConfig("fproxy", config);
> -             bookmarkManager = new BookmarkManager(this, fproxyConfig);
> +             bookmarkManager = new BookmarkManager(this, oldConfig);
>               
>               // FProxy
>               // FIXME this is a hack, the real way to do this is plugins
> 
> _______________________________________________
> cvs mailing list
> cvs at freenetproject.org
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<https://emu.freenetproject.org/pipermail/devl/attachments/20071120/3c8b1b01/attachment.pgp>

Reply via email to