Author: xor Date: 2008-11-06 01:12:25 +0000 (Thu, 06 Nov 2008) New Revision: 23329
Added: trunk/plugins/Freetalk/FTBoard.java trunk/plugins/Freetalk/FTDealer.java trunk/plugins/Freetalk/FTIdentity.java trunk/plugins/Freetalk/FTIdentityManager.java trunk/plugins/Freetalk/FTMessage.java trunk/plugins/Freetalk/FTMessageManager.java trunk/plugins/Freetalk/FTOwnIdentity.java trunk/plugins/Freetalk/Freetalk.java trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java trunk/plugins/Freetalk/WoT/FTIdentityWoT.java trunk/plugins/Freetalk/WoT/FTMessageManagerWoT.java trunk/plugins/Freetalk/WoT/FTMessageWoT.java trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java Removed: trunk/plugins/Freetalk/FMS.java trunk/plugins/Freetalk/FMSBoard.java trunk/plugins/Freetalk/FMSDealer.java trunk/plugins/Freetalk/FMSIdentity.java trunk/plugins/Freetalk/FMSIdentityManager.java trunk/plugins/Freetalk/FMSMessage.java trunk/plugins/Freetalk/FMSMessageManager.java trunk/plugins/Freetalk/FMSOwnIdentity.java trunk/plugins/Freetalk/WoT/FMSIdentityManagerWoT.java trunk/plugins/Freetalk/WoT/FMSIdentityWoT.java trunk/plugins/Freetalk/WoT/FMSMessageManagerWoT.java trunk/plugins/Freetalk/WoT/FMSMessageWoT.java trunk/plugins/Freetalk/WoT/FMSOwnIdentityWoT.java Log: Rename FMS to Freetalk stage 2/3: Rename the files. Deleted: trunk/plugins/Freetalk/FMS.java =================================================================== --- trunk/plugins/Freetalk/FMS.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMS.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,347 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -import plugins.FMSPlugin.ui.Errors; -import plugins.FMSPlugin.ui.IdentityEditor; -import plugins.FMSPlugin.ui.Messages; -import plugins.FMSPlugin.ui.Status; -import plugins.FMSPlugin.ui.Welcome; - -import com.db4o.Db4o; -import com.db4o.ObjectContainer; -import com.db4o.ObjectSet; -import com.db4o.config.Configuration; - -import freenet.client.HighLevelSimpleClient; -import freenet.clients.http.PageMaker; -import freenet.clients.http.PageMaker.THEME; -import freenet.keys.FreenetURI; -import freenet.l10n.L10n.LANGUAGE; -import freenet.pluginmanager.DownloadPluginHTTPException; -import freenet.pluginmanager.FredPlugin; -import freenet.pluginmanager.FredPluginFCP; -import freenet.pluginmanager.FredPluginHTTP; -import freenet.pluginmanager.FredPluginL10n; -import freenet.pluginmanager.FredPluginThemed; -import freenet.pluginmanager.FredPluginThreadless; -import freenet.pluginmanager.FredPluginVersioned; -import freenet.pluginmanager.NotFoundPluginHTTPException; -import freenet.pluginmanager.PluginHTTPException; -import freenet.pluginmanager.PluginReplySender; -import freenet.pluginmanager.PluginRespirator; -import freenet.pluginmanager.RedirectPluginHTTPException; -import freenet.support.HTMLNode; -import freenet.support.Logger; -import freenet.support.SimpleFieldSet; -import freenet.support.api.Bucket; -import freenet.support.api.HTTPRequest; -import freenet.support.api.HTTPUploadedFile; -import freenet.support.io.TempBucketFactory; - -/** - * @author saces - * - */ -public class FMS implements FredPlugin, FredPluginFCP, FredPluginHTTP, FredPluginL10n, FredPluginThemed, FredPluginThreadless, FredPluginVersioned { - - public static String SELF_URI = "/plugins/plugins.FMSPlugin.FMSPlugin"; - public static String SELF_TITLE = "Freenet Message System"; - public static String WOT_NAME = "plugins.WoT.WoT"; - - public final String MESSAGEBASE = "fms"; - - public PluginRespirator pr; - - public PageMaker pm; - - private LANGUAGE language; - private THEME theme; - - private HighLevelSimpleClient client; - - private FMSDealer dealer; - - public ObjectContainer db_config; - public ObjectContainer db_cache; - - public TempBucketFactory tbf; - - public void runPlugin(PluginRespirator pr2) { - - Logger.error(this, "Start"); - - pr = pr2; - - pm = pr.getPageMaker(); - pm.addNavigationLink(SELF_URI + "/", "Home", "FMS plugin home", false, null); - pm.addNavigationLink(SELF_URI + "/ownidentities", "Own Identities", "Manage your own identities", false, null); - pm.addNavigationLink(SELF_URI + "/knownidentities", "Known Identities", "Manage others identities", false, null); - pm.addNavigationLink(SELF_URI + "/messages", "Messages", "View Messages", false, null); - pm.addNavigationLink(SELF_URI + "/status", "Dealer status", "Show what happens in background", false, null); - pm.addNavigationLink("/", "Fproxy", "Back to nodes home", false, null); - - client = pr.getHLSimpleClient(); - - Configuration config_config = Db4o.newConfiguration(); - /* We re-use all information from the WoT-plugin's database. - config_config.objectClass(FMSOwnIdentity.class).objectField("requestUri").indexed(true); - config_config.objectClass(FMSIdentity.class).objectField("requestUri").indexed(true); - */ - db_config = Db4o.openFile(config_config, "fms_conf.db4o"); - - Configuration cache_config = Db4o.newConfiguration(); - for(String f : FMSMessage.getIndexedFields()) - cache_config.objectClass(FMSMessage.class).objectField(f).indexed(true); - cache_config.objectClass(FMSMessage.class).cascadeOnUpdate(true); - // TODO: decide about cascade on delete. - for(String f : FMSBoard.getIndexedFields()) - cache_config.objectClass(FMSBoard.class).objectField(f).indexed(true); - - db_cache = Db4o.openFile(cache_config, "fms_cache.db4o"); - - // while develop wipe cache on startup - ObjectSet<Object> result = db_cache.queryByExample(new Object()); - if (result.size() > 0) { - for (Object o : result) { - db_cache.delete(o); - } - db_cache.commit(); - } - - dealer = new FMSDealer(pr.getNode().executor); - - tbf = pr.getNode().clientCore.tempBucketFactory; - } - - public void terminate() { - dealer.killMe(); - db_config.close(); - db_cache.close(); - } - - public String handleHTTPGet(HTTPRequest request) throws PluginHTTPException { - - if (request.isParameterSet("formPassword")) { - String pass = request.getParam("formPassword"); - if ((pass.length() == 0) || !pass.equals(pr.getNode().clientCore.formPassword)) { - return Errors.makeErrorPage(this, "Buh! Invalid form password"); - } - } - - String page = request.getPath().substring(SELF_URI.length()); - if ((page.length() < 1) || ("/".equals(page))) - return Welcome.makeWelcomePage(this); - - if ("/status".equals(page)) { - return Status.makeStatusPage(this); - } - - if ("/ownidentities".equals(page)) - return IdentityEditor.makeOwnIdentitiesPage(this, request); - - if ("/knownidentities".equals(page)) - return IdentityEditor.makeKnownIdentitiesPage(this, request); - - if ("/messages".equals(page)) - return Messages.makeMessagesPage(this, request); - - throw new NotFoundPluginHTTPException("Resource not found in FMSPlugin", page); - } - - public void handle(PluginReplySender replysender, SimpleFieldSet params, Bucket data, int accesstype) { - SimpleFieldSet sfs = new SimpleFieldSet(true); - sfs.putOverwrite("Hello", "Nice try ;)"); - sfs.putOverwrite("Sorry", "Not implemeted yet :("); - } - - public String handleHTTPPost(HTTPRequest request) throws PluginHTTPException { - String pass = request.getPartAsString("formPassword", 32); - if ((pass.length() == 0) || !pass.equals(pr.getNode().clientCore.formPassword)) { - return Errors.makeErrorPage(this, "Buh! Invalid form password"); - } - - String page = request.getPath().substring(SELF_URI.length()); - - if (page.length() < 1) - throw new NotFoundPluginHTTPException("Resource not found", page); - - if (page.equals("/exportDB")) { - StringWriter sw = new StringWriter(); - try { - Backup.exportConfigDb(db_config, sw); - } catch (IOException e) { - Logger.error(this, "Error While exporting database!", e); - return Errors.makeErrorPage(this, "Server BuhBuh! " + e.getMessage()); - } - throw new DownloadPluginHTTPException(sw.toString().getBytes(), "fms-kidding.xml", "fms-clone/db-backup"); - } - - if (page.equals("/importDB")) { - HTTPUploadedFile file = request.getUploadedFile("filename"); - if (file == null || file.getFilename().trim().length() == 0) { - return Errors.makeErrorPage(this, "No file to import selected!"); - } - try { - Backup.importConfigDb(db_config, file.getData().getInputStream()); - } catch (Exception e) { - Logger.error(this, "Error While importing db from: " + file.getFilename(), e); - return Errors.makeErrorPage(this, "Error While importing db from: " + file.getFilename() + e.getMessage()); - } - throw new RedirectPluginHTTPException("", SELF_URI); - } - - if (page.equals("/createownidentity")) { - List<String> err = new ArrayList<String>(); - String nick = request.getPartAsString("nick", 1024).trim(); - String requestUri = request.getPartAsString("requestURI", 1024); - String insertUri = request.getPartAsString("insertURI", 1024); - boolean publish = "true".equals(request.getPartAsString("publishTrustList", 24)); - - IdentityEditor.checkNick(err, nick); - - if ((requestUri.length() == 0) && (insertUri.length() == 0)) { - FreenetURI[] kp = client.generateKeyPair("fms"); - insertUri = kp[0].toString(); - requestUri = kp[1].toString(); - err.add("URI was empty, I generated one for you."); - return IdentityEditor.makeNewOwnIdentityPage(this, nick, requestUri, insertUri, publish, err); - } - - IdentityEditor.checkInsertURI(err, insertUri); - IdentityEditor.checkRequestURI(err, requestUri); - - if (err.size() == 0) { - // FIXME: use identity manager to implement this - throw new UnsupportedOperationException(); - /* - FMSOwnIdentity oi = new FMSOwnIdentity(nick, requestUri, insertUri, publish); - IdentityEditor.addNewOwnIdentity(db_config, oi, err); - */ - } - - if (err.size() == 0) { - throw new RedirectPluginHTTPException("", SELF_URI + "/ownidentities"); - } - - return IdentityEditor.makeNewOwnIdentityPage(this, nick, requestUri, insertUri, publish, err); - } - - if (page.equals("/addknownidentity")) { - List<String> err = new ArrayList<String>(); - - String requestUri = request.getPartAsString("requestURI", 1024); - - if (requestUri.length() == 0) { - err.add("Are you jokingly? URI was empty."); - return IdentityEditor.makeNewKnownIdentityPage(this, requestUri, err); - } - - IdentityEditor.checkRequestURI(err, requestUri); - - if (err.size() == 0) { - // FIXME: use identity manager to implement this - throw new UnsupportedOperationException(); - /* - FMSIdentity i = new FMSIdentity("", requestUri); - IdentityEditor.addNewKnownIdentity(db_config, i, err); - */ - } - - if (err.size() == 0) { - throw new RedirectPluginHTTPException("", SELF_URI + "/knownidentities"); - } - - return IdentityEditor.makeNewKnownIdentityPage(this, requestUri, err); - } - - if (page.equals("/deleteOwnIdentity")) { - List<String> err = new ArrayList<String>(); - - String requestUri = request.getPartAsString("identity", 1024); - if (requestUri.length() == 0) { - err.add("Are you jokingly? URI was empty."); - return IdentityEditor.makeDeleteOwnIdentityPage(this, requestUri, err); - } - - if (request.isPartSet("confirmed")) { - IdentityEditor.deleteIdentity(this, requestUri, err); - } else { - err.add("Please confirm."); - } - - if (err.size() > 0) { - return IdentityEditor.makeDeleteOwnIdentityPage(this, requestUri, err); - } - throw new RedirectPluginHTTPException("", SELF_URI + "/ownidentities"); - // return IdentityEditor.makeDeleteOwnIdentityPage(fms, requestUri, - // err); - } - - if (page.equals("/deleteIdentity")) { - List<String> err = new ArrayList<String>(); - - String requestUri = request.getPartAsString("identity", 1024); - if (requestUri.length() == 0) { - err.add("Are you jokingly? URI was empty."); - return IdentityEditor.makeDeleteKnownIdentityPage(this, requestUri, err); - } - - if (request.isPartSet("confirmed")) { - IdentityEditor.deleteIdentity(this, requestUri, err); - } else { - err.add("Please confirm."); - } - - if (err.size() > 0) { - return IdentityEditor.makeDeleteKnownIdentityPage(this, requestUri, err); - } - throw new RedirectPluginHTTPException("", SELF_URI + "/knownidentities"); - } - throw new NotFoundPluginHTTPException("Resource not found", page); - } - - public String getVersion() { - return "? r" + Version.svnRevision; - } - - public String getString(String key) { - // Logger.error(this, "Request translation for "+key); - return key; - } - - public void setLanguage(LANGUAGE newLanguage) { - language = newLanguage; - Logger.error(this, "Set LANGUAGE to: " + language.isoCode); - } - - public void setTheme(THEME newTheme) { - theme= newTheme; - Logger.error(this, "Set THEME to: " + theme.code); - } - - public boolean isWoTpresent() { - FredPluginFCP plug = pr.getNode().pluginManager.getFCPPlugin(FMS.WOT_NAME); - return (plug != null); - } - - public long countIdentities() { - return db_config.queryByExample(FMSIdentity.class).size() - countOwnIdentities(); - } - - public long countOwnIdentities() { - return db_config.queryByExample(FMSOwnIdentity.class).size(); - } - - - final public HTMLNode getPageNode() { - return pm.getPageNode(FMS.SELF_TITLE, null); - } - -} Deleted: trunk/plugins/Freetalk/FMSBoard.java =================================================================== --- trunk/plugins/Freetalk/FMSBoard.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSBoard.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,232 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Iterator; - -import com.db4o.ObjectContainer; -import com.db4o.ObjectSet; -import com.db4o.query.Query; - -import freenet.keys.FreenetURI; -import freenet.support.UpdatableSortedLinkedListKilledException; - -/** - * @author xor - * - */ -public class FMSBoard { - - private transient final ObjectContainer db; - - private transient final FMSBoard self = this; - - private transient final FMSMessageManager mMessageManager; - - private final String mName; - - /** - * Get a list of fields which the database should create an index on. - */ - public static String[] getIndexedFields() { - return new String[] {"mName"}; - } - - public FMSBoard(ObjectContainer myDB, FMSMessageManager newMessageManager, String newName) { - if(newName==null || newName.length() == 0) - throw new IllegalArgumentException("Empty board name."); - - assert(myDB != null); - assert(newMessageManager != null); - - db = myDB; - mMessageManager = newMessageManager; - // FIXME: Validate name and description. - mName = newName; - - db.store(this); - db.commit(); - } - - /** - * @return The name. - */ - public String getName() { - return mName; - } - - /** - * Called by the <code>FMSMessageManager</code> to add a just received message to the board. - * The job for this function is to find the right place in the thread-tree for the new message and to move around older messages - * if a parent message of them is received. - */ - public synchronized void addMessage(FMSMessage newMessage) throws UpdatableSortedLinkedListKilledException { - synchronized(mMessageManager) { - db.store(newMessage); - db.commit(); - - if(!newMessage.isThread()) - { - FreenetURI parentURI = newMessage.getParentURI(); - FMSMessage parentMessage = mMessageManager.get(parentURI); /* TODO: This allows crossposting. Figure out whether we need to handle it specially */ - FMSMessage parentThread = findParentThread(newMessage); - - if(parentThread != null) - newMessage.setThread(parentThread); - - if(parentMessage != null) { - newMessage.setParent(parentMessage); - } else { /* The message is an orphan */ - if(parentThread != null) { - newMessage.setParent(parentThread); /* We found its parent thread so just stick it in there for now */ - } - else { - /* The message is an absolute orphan */ - - /* - * FIXME: The MessageManager should try to download the parent message if it's poster has enough trust. - * If it is programmed to do that, it will check its Hashtable whether the parent message already exists. - * We also do that here, therefore, when implementing parent message downloading, please do the Hashtable checking only once. - */ - } - } - } - - linkOrphansToNewParent(newMessage); - } - } - - private synchronized void linkOrphansToNewParent(FMSMessage newMessage) throws UpdatableSortedLinkedListKilledException { - if(newMessage.isThread()) { - Iterator<FMSMessage> absoluteOrphans = absoluteOrphanIterator(newMessage.getURI()); - while(absoluteOrphans.hasNext()){ /* Search in the absolute orphans for messages which belong to this thread */ - FMSMessage orphan = absoluteOrphans.next(); - orphan.setParent(newMessage); - } - } - else { - FMSMessage parentThread = newMessage.getThread(); - if(parentThread != null) { /* Search in its parent thread for its children */ - Iterator<FMSMessage> iter = parentThread.childrenIterator(this); - while(iter.hasNext()) { - FMSMessage parentThreadChild = iter.next(); - - if(parentThreadChild.getParentURI().equals(newMessage.getURI())) { /* We found its parent, yeah! */ - parentThreadChild.setParent(newMessage); /* It's a child of the newMessage, not of the parentThread */ - } - } - } - else { /* The new message is an absolute orphan, find its children amongst the other absolute orphans */ - Iterator<FMSMessage> absoluteOrphans = absoluteOrphanIterator(newMessage.getURI()); - while(absoluteOrphans.hasNext()){ /* Search in the orphans for messages which belong to this message */ - FMSMessage orphan = absoluteOrphans.next(); - /* - * The following if() could be joined into the db4o query in absoluteOrphanIterator(). I did not do it because we could - * cache the list of absolute orphans locally. - */ - if(orphan.getParentURI().equals(newMessage.getURI())) - orphan.setParent(newMessage); - } - } - } - } - - protected synchronized FMSMessage findParentThread(FMSMessage m) { - Query q = db.query(); - q.constrain(FMSMessage.class); - /* FIXME: I assume that db4o is configured to keep an URI index per board. We still have to ensure in FMS.java that it is configured to do so. - * If my second assumption - that the descend() statements are evaluated in the specified order - is true, then it might be faste because the - * URI index is smaller per board than the global URI index. */ - q.descend("mBoards").constrain(mName); - q.descend("mURI").constrain(m.getParentThreadURI()); - ObjectSet<FMSMessage> parents = q.execute(); - - assert(parents.size() <= 1); - - return (parents.size() != 0 ? parents.next() : null); - } - - - /** - * Get all threads in the board. The view is specified to the FMSOwnIdentity displaying it, therefore you have to pass one as parameter. - * @param identity The identity viewing the board. - * @return An iterator of the message which the identity will see (based on its trust levels). - */ - public synchronized Iterator<FMSMessage> threadIterator(final FMSOwnIdentity identity) { - return new Iterator<FMSMessage>() { - private final FMSOwnIdentity mIdentity = identity; - private final Iterator<FMSMessage> iter; - private FMSMessage next; - - { - /* FIXME: If db4o supports precompiled queries, this one should be stored precompiled. - * Reason: We sort the threads by date. - * Maybe we can just keep the Query-object and call q.execute() as many times as we like to? - * Or somehow tell db4o to keep a per-board thread index which is sorted by Date? - This would be the best solution */ - Query q = db.query(); - q.constrain(FMSMessage.class); - q.descend("mBoards").constrain(mName); /* FIXME: mBoards is an array. Does constrain() check whether it contains the element mName? */ - q.descend("mThread").constrain(null); - q.descend("mDate").orderDescending(); - - iter = q.execute().iterator(); - next = iter.hasNext() ? iter.next() : null; - } - - public boolean hasNext() { - for(; next != null; next = iter.hasNext() ? iter.next() : null) - { - if(mIdentity.wantsMessagesFrom(identity)) - return true; - } - return false; - } - - public FMSMessage next() { - FMSMessage result = hasNext() ? next : null; - next = iter.hasNext() ? iter.next() : null; - return result; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } - - /** - * Get an iterator over messages for which the parent thread with the given URI was not known. - */ - public synchronized Iterator<FMSMessage> absoluteOrphanIterator(final FreenetURI thread) { - return new Iterator<FMSMessage>() { - private final ObjectSet<FMSMessage> mMessages; - private final Iterator<FMSMessage> iter; - - { - /* FIXME: This query should be accelerated. The amount of absolute orphans is very small usually, so we should configure db4o - * to keep a separate list of those. */ - Query q = db.query(); - q.constrain(FMSMessage.class); - q.descend("mBoards").constrain(mName); /* FIXME: mBoards is an array. Does constrain() check whether it contains the element mName? */ - q.descend("mThreadURI").constrain(thread); - q.descend("mThread").constrain(null); - mMessages = q.execute(); - iter = mMessages.iterator(); - } - - public boolean hasNext() { - return mMessages.hasNext(); - } - - public FMSMessage next() { - return mMessages.next(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} Deleted: trunk/plugins/Freetalk/FMSDealer.java =================================================================== --- trunk/plugins/Freetalk/FMSDealer.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSDealer.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,31 +0,0 @@ -/* 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 plugins.Freetalk; - -import freenet.support.Executor; -import freenet.support.Logger; - -public class FMSDealer { - - private final Executor _executor; - - // services - private FMSIdentityManager identManager; - - FMSDealer(Executor executor) { - this._executor = executor; - _executor.execute(new Runnable() { - public void run() { - startDealer(); - }}, "Dealer starter"); - } - - private void startDealer() { - Logger.error(this, "Starting dealer", new Error("TODO")); - } - - synchronized void killMe() { - Logger.error(this, "Killing dealer", new Error("TODO")); - } -} Deleted: trunk/plugins/Freetalk/FMSIdentity.java =================================================================== --- trunk/plugins/Freetalk/FMSIdentity.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSIdentity.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,26 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Date; -import java.util.Iterator; - -import freenet.keys.FreenetURI; - -public interface FMSIdentity { - - /** - * @return The requestURI ({@link FreenetURI}) to fetch this Identity - */ - public FreenetURI getRequestURI(); - - public String getNickName(); - - public Date getLastChange(); - - /** - * @return Whether this Identity publishes its trustList or not - */ - public boolean doesPublishTrustList(); -} Deleted: trunk/plugins/Freetalk/FMSIdentityManager.java =================================================================== --- trunk/plugins/Freetalk/FMSIdentityManager.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSIdentityManager.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,49 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Iterator; - -import com.db4o.ObjectContainer; -import com.db4o.ObjectSet; - -import freenet.support.Executor; - -/** - * @author saces, xor - * - */ -public abstract class FMSIdentityManager implements Iterable<FMSIdentity> { - - protected final ObjectContainer db; - - protected final Executor mExecutor; - - public FMSIdentityManager(ObjectContainer myDB, Executor newExecutor) { - db = myDB; - mExecutor = newExecutor; - } - - public synchronized Iterator<FMSIdentity> iterator() { - ObjectSet<FMSIdentity> ids = db.query(FMSIdentity.class); - return ids.iterator(); - } - - public synchronized Iterator<FMSOwnIdentity> ownIdentityIterator() { - ObjectSet<FMSOwnIdentity> oids = db.query(FMSOwnIdentity.class); - return oids.iterator(); - } - - public synchronized boolean anyOwnIdentityWantsMessagesFrom(FMSIdentity identity) { - Iterator<FMSOwnIdentity> iter = ownIdentityIterator(); - - while (iter.hasNext()) { - FMSOwnIdentity oid = iter.next(); - if (oid.wantsMessagesFrom(identity)) - return true; - } - - return false; - } -} Deleted: trunk/plugins/Freetalk/FMSMessage.java =================================================================== --- trunk/plugins/Freetalk/FMSMessage.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSMessage.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,265 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Arrays; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import com.db4o.ObjectContainer; -import com.db4o.query.Query; - -import freenet.keys.FreenetURI; -import freenet.support.UpdatableSortedLinkedListKilledException; - -/** - * @author saces, xor - * - */ -public abstract class FMSMessage { - - protected ObjectContainer db; - - /** - * The URI of this message. - */ - private final FreenetURI mURI; - - /** - * The URI of the thread this message belongs to. - * We do not need it to construct the thread-tree from messages, but it boosts performance of thread-tree-construction: - * Thread-size (amount of replies) is usually infinitesimal compared to the size of a FMSBoard (amount of threads). - * We receive messages in random order, therefore we will usually have orphan messages of which we need to find the parents. - * If we receive the parent messages of those messages, we will be able to find their orphan children faster if we only need to search in - * the thread they belong to and not in the whole FMSBoard - which may contain many thousands of messages. - */ - private final FreenetURI mThreadURI; - - /** - * The URI of the message to which this message is a reply. Null if it is a thread. - */ - private final FreenetURI mParentURI; - - /** - * The boards to which this message was posted, in alphabetical order. - */ - private final FMSBoard[] mBoards; - - private final FMSIdentity mAuthor; - - private final String mTitle; - - /** - * The date when the message was written in <strong>UTC time</strong>. - */ - private final Date mDate; - - private final String mText; - - /** - * The attachments of this message, in the order in which they were received in the original message. - */ - private final FreenetURI[] mAttachments; - - /** - * The thread to which this message is a reply. - */ - private FMSMessage mThread = null; - - /** - * The message to which this message is a reply. - */ - private FMSMessage mParent = null; - - /** - * Get a list of fields which the database should create an index on. - */ - public static String[] getIndexedFields() { - return new String[] { "mURI", "mThreadURI", "mBoards"}; - } - - public FMSMessage(ObjectContainer db, FreenetURI newURI, FreenetURI newThreadURI, FreenetURI newParentURI, Set<FMSBoard> newBoards, FMSIdentity newAuthor, String newTitle, Date newDate, String newText, List<FreenetURI> newAttachments) { - if (newURI == null || newBoards == null || newAuthor == null) - throw new IllegalArgumentException(); - - if (newBoards.isEmpty()) - throw new IllegalArgumentException("No boards in message " + newURI); - - if (!isTitleValid(newTitle)) - throw new IllegalArgumentException("Invalid message title in message " + newURI); - - if (!isTextValid(newText)) - throw new IllegalArgumentException("Invalid message text in message " + newURI); - - mURI = newURI; - mThreadURI = newThreadURI; - mParentURI = newParentURI; - mBoards = (FMSBoard[])newBoards.toArray(); - Arrays.sort(mBoards); - mAuthor = newAuthor; - mTitle = newTitle; - mDate = newDate; // TODO: Check out whether Date provides a function for getting the timezone and throw an Exception if not UTC. - mText = newText; - mAttachments = newAttachments!=null ? (FreenetURI[])newAttachments.toArray() : new FreenetURI[0]; - } - - /** - * Get the URI of the message. - */ - public FreenetURI getURI() { - return mURI; - } - - /** - * Get the FreenetURI of the thread this message belongs to. - */ - public FreenetURI getParentThreadURI() { - return mThreadURI; - } - - /** - * Get the FreenetURI to which this message is a reply. Null if the message is a thread. - */ - public FreenetURI getParentURI() { - return mParentURI; - } - - public boolean isThread() { - return getParentURI() == null; - } - - /** - * Get the boards to which this message was posted. - * The boards are returned in alphabetical order. - */ - public FMSBoard[] getBoards() { - return mBoards; - } - - /** - * Get the author of the message. - */ - public FMSIdentity getAuthor() { - return mAuthor; - } - - /** - * Get the title of the message. - */ - public String getTitle() { - return mTitle; - } - - /** - * Get the date when the message was written in <strong>UTC time</strong>. - */ - public Date getDate() { - return mDate; - } - - /** - * Get the text of the message. - */ - public String getText() { - return mText; - } - - /** - * Get the attachments of the message, in the order in which they were received. - */ - public FreenetURI[] getAttachments() { - return mAttachments; - } - - public synchronized FMSMessage getThread() { - return mThread; - } - - public synchronized void setThread(FMSMessage newParentThread) { - assert(mThread == null); - assert(mThreadURI == null); - mThread = newParentThread; - db.store(this); - db.commit(); - } - - public synchronized FMSMessage getParent() { - return mParent; - } - - public synchronized void setParent(FMSMessage newParent) throws UpdatableSortedLinkedListKilledException { - /* TODO: assert(newParent contains at least one board which mBoards contains) */ - mParent = newParent; - db.store(this); - db.commit(); - } - - public synchronized Iterator<FMSMessage> childrenIterator(final FMSBoard board) { - return new Iterator<FMSMessage>() { - private Iterator<FMSMessage> iter; - - { - /* TODO: Accelerate this query: configure db4o to keep a per-message date-sorted index of children. - * - Not very important for now since threads are usually small. */ - Query q = db.query(); - q.constrain(FMSMessage.class); - q.descend("mBoard").constrain(board.getName()); - q.descend("mParent").constrain(this); - q.descend("mDate").orderDescending(); - - iter = q.execute().iterator(); - } - - public boolean hasNext() { - return iter.hasNext(); - } - - public FMSMessage next() { - return iter.next(); - } - - public void remove() { - throw new UnsupportedOperationException("Use child.setParent(null) instead."); - } - }; - } - - /** - * Checks whether the title of the message is valid. Validity conditions: - * - ... - */ - static public boolean isTitleValid(String title) { - // FIXME: Implement. - return true; - } - - /** - * Checks whether the text of the message is valid. Validity conditions: - * - ... - */ - static public boolean isTextValid(String text) { - // FIXME: Implement. - return true; - } - - /** - * Makes the passed title valid in means of <code>isTitleValid()</code> - * @see isTitleValid - */ - static public String makeTitleValid(String title) { - // FIXME: Implement. - return title; - } - - /** - * Makes the passed text valid in means of <code>isTextValid()</code> - * @see isTextValid - */ - static public String makeTextValid(String text) { - // FIXME: Implement. - return text; - } -} Deleted: trunk/plugins/Freetalk/FMSMessageManager.java =================================================================== --- trunk/plugins/Freetalk/FMSMessageManager.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSMessageManager.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,74 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Iterator; - -import com.db4o.ObjectContainer; -import com.db4o.ObjectSet; -import com.db4o.query.Query; - -import freenet.keys.FreenetURI; - -/** - * @author xor - * - */ -public abstract class FMSMessageManager { - - protected ObjectContainer db; - - protected FMSIdentityManager mIdentityManager; - - public FMSMessageManager(ObjectContainer myDB, FMSIdentityManager myIdentityManager) { - assert(myDB != null); - assert(myIdentityManager != null); - - db = myDB; - mIdentityManager = myIdentityManager; - } - - public synchronized FMSMessage get(FreenetURI uri) { - Query query = db.query(); - query.constrain(FMSMessage.class); - query.descend("mURI").constrain(uri); - ObjectSet<FMSMessage> result = query.execute(); - - assert(result.size() <= 1); - - return (result.size() == 0) ? null : result.next(); - } - - public synchronized FMSBoard getBoardByName(String name) { - Query query = db.query(); - query.constrain(FMSBoard.class); - query.descend("mName").constrain(name); - ObjectSet<FMSBoard> result = query.execute(); - - assert(result.size() <= 1); - - return (result.size() == 0) ? null : result.next(); - } - - /** - * Get an iterator of all boards. - */ - public synchronized Iterator<FMSBoard> boardIterator() { - /* FIXME: Accelerate this query. db4o should be configured to keep an alphabetic index of boards */ - Query query = db.query(); - query.constrain(FMSBoard.class); - query.descend("mName").orderDescending(); - - ObjectSet<FMSBoard> result = query.execute(); - - return result.iterator(); - } - - /** - * Returns true if the message was not downloaded yet and any of the FMSOwnIdentity wants the message. - */ - protected synchronized boolean shouldDownloadMessage(FreenetURI uri, FMSIdentity author) { - return (get(uri) != null) || mIdentityManager.anyOwnIdentityWantsMessagesFrom(author); - } -} Deleted: trunk/plugins/Freetalk/FMSOwnIdentity.java =================================================================== --- trunk/plugins/Freetalk/FMSOwnIdentity.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/FMSOwnIdentity.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,30 +0,0 @@ -/* 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 plugins.Freetalk; - -import java.util.Date; -import java.util.Iterator; - -import freenet.keys.FreenetURI; - -/** - * @author saces, xor - * - */ -public interface FMSOwnIdentity extends FMSIdentity { - - public FreenetURI getInsertURI(); - - public Date getLastInsert(); - - public boolean wantsMessagesFrom(FMSIdentity identity); - - public void postMessage(FMSMessage message); - - public void subscribeToBoard(FMSBoard board); - - public void unsubscribeFromBoard(FMSBoard board); - - public Iterator<FMSBoard> subscribedBoardsIterator(); -} Copied: trunk/plugins/Freetalk/FTBoard.java (from rev 23328, trunk/plugins/Freetalk/FMSBoard.java) =================================================================== --- trunk/plugins/Freetalk/FTBoard.java (rev 0) +++ trunk/plugins/Freetalk/FTBoard.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,232 @@ +/* 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 plugins.Freetalk; + +import java.util.Iterator; + +import com.db4o.ObjectContainer; +import com.db4o.ObjectSet; +import com.db4o.query.Query; + +import freenet.keys.FreenetURI; +import freenet.support.UpdatableSortedLinkedListKilledException; + +/** + * @author xor + * + */ +public class FTBoard { + + private transient final ObjectContainer db; + + private transient final FMSBoard self = this; + + private transient final FMSMessageManager mMessageManager; + + private final String mName; + + /** + * Get a list of fields which the database should create an index on. + */ + public static String[] getIndexedFields() { + return new String[] {"mName"}; + } + + public FTBoard(ObjectContainer myDB, FMSMessageManager newMessageManager, String newName) { + if(newName==null || newName.length() == 0) + throw new IllegalArgumentException("Empty board name."); + + assert(myDB != null); + assert(newMessageManager != null); + + db = myDB; + mMessageManager = newMessageManager; + // FIXME: Validate name and description. + mName = newName; + + db.store(this); + db.commit(); + } + + /** + * @return The name. + */ + public String getName() { + return mName; + } + + /** + * Called by the <code>FMSMessageManager</code> to add a just received message to the board. + * The job for this function is to find the right place in the thread-tree for the new message and to move around older messages + * if a parent message of them is received. + */ + public synchronized void addMessage(FMSMessage newMessage) throws UpdatableSortedLinkedListKilledException { + synchronized(mMessageManager) { + db.store(newMessage); + db.commit(); + + if(!newMessage.isThread()) + { + FreenetURI parentURI = newMessage.getParentURI(); + FMSMessage parentMessage = mMessageManager.get(parentURI); /* TODO: This allows crossposting. Figure out whether we need to handle it specially */ + FMSMessage parentThread = findParentThread(newMessage); + + if(parentThread != null) + newMessage.setThread(parentThread); + + if(parentMessage != null) { + newMessage.setParent(parentMessage); + } else { /* The message is an orphan */ + if(parentThread != null) { + newMessage.setParent(parentThread); /* We found its parent thread so just stick it in there for now */ + } + else { + /* The message is an absolute orphan */ + + /* + * FIXME: The MessageManager should try to download the parent message if it's poster has enough trust. + * If it is programmed to do that, it will check its Hashtable whether the parent message already exists. + * We also do that here, therefore, when implementing parent message downloading, please do the Hashtable checking only once. + */ + } + } + } + + linkOrphansToNewParent(newMessage); + } + } + + private synchronized void linkOrphansToNewParent(FMSMessage newMessage) throws UpdatableSortedLinkedListKilledException { + if(newMessage.isThread()) { + Iterator<FMSMessage> absoluteOrphans = absoluteOrphanIterator(newMessage.getURI()); + while(absoluteOrphans.hasNext()){ /* Search in the absolute orphans for messages which belong to this thread */ + FMSMessage orphan = absoluteOrphans.next(); + orphan.setParent(newMessage); + } + } + else { + FMSMessage parentThread = newMessage.getThread(); + if(parentThread != null) { /* Search in its parent thread for its children */ + Iterator<FMSMessage> iter = parentThread.childrenIterator(this); + while(iter.hasNext()) { + FMSMessage parentThreadChild = iter.next(); + + if(parentThreadChild.getParentURI().equals(newMessage.getURI())) { /* We found its parent, yeah! */ + parentThreadChild.setParent(newMessage); /* It's a child of the newMessage, not of the parentThread */ + } + } + } + else { /* The new message is an absolute orphan, find its children amongst the other absolute orphans */ + Iterator<FMSMessage> absoluteOrphans = absoluteOrphanIterator(newMessage.getURI()); + while(absoluteOrphans.hasNext()){ /* Search in the orphans for messages which belong to this message */ + FMSMessage orphan = absoluteOrphans.next(); + /* + * The following if() could be joined into the db4o query in absoluteOrphanIterator(). I did not do it because we could + * cache the list of absolute orphans locally. + */ + if(orphan.getParentURI().equals(newMessage.getURI())) + orphan.setParent(newMessage); + } + } + } + } + + protected synchronized FMSMessage findParentThread(FMSMessage m) { + Query q = db.query(); + q.constrain(FMSMessage.class); + /* FIXME: I assume that db4o is configured to keep an URI index per board. We still have to ensure in FMS.java that it is configured to do so. + * If my second assumption - that the descend() statements are evaluated in the specified order - is true, then it might be faste because the + * URI index is smaller per board than the global URI index. */ + q.descend("mBoards").constrain(mName); + q.descend("mURI").constrain(m.getParentThreadURI()); + ObjectSet<FMSMessage> parents = q.execute(); + + assert(parents.size() <= 1); + + return (parents.size() != 0 ? parents.next() : null); + } + + + /** + * Get all threads in the board. The view is specified to the FMSOwnIdentity displaying it, therefore you have to pass one as parameter. + * @param identity The identity viewing the board. + * @return An iterator of the message which the identity will see (based on its trust levels). + */ + public synchronized Iterator<FMSMessage> threadIterator(final FMSOwnIdentity identity) { + return new Iterator<FMSMessage>() { + private final FMSOwnIdentity mIdentity = identity; + private final Iterator<FMSMessage> iter; + private FMSMessage next; + + { + /* FIXME: If db4o supports precompiled queries, this one should be stored precompiled. + * Reason: We sort the threads by date. + * Maybe we can just keep the Query-object and call q.execute() as many times as we like to? + * Or somehow tell db4o to keep a per-board thread index which is sorted by Date? - This would be the best solution */ + Query q = db.query(); + q.constrain(FMSMessage.class); + q.descend("mBoards").constrain(mName); /* FIXME: mBoards is an array. Does constrain() check whether it contains the element mName? */ + q.descend("mThread").constrain(null); + q.descend("mDate").orderDescending(); + + iter = q.execute().iterator(); + next = iter.hasNext() ? iter.next() : null; + } + + public boolean hasNext() { + for(; next != null; next = iter.hasNext() ? iter.next() : null) + { + if(mIdentity.wantsMessagesFrom(identity)) + return true; + } + return false; + } + + public FMSMessage next() { + FMSMessage result = hasNext() ? next : null; + next = iter.hasNext() ? iter.next() : null; + return result; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + + /** + * Get an iterator over messages for which the parent thread with the given URI was not known. + */ + public synchronized Iterator<FMSMessage> absoluteOrphanIterator(final FreenetURI thread) { + return new Iterator<FMSMessage>() { + private final ObjectSet<FMSMessage> mMessages; + private final Iterator<FMSMessage> iter; + + { + /* FIXME: This query should be accelerated. The amount of absolute orphans is very small usually, so we should configure db4o + * to keep a separate list of those. */ + Query q = db.query(); + q.constrain(FMSMessage.class); + q.descend("mBoards").constrain(mName); /* FIXME: mBoards is an array. Does constrain() check whether it contains the element mName? */ + q.descend("mThreadURI").constrain(thread); + q.descend("mThread").constrain(null); + mMessages = q.execute(); + iter = mMessages.iterator(); + } + + public boolean hasNext() { + return mMessages.hasNext(); + } + + public FMSMessage next() { + return mMessages.next(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } +} Copied: trunk/plugins/Freetalk/FTDealer.java (from rev 23328, trunk/plugins/Freetalk/FMSDealer.java) =================================================================== --- trunk/plugins/Freetalk/FTDealer.java (rev 0) +++ trunk/plugins/Freetalk/FTDealer.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,31 @@ +/* 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 plugins.Freetalk; + +import freenet.support.Executor; +import freenet.support.Logger; + +public class FTDealer { + + private final Executor _executor; + + // services + private FMSIdentityManager identManager; + + FTDealer(Executor executor) { + this._executor = executor; + _executor.execute(new Runnable() { + public void run() { + startDealer(); + }}, "Dealer starter"); + } + + private void startDealer() { + Logger.error(this, "Starting dealer", new Error("TODO")); + } + + synchronized void killMe() { + Logger.error(this, "Killing dealer", new Error("TODO")); + } +} Copied: trunk/plugins/Freetalk/FTIdentity.java (from rev 23328, trunk/plugins/Freetalk/FMSIdentity.java) =================================================================== --- trunk/plugins/Freetalk/FTIdentity.java (rev 0) +++ trunk/plugins/Freetalk/FTIdentity.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,26 @@ +/* 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 plugins.Freetalk; + +import java.util.Date; +import java.util.Iterator; + +import freenet.keys.FreenetURI; + +public interface FTIdentity { + + /** + * @return The requestURI ({@link FreenetURI}) to fetch this Identity + */ + public FreenetURI getRequestURI(); + + public String getNickName(); + + public Date getLastChange(); + + /** + * @return Whether this Identity publishes its trustList or not + */ + public boolean doesPublishTrustList(); +} Copied: trunk/plugins/Freetalk/FTIdentityManager.java (from rev 23328, trunk/plugins/Freetalk/FMSIdentityManager.java) =================================================================== --- trunk/plugins/Freetalk/FTIdentityManager.java (rev 0) +++ trunk/plugins/Freetalk/FTIdentityManager.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,49 @@ +/* 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 plugins.Freetalk; + +import java.util.Iterator; + +import com.db4o.ObjectContainer; +import com.db4o.ObjectSet; + +import freenet.support.Executor; + +/** + * @author saces, xor + * + */ +public abstract class FTIdentityManager implements Iterable<FMSIdentity> { + + protected final ObjectContainer db; + + protected final Executor mExecutor; + + public FTIdentityManager(ObjectContainer myDB, Executor newExecutor) { + db = myDB; + mExecutor = newExecutor; + } + + public synchronized Iterator<FMSIdentity> iterator() { + ObjectSet<FMSIdentity> ids = db.query(FMSIdentity.class); + return ids.iterator(); + } + + public synchronized Iterator<FMSOwnIdentity> ownIdentityIterator() { + ObjectSet<FMSOwnIdentity> oids = db.query(FMSOwnIdentity.class); + return oids.iterator(); + } + + public synchronized boolean anyOwnIdentityWantsMessagesFrom(FMSIdentity identity) { + Iterator<FMSOwnIdentity> iter = ownIdentityIterator(); + + while (iter.hasNext()) { + FMSOwnIdentity oid = iter.next(); + if (oid.wantsMessagesFrom(identity)) + return true; + } + + return false; + } +} Copied: trunk/plugins/Freetalk/FTMessage.java (from rev 23328, trunk/plugins/Freetalk/FMSMessage.java) =================================================================== --- trunk/plugins/Freetalk/FTMessage.java (rev 0) +++ trunk/plugins/Freetalk/FTMessage.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,265 @@ +/* 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 plugins.Freetalk; + +import java.util.Arrays; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import com.db4o.ObjectContainer; +import com.db4o.query.Query; + +import freenet.keys.FreenetURI; +import freenet.support.UpdatableSortedLinkedListKilledException; + +/** + * @author saces, xor + * + */ +public abstract class FTMessage { + + protected ObjectContainer db; + + /** + * The URI of this message. + */ + private final FreenetURI mURI; + + /** + * The URI of the thread this message belongs to. + * We do not need it to construct the thread-tree from messages, but it boosts performance of thread-tree-construction: + * Thread-size (amount of replies) is usually infinitesimal compared to the size of a FMSBoard (amount of threads). + * We receive messages in random order, therefore we will usually have orphan messages of which we need to find the parents. + * If we receive the parent messages of those messages, we will be able to find their orphan children faster if we only need to search in + * the thread they belong to and not in the whole FMSBoard - which may contain many thousands of messages. + */ + private final FreenetURI mThreadURI; + + /** + * The URI of the message to which this message is a reply. Null if it is a thread. + */ + private final FreenetURI mParentURI; + + /** + * The boards to which this message was posted, in alphabetical order. + */ + private final FMSBoard[] mBoards; + + private final FMSIdentity mAuthor; + + private final String mTitle; + + /** + * The date when the message was written in <strong>UTC time</strong>. + */ + private final Date mDate; + + private final String mText; + + /** + * The attachments of this message, in the order in which they were received in the original message. + */ + private final FreenetURI[] mAttachments; + + /** + * The thread to which this message is a reply. + */ + private FMSMessage mThread = null; + + /** + * The message to which this message is a reply. + */ + private FMSMessage mParent = null; + + /** + * Get a list of fields which the database should create an index on. + */ + public static String[] getIndexedFields() { + return new String[] { "mURI", "mThreadURI", "mBoards"}; + } + + public FTMessage(ObjectContainer db, FreenetURI newURI, FreenetURI newThreadURI, FreenetURI newParentURI, Set<FMSBoard> newBoards, FMSIdentity newAuthor, String newTitle, Date newDate, String newText, List<FreenetURI> newAttachments) { + if (newURI == null || newBoards == null || newAuthor == null) + throw new IllegalArgumentException(); + + if (newBoards.isEmpty()) + throw new IllegalArgumentException("No boards in message " + newURI); + + if (!isTitleValid(newTitle)) + throw new IllegalArgumentException("Invalid message title in message " + newURI); + + if (!isTextValid(newText)) + throw new IllegalArgumentException("Invalid message text in message " + newURI); + + mURI = newURI; + mThreadURI = newThreadURI; + mParentURI = newParentURI; + mBoards = (FMSBoard[])newBoards.toArray(); + Arrays.sort(mBoards); + mAuthor = newAuthor; + mTitle = newTitle; + mDate = newDate; // TODO: Check out whether Date provides a function for getting the timezone and throw an Exception if not UTC. + mText = newText; + mAttachments = newAttachments!=null ? (FreenetURI[])newAttachments.toArray() : new FreenetURI[0]; + } + + /** + * Get the URI of the message. + */ + public FreenetURI getURI() { + return mURI; + } + + /** + * Get the FreenetURI of the thread this message belongs to. + */ + public FreenetURI getParentThreadURI() { + return mThreadURI; + } + + /** + * Get the FreenetURI to which this message is a reply. Null if the message is a thread. + */ + public FreenetURI getParentURI() { + return mParentURI; + } + + public boolean isThread() { + return getParentURI() == null; + } + + /** + * Get the boards to which this message was posted. + * The boards are returned in alphabetical order. + */ + public FMSBoard[] getBoards() { + return mBoards; + } + + /** + * Get the author of the message. + */ + public FMSIdentity getAuthor() { + return mAuthor; + } + + /** + * Get the title of the message. + */ + public String getTitle() { + return mTitle; + } + + /** + * Get the date when the message was written in <strong>UTC time</strong>. + */ + public Date getDate() { + return mDate; + } + + /** + * Get the text of the message. + */ + public String getText() { + return mText; + } + + /** + * Get the attachments of the message, in the order in which they were received. + */ + public FreenetURI[] getAttachments() { + return mAttachments; + } + + public synchronized FMSMessage getThread() { + return mThread; + } + + public synchronized void setThread(FMSMessage newParentThread) { + assert(mThread == null); + assert(mThreadURI == null); + mThread = newParentThread; + db.store(this); + db.commit(); + } + + public synchronized FMSMessage getParent() { + return mParent; + } + + public synchronized void setParent(FMSMessage newParent) throws UpdatableSortedLinkedListKilledException { + /* TODO: assert(newParent contains at least one board which mBoards contains) */ + mParent = newParent; + db.store(this); + db.commit(); + } + + public synchronized Iterator<FMSMessage> childrenIterator(final FMSBoard board) { + return new Iterator<FMSMessage>() { + private Iterator<FMSMessage> iter; + + { + /* TODO: Accelerate this query: configure db4o to keep a per-message date-sorted index of children. + * - Not very important for now since threads are usually small. */ + Query q = db.query(); + q.constrain(FMSMessage.class); + q.descend("mBoard").constrain(board.getName()); + q.descend("mParent").constrain(this); + q.descend("mDate").orderDescending(); + + iter = q.execute().iterator(); + } + + public boolean hasNext() { + return iter.hasNext(); + } + + public FMSMessage next() { + return iter.next(); + } + + public void remove() { + throw new UnsupportedOperationException("Use child.setParent(null) instead."); + } + }; + } + + /** + * Checks whether the title of the message is valid. Validity conditions: + * - ... + */ + static public boolean isTitleValid(String title) { + // FIXME: Implement. + return true; + } + + /** + * Checks whether the text of the message is valid. Validity conditions: + * - ... + */ + static public boolean isTextValid(String text) { + // FIXME: Implement. + return true; + } + + /** + * Makes the passed title valid in means of <code>isTitleValid()</code> + * @see isTitleValid + */ + static public String makeTitleValid(String title) { + // FIXME: Implement. + return title; + } + + /** + * Makes the passed text valid in means of <code>isTextValid()</code> + * @see isTextValid + */ + static public String makeTextValid(String text) { + // FIXME: Implement. + return text; + } +} Copied: trunk/plugins/Freetalk/FTMessageManager.java (from rev 23328, trunk/plugins/Freetalk/FMSMessageManager.java) =================================================================== --- trunk/plugins/Freetalk/FTMessageManager.java (rev 0) +++ trunk/plugins/Freetalk/FTMessageManager.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,74 @@ +/* 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 plugins.Freetalk; + +import java.util.Iterator; + +import com.db4o.ObjectContainer; +import com.db4o.ObjectSet; +import com.db4o.query.Query; + +import freenet.keys.FreenetURI; + +/** + * @author xor + * + */ +public abstract class FTMessageManager { + + protected ObjectContainer db; + + protected FMSIdentityManager mIdentityManager; + + public FTMessageManager(ObjectContainer myDB, FMSIdentityManager myIdentityManager) { + assert(myDB != null); + assert(myIdentityManager != null); + + db = myDB; + mIdentityManager = myIdentityManager; + } + + public synchronized FMSMessage get(FreenetURI uri) { + Query query = db.query(); + query.constrain(FMSMessage.class); + query.descend("mURI").constrain(uri); + ObjectSet<FMSMessage> result = query.execute(); + + assert(result.size() <= 1); + + return (result.size() == 0) ? null : result.next(); + } + + public synchronized FMSBoard getBoardByName(String name) { + Query query = db.query(); + query.constrain(FMSBoard.class); + query.descend("mName").constrain(name); + ObjectSet<FMSBoard> result = query.execute(); + + assert(result.size() <= 1); + + return (result.size() == 0) ? null : result.next(); + } + + /** + * Get an iterator of all boards. + */ + public synchronized Iterator<FMSBoard> boardIterator() { + /* FIXME: Accelerate this query. db4o should be configured to keep an alphabetic index of boards */ + Query query = db.query(); + query.constrain(FMSBoard.class); + query.descend("mName").orderDescending(); + + ObjectSet<FMSBoard> result = query.execute(); + + return result.iterator(); + } + + /** + * Returns true if the message was not downloaded yet and any of the FMSOwnIdentity wants the message. + */ + protected synchronized boolean shouldDownloadMessage(FreenetURI uri, FMSIdentity author) { + return (get(uri) != null) || mIdentityManager.anyOwnIdentityWantsMessagesFrom(author); + } +} Copied: trunk/plugins/Freetalk/FTOwnIdentity.java (from rev 23328, trunk/plugins/Freetalk/FMSOwnIdentity.java) =================================================================== --- trunk/plugins/Freetalk/FTOwnIdentity.java (rev 0) +++ trunk/plugins/Freetalk/FTOwnIdentity.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,30 @@ +/* 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 plugins.Freetalk; + +import java.util.Date; +import java.util.Iterator; + +import freenet.keys.FreenetURI; + +/** + * @author saces, xor + * + */ +public interface FTOwnIdentity extends FMSIdentity { + + public FreenetURI getInsertURI(); + + public Date getLastInsert(); + + public boolean wantsMessagesFrom(FMSIdentity identity); + + public void postMessage(FMSMessage message); + + public void subscribeToBoard(FMSBoard board); + + public void unsubscribeFromBoard(FMSBoard board); + + public Iterator<FMSBoard> subscribedBoardsIterator(); +} Copied: trunk/plugins/Freetalk/Freetalk.java (from rev 23328, trunk/plugins/Freetalk/FMS.java) =================================================================== --- trunk/plugins/Freetalk/Freetalk.java (rev 0) +++ trunk/plugins/Freetalk/Freetalk.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,347 @@ +/* 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 plugins.Freetalk; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import plugins.FMSPlugin.ui.Errors; +import plugins.FMSPlugin.ui.IdentityEditor; +import plugins.FMSPlugin.ui.Messages; +import plugins.FMSPlugin.ui.Status; +import plugins.FMSPlugin.ui.Welcome; + +import com.db4o.Db4o; +import com.db4o.ObjectContainer; +import com.db4o.ObjectSet; +import com.db4o.config.Configuration; + +import freenet.client.HighLevelSimpleClient; +import freenet.clients.http.PageMaker; +import freenet.clients.http.PageMaker.THEME; +import freenet.keys.FreenetURI; +import freenet.l10n.L10n.LANGUAGE; +import freenet.pluginmanager.DownloadPluginHTTPException; +import freenet.pluginmanager.FredPlugin; +import freenet.pluginmanager.FredPluginFCP; +import freenet.pluginmanager.FredPluginHTTP; +import freenet.pluginmanager.FredPluginL10n; +import freenet.pluginmanager.FredPluginThemed; +import freenet.pluginmanager.FredPluginThreadless; +import freenet.pluginmanager.FredPluginVersioned; +import freenet.pluginmanager.NotFoundPluginHTTPException; +import freenet.pluginmanager.PluginHTTPException; +import freenet.pluginmanager.PluginReplySender; +import freenet.pluginmanager.PluginRespirator; +import freenet.pluginmanager.RedirectPluginHTTPException; +import freenet.support.HTMLNode; +import freenet.support.Logger; +import freenet.support.SimpleFieldSet; +import freenet.support.api.Bucket; +import freenet.support.api.HTTPRequest; +import freenet.support.api.HTTPUploadedFile; +import freenet.support.io.TempBucketFactory; + +/** + * @author saces + * + */ +public class Freetalk implements FredPlugin, FredPluginFCP, FredPluginHTTP, FredPluginL10n, FredPluginThemed, FredPluginThreadless, FredPluginVersioned { + + public static String SELF_URI = "/plugins/plugins.FMSPlugin.FMSPlugin"; + public static String SELF_TITLE = "Freenet Message System"; + public static String WOT_NAME = "plugins.WoT.WoT"; + + public final String MESSAGEBASE = "fms"; + + public PluginRespirator pr; + + public PageMaker pm; + + private LANGUAGE language; + private THEME theme; + + private HighLevelSimpleClient client; + + private FTDealer dealer; + + public ObjectContainer db_config; + public ObjectContainer db_cache; + + public TempBucketFactory tbf; + + public void runPlugin(PluginRespirator pr2) { + + Logger.error(this, "Start"); + + pr = pr2; + + pm = pr.getPageMaker(); + pm.addNavigationLink(SELF_URI + "/", "Home", "FMS plugin home", false, null); + pm.addNavigationLink(SELF_URI + "/ownidentities", "Own Identities", "Manage your own identities", false, null); + pm.addNavigationLink(SELF_URI + "/knownidentities", "Known Identities", "Manage others identities", false, null); + pm.addNavigationLink(SELF_URI + "/messages", "Messages", "View Messages", false, null); + pm.addNavigationLink(SELF_URI + "/status", "Dealer status", "Show what happens in background", false, null); + pm.addNavigationLink("/", "Fproxy", "Back to nodes home", false, null); + + client = pr.getHLSimpleClient(); + + Configuration config_config = Db4o.newConfiguration(); + /* We re-use all information from the WoT-plugin's database. + config_config.objectClass(FMSOwnIdentity.class).objectField("requestUri").indexed(true); + config_config.objectClass(FMSIdentity.class).objectField("requestUri").indexed(true); + */ + db_config = Db4o.openFile(config_config, "fms_conf.db4o"); + + Configuration cache_config = Db4o.newConfiguration(); + for(String f : FMSMessage.getIndexedFields()) + cache_config.objectClass(FMSMessage.class).objectField(f).indexed(true); + cache_config.objectClass(FMSMessage.class).cascadeOnUpdate(true); + // TODO: decide about cascade on delete. + for(String f : FMSBoard.getIndexedFields()) + cache_config.objectClass(FMSBoard.class).objectField(f).indexed(true); + + db_cache = Db4o.openFile(cache_config, "fms_cache.db4o"); + + // while develop wipe cache on startup + ObjectSet<Object> result = db_cache.queryByExample(new Object()); + if (result.size() > 0) { + for (Object o : result) { + db_cache.delete(o); + } + db_cache.commit(); + } + + dealer = new FTDealer(pr.getNode().executor); + + tbf = pr.getNode().clientCore.tempBucketFactory; + } + + public void terminate() { + dealer.killMe(); + db_config.close(); + db_cache.close(); + } + + public String handleHTTPGet(HTTPRequest request) throws PluginHTTPException { + + if (request.isParameterSet("formPassword")) { + String pass = request.getParam("formPassword"); + if ((pass.length() == 0) || !pass.equals(pr.getNode().clientCore.formPassword)) { + return Errors.makeErrorPage(this, "Buh! Invalid form password"); + } + } + + String page = request.getPath().substring(SELF_URI.length()); + if ((page.length() < 1) || ("/".equals(page))) + return Welcome.makeWelcomePage(this); + + if ("/status".equals(page)) { + return Status.makeStatusPage(this); + } + + if ("/ownidentities".equals(page)) + return IdentityEditor.makeOwnIdentitiesPage(this, request); + + if ("/knownidentities".equals(page)) + return IdentityEditor.makeKnownIdentitiesPage(this, request); + + if ("/messages".equals(page)) + return Messages.makeMessagesPage(this, request); + + throw new NotFoundPluginHTTPException("Resource not found in FMSPlugin", page); + } + + public void handle(PluginReplySender replysender, SimpleFieldSet params, Bucket data, int accesstype) { + SimpleFieldSet sfs = new SimpleFieldSet(true); + sfs.putOverwrite("Hello", "Nice try ;)"); + sfs.putOverwrite("Sorry", "Not implemeted yet :("); + } + + public String handleHTTPPost(HTTPRequest request) throws PluginHTTPException { + String pass = request.getPartAsString("formPassword", 32); + if ((pass.length() == 0) || !pass.equals(pr.getNode().clientCore.formPassword)) { + return Errors.makeErrorPage(this, "Buh! Invalid form password"); + } + + String page = request.getPath().substring(SELF_URI.length()); + + if (page.length() < 1) + throw new NotFoundPluginHTTPException("Resource not found", page); + + if (page.equals("/exportDB")) { + StringWriter sw = new StringWriter(); + try { + Backup.exportConfigDb(db_config, sw); + } catch (IOException e) { + Logger.error(this, "Error While exporting database!", e); + return Errors.makeErrorPage(this, "Server BuhBuh! " + e.getMessage()); + } + throw new DownloadPluginHTTPException(sw.toString().getBytes(), "fms-kidding.xml", "fms-clone/db-backup"); + } + + if (page.equals("/importDB")) { + HTTPUploadedFile file = request.getUploadedFile("filename"); + if (file == null || file.getFilename().trim().length() == 0) { + return Errors.makeErrorPage(this, "No file to import selected!"); + } + try { + Backup.importConfigDb(db_config, file.getData().getInputStream()); + } catch (Exception e) { + Logger.error(this, "Error While importing db from: " + file.getFilename(), e); + return Errors.makeErrorPage(this, "Error While importing db from: " + file.getFilename() + e.getMessage()); + } + throw new RedirectPluginHTTPException("", SELF_URI); + } + + if (page.equals("/createownidentity")) { + List<String> err = new ArrayList<String>(); + String nick = request.getPartAsString("nick", 1024).trim(); + String requestUri = request.getPartAsString("requestURI", 1024); + String insertUri = request.getPartAsString("insertURI", 1024); + boolean publish = "true".equals(request.getPartAsString("publishTrustList", 24)); + + IdentityEditor.checkNick(err, nick); + + if ((requestUri.length() == 0) && (insertUri.length() == 0)) { + FreenetURI[] kp = client.generateKeyPair("fms"); + insertUri = kp[0].toString(); + requestUri = kp[1].toString(); + err.add("URI was empty, I generated one for you."); + return IdentityEditor.makeNewOwnIdentityPage(this, nick, requestUri, insertUri, publish, err); + } + + IdentityEditor.checkInsertURI(err, insertUri); + IdentityEditor.checkRequestURI(err, requestUri); + + if (err.size() == 0) { + // FIXME: use identity manager to implement this + throw new UnsupportedOperationException(); + /* + FMSOwnIdentity oi = new FMSOwnIdentity(nick, requestUri, insertUri, publish); + IdentityEditor.addNewOwnIdentity(db_config, oi, err); + */ + } + + if (err.size() == 0) { + throw new RedirectPluginHTTPException("", SELF_URI + "/ownidentities"); + } + + return IdentityEditor.makeNewOwnIdentityPage(this, nick, requestUri, insertUri, publish, err); + } + + if (page.equals("/addknownidentity")) { + List<String> err = new ArrayList<String>(); + + String requestUri = request.getPartAsString("requestURI", 1024); + + if (requestUri.length() == 0) { + err.add("Are you jokingly? URI was empty."); + return IdentityEditor.makeNewKnownIdentityPage(this, requestUri, err); + } + + IdentityEditor.checkRequestURI(err, requestUri); + + if (err.size() == 0) { + // FIXME: use identity manager to implement this + throw new UnsupportedOperationException(); + /* + FMSIdentity i = new FMSIdentity("", requestUri); + IdentityEditor.addNewKnownIdentity(db_config, i, err); + */ + } + + if (err.size() == 0) { + throw new RedirectPluginHTTPException("", SELF_URI + "/knownidentities"); + } + + return IdentityEditor.makeNewKnownIdentityPage(this, requestUri, err); + } + + if (page.equals("/deleteOwnIdentity")) { + List<String> err = new ArrayList<String>(); + + String requestUri = request.getPartAsString("identity", 1024); + if (requestUri.length() == 0) { + err.add("Are you jokingly? URI was empty."); + return IdentityEditor.makeDeleteOwnIdentityPage(this, requestUri, err); + } + + if (request.isPartSet("confirmed")) { + IdentityEditor.deleteIdentity(this, requestUri, err); + } else { + err.add("Please confirm."); + } + + if (err.size() > 0) { + return IdentityEditor.makeDeleteOwnIdentityPage(this, requestUri, err); + } + throw new RedirectPluginHTTPException("", SELF_URI + "/ownidentities"); + // return IdentityEditor.makeDeleteOwnIdentityPage(fms, requestUri, + // err); + } + + if (page.equals("/deleteIdentity")) { + List<String> err = new ArrayList<String>(); + + String requestUri = request.getPartAsString("identity", 1024); + if (requestUri.length() == 0) { + err.add("Are you jokingly? URI was empty."); + return IdentityEditor.makeDeleteKnownIdentityPage(this, requestUri, err); + } + + if (request.isPartSet("confirmed")) { + IdentityEditor.deleteIdentity(this, requestUri, err); + } else { + err.add("Please confirm."); + } + + if (err.size() > 0) { + return IdentityEditor.makeDeleteKnownIdentityPage(this, requestUri, err); + } + throw new RedirectPluginHTTPException("", SELF_URI + "/knownidentities"); + } + throw new NotFoundPluginHTTPException("Resource not found", page); + } + + public String getVersion() { + return "? r" + Version.svnRevision; + } + + public String getString(String key) { + // Logger.error(this, "Request translation for "+key); + return key; + } + + public void setLanguage(LANGUAGE newLanguage) { + language = newLanguage; + Logger.error(this, "Set LANGUAGE to: " + language.isoCode); + } + + public void setTheme(THEME newTheme) { + theme= newTheme; + Logger.error(this, "Set THEME to: " + theme.code); + } + + public boolean isWoTpresent() { + FredPluginFCP plug = pr.getNode().pluginManager.getFCPPlugin(FMS.WOT_NAME); + return (plug != null); + } + + public long countIdentities() { + return db_config.queryByExample(FMSIdentity.class).size() - countOwnIdentities(); + } + + public long countOwnIdentities() { + return db_config.queryByExample(FMSOwnIdentity.class).size(); + } + + + final public HTMLNode getPageNode() { + return pm.getPageNode(FMS.SELF_TITLE, null); + } + +} Deleted: trunk/plugins/Freetalk/WoT/FMSIdentityManagerWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FMSIdentityManagerWoT.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/WoT/FMSIdentityManagerWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,30 +0,0 @@ -/* 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 plugins.Freetalk.WoT; - -import plugins.FMSPlugin.FMSIdentityManager; -import plugins.WoT.WoT; - -import com.db4o.ObjectContainer; - -import freenet.support.Executor; - -/** - * An identity manager which uses the identities from the WoT plugin. - * - * @author xor - * - */ -public class FMSIdentityManagerWoT extends FMSIdentityManager { - - private WoT mWoT; - - /** - * @param executor - */ - public FMSIdentityManagerWoT(ObjectContainer myDB, Executor executor, WoT newWoT) { - super(myDB, executor); - mWoT = newWoT; - } -} Deleted: trunk/plugins/Freetalk/WoT/FMSIdentityWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FMSIdentityWoT.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/WoT/FMSIdentityWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,41 +0,0 @@ -/* 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 plugins.Freetalk.WoT; - -import java.util.Date; - -import freenet.keys.FreenetURI; -import plugins.FMSPlugin.FMSIdentity; - -import plugins.WoT.Identity; - -/** - * @author xor - * - */ -public class FMSIdentityWoT implements FMSIdentity { - - protected final Identity mIdentity; - - public FMSIdentityWoT(Identity newIndentity) { - mIdentity = newIndentity; - } - - public boolean doesPublishTrustList() { - return mIdentity.doesPublishTrustList(); - } - - public Date getLastChange() { - return mIdentity.getLastChange(); - } - - public String getNickName() { - return mIdentity.getNickName(); - } - - public FreenetURI getRequestURI() { - return mIdentity.getRequestURI(); - } - -} Deleted: trunk/plugins/Freetalk/WoT/FMSMessageManagerWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FMSMessageManagerWoT.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/WoT/FMSMessageManagerWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,50 +0,0 @@ -/* 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 plugins.Freetalk.WoT; - -import java.util.NoSuchElementException; - -import plugins.FMSPlugin.FMSBoard; -import plugins.FMSPlugin.FMSMessageManager; - -import com.db4o.ObjectContainer; - -import freenet.keys.FreenetURI; -import freenet.support.UpdatableSortedLinkedListKilledException; - -public class FMSMessageManagerWoT extends FMSMessageManager { - - protected FMSIdentityManagerWoT mIdentityManager; - - public FMSMessageManagerWoT(ObjectContainer myDB, FMSIdentityManagerWoT myIdentityManager) { - super(myDB, myIdentityManager); - mIdentityManager = myIdentityManager; - } - - protected synchronized void deleteMessage(FreenetURI uri) throws NoSuchElementException { - /* FIXME: implement */ - } - - private synchronized void onMessageReceived(String newMessageData) throws UpdatableSortedLinkedListKilledException { - FMSMessageWoT newMessage = new FMSMessageWoT(db, null, null, null, null, null, null, null, null, null); - String boardName = ""; - /* FIXME: Store the description in FMSOwnIdentity. We cannot store in FMSBoard because we want to allow per-identity customization */ - - String[] boardNames = new String[0]; - FMSBoard[] boards = new FMSBoard[boardNames.length]; - - for(int idx = 0; idx < boards.length; ++idx) { - FMSBoard board = getBoardByName(boardNames[idx]); - - if(board == null) - board = new FMSBoard(db, this, boardName); - - boards[idx] = board; - } - - for(FMSBoard b : boards) { - b.addMessage(newMessage); - } - } -} Deleted: trunk/plugins/Freetalk/WoT/FMSMessageWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FMSMessageWoT.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/WoT/FMSMessageWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,31 +0,0 @@ -/* 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 plugins.Freetalk.WoT; - -import java.util.Date; -import java.util.List; -import java.util.Set; - -import plugins.FMSPlugin.FMSBoard; -import plugins.FMSPlugin.FMSIdentity; -import plugins.FMSPlugin.FMSMessage; - -import com.db4o.ObjectContainer; - -import freenet.keys.FreenetURI; - -/** - * @author xor - * - */ -public class FMSMessageWoT extends FMSMessage { - - public FMSMessageWoT(ObjectContainer myDB, FreenetURI newURI, FreenetURI newThreadURI, FreenetURI newParentURI, Set<FMSBoard> newBoards, FMSIdentity newAuthor, - String newTitle, Date newDate, String newText, List<FreenetURI> newAttachments) { - super(myDB, newURI, newThreadURI, newParentURI, newBoards, newAuthor, newTitle, newDate, newText, newAttachments); - // TODO Auto-generated constructor stub - } - - -} Deleted: trunk/plugins/Freetalk/WoT/FMSOwnIdentityWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FMSOwnIdentityWoT.java 2008-11-06 00:42:59 UTC (rev 23328) +++ trunk/plugins/Freetalk/WoT/FMSOwnIdentityWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -1,85 +0,0 @@ -/* 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 plugins.Freetalk.WoT; - -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; - -import plugins.FMSPlugin.FMSBoard; -import plugins.FMSPlugin.FMSIdentity; -import plugins.FMSPlugin.FMSMessage; -import plugins.FMSPlugin.FMSOwnIdentity; -import plugins.WoT.OwnIdentity; -import freenet.keys.FreenetURI; - -/** - * @author xor - * - */ -public class FMSOwnIdentityWoT extends FMSIdentityWoT implements FMSOwnIdentity { - - private final LinkedList<FMSBoard> mSubscribedBoards = new LinkedList<FMSBoard>(); - - public FMSOwnIdentityWoT(OwnIdentity newIndentity) { - super(newIndentity); - } - - protected OwnIdentity getOwnIdentity() { - return (OwnIdentity)mIdentity; - } - - public FreenetURI getInsertURI() { - return getOwnIdentity().getInsertURI(); - } - - public synchronized Date getLastInsert() { - return getOwnIdentity().getLastInsert(); - } - - public synchronized void postMessage(FMSMessage message) { - // TODO Auto-generated method stub - - } - - public synchronized void subscribeToBoard(FMSBoard board) { - if(mSubscribedBoards.contains(board)) { - assert(false); /* TODO: Add logging / check whether this should be allowed to happen */ - return; - } - mSubscribedBoards.add(board); - } - - public synchronized void unsubscribeFromBoard(FMSBoard board) { - mSubscribedBoards.remove(board); - } - - public synchronized Iterator<FMSBoard> subscribedBoardsIterator() { - return mSubscribedBoards.iterator(); - } - - public synchronized boolean wantsMessagesFrom(FMSIdentity identity) { - // TODO Auto-generated method stub - return false; - } - - /* - public final void exportXML(OutputStream out) throws IOException { - Writer w = new BufferedWriter(new OutputStreamWriter(out)); - w.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - w.write("<Identity\n"); - w.write("\t<Name><![CDATA["); - XMLUtils.writeEsc(w, getNickName()); - w.write("]]></Name>\n"); - - w.write("\t<SingleUse>false</SingleUse>\n"); - w.write("\t<PublishTrustList>false</PublishTrustList>\n"); - w.write("\t<PublishBoardList>false</PublishBoardList>\n"); - - w.write("<Identity\n"); - w.flush(); - w.close(); - } - */ -} Copied: trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java (from rev 23328, trunk/plugins/Freetalk/WoT/FMSIdentityManagerWoT.java) =================================================================== --- trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java (rev 0) +++ trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,30 @@ +/* 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 plugins.Freetalk.WoT; + +import plugins.FMSPlugin.FMSIdentityManager; +import plugins.WoT.WoT; + +import com.db4o.ObjectContainer; + +import freenet.support.Executor; + +/** + * An identity manager which uses the identities from the WoT plugin. + * + * @author xor + * + */ +public class FTIdentityManagerWoT extends FMSIdentityManager { + + private WoT mWoT; + + /** + * @param executor + */ + public FTIdentityManagerWoT(ObjectContainer myDB, Executor executor, WoT newWoT) { + super(myDB, executor); + mWoT = newWoT; + } +} Copied: trunk/plugins/Freetalk/WoT/FTIdentityWoT.java (from rev 23328, trunk/plugins/Freetalk/WoT/FMSIdentityWoT.java) =================================================================== --- trunk/plugins/Freetalk/WoT/FTIdentityWoT.java (rev 0) +++ trunk/plugins/Freetalk/WoT/FTIdentityWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,41 @@ +/* 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 plugins.Freetalk.WoT; + +import java.util.Date; + +import freenet.keys.FreenetURI; +import plugins.FMSPlugin.FMSIdentity; + +import plugins.WoT.Identity; + +/** + * @author xor + * + */ +public class FTIdentityWoT implements FMSIdentity { + + protected final Identity mIdentity; + + public FTIdentityWoT(Identity newIndentity) { + mIdentity = newIndentity; + } + + public boolean doesPublishTrustList() { + return mIdentity.doesPublishTrustList(); + } + + public Date getLastChange() { + return mIdentity.getLastChange(); + } + + public String getNickName() { + return mIdentity.getNickName(); + } + + public FreenetURI getRequestURI() { + return mIdentity.getRequestURI(); + } + +} Copied: trunk/plugins/Freetalk/WoT/FTMessageManagerWoT.java (from rev 23328, trunk/plugins/Freetalk/WoT/FMSMessageManagerWoT.java) =================================================================== --- trunk/plugins/Freetalk/WoT/FTMessageManagerWoT.java (rev 0) +++ trunk/plugins/Freetalk/WoT/FTMessageManagerWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,50 @@ +/* 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 plugins.Freetalk.WoT; + +import java.util.NoSuchElementException; + +import plugins.FMSPlugin.FMSBoard; +import plugins.FMSPlugin.FMSMessageManager; + +import com.db4o.ObjectContainer; + +import freenet.keys.FreenetURI; +import freenet.support.UpdatableSortedLinkedListKilledException; + +public class FTMessageManagerWoT extends FMSMessageManager { + + protected FMSIdentityManagerWoT mIdentityManager; + + public FTMessageManagerWoT(ObjectContainer myDB, FMSIdentityManagerWoT myIdentityManager) { + super(myDB, myIdentityManager); + mIdentityManager = myIdentityManager; + } + + protected synchronized void deleteMessage(FreenetURI uri) throws NoSuchElementException { + /* FIXME: implement */ + } + + private synchronized void onMessageReceived(String newMessageData) throws UpdatableSortedLinkedListKilledException { + FMSMessageWoT newMessage = new FMSMessageWoT(db, null, null, null, null, null, null, null, null, null); + String boardName = ""; + /* FIXME: Store the description in FMSOwnIdentity. We cannot store in FMSBoard because we want to allow per-identity customization */ + + String[] boardNames = new String[0]; + FMSBoard[] boards = new FMSBoard[boardNames.length]; + + for(int idx = 0; idx < boards.length; ++idx) { + FMSBoard board = getBoardByName(boardNames[idx]); + + if(board == null) + board = new FMSBoard(db, this, boardName); + + boards[idx] = board; + } + + for(FMSBoard b : boards) { + b.addMessage(newMessage); + } + } +} Copied: trunk/plugins/Freetalk/WoT/FTMessageWoT.java (from rev 23328, trunk/plugins/Freetalk/WoT/FMSMessageWoT.java) =================================================================== --- trunk/plugins/Freetalk/WoT/FTMessageWoT.java (rev 0) +++ trunk/plugins/Freetalk/WoT/FTMessageWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,31 @@ +/* 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 plugins.Freetalk.WoT; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +import plugins.FMSPlugin.FMSBoard; +import plugins.FMSPlugin.FMSIdentity; +import plugins.FMSPlugin.FMSMessage; + +import com.db4o.ObjectContainer; + +import freenet.keys.FreenetURI; + +/** + * @author xor + * + */ +public class FTMessageWoT extends FMSMessage { + + public FTMessageWoT(ObjectContainer myDB, FreenetURI newURI, FreenetURI newThreadURI, FreenetURI newParentURI, Set<FMSBoard> newBoards, FMSIdentity newAuthor, + String newTitle, Date newDate, String newText, List<FreenetURI> newAttachments) { + super(myDB, newURI, newThreadURI, newParentURI, newBoards, newAuthor, newTitle, newDate, newText, newAttachments); + // TODO Auto-generated constructor stub + } + + +} Copied: trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java (from rev 23328, trunk/plugins/Freetalk/WoT/FMSOwnIdentityWoT.java) =================================================================== --- trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java (rev 0) +++ trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java 2008-11-06 01:12:25 UTC (rev 23329) @@ -0,0 +1,85 @@ +/* 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 plugins.Freetalk.WoT; + +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; + +import plugins.FMSPlugin.FMSBoard; +import plugins.FMSPlugin.FMSIdentity; +import plugins.FMSPlugin.FMSMessage; +import plugins.FMSPlugin.FMSOwnIdentity; +import plugins.WoT.OwnIdentity; +import freenet.keys.FreenetURI; + +/** + * @author xor + * + */ +public class FTOwnIdentityWoT extends FMSIdentityWoT implements FMSOwnIdentity { + + private final LinkedList<FMSBoard> mSubscribedBoards = new LinkedList<FMSBoard>(); + + public FTOwnIdentityWoT(OwnIdentity newIndentity) { + super(newIndentity); + } + + protected OwnIdentity getOwnIdentity() { + return (OwnIdentity)mIdentity; + } + + public FreenetURI getInsertURI() { + return getOwnIdentity().getInsertURI(); + } + + public synchronized Date getLastInsert() { + return getOwnIdentity().getLastInsert(); + } + + public synchronized void postMessage(FMSMessage message) { + // TODO Auto-generated method stub + + } + + public synchronized void subscribeToBoard(FMSBoard board) { + if(mSubscribedBoards.contains(board)) { + assert(false); /* TODO: Add logging / check whether this should be allowed to happen */ + return; + } + mSubscribedBoards.add(board); + } + + public synchronized void unsubscribeFromBoard(FMSBoard board) { + mSubscribedBoards.remove(board); + } + + public synchronized Iterator<FMSBoard> subscribedBoardsIterator() { + return mSubscribedBoards.iterator(); + } + + public synchronized boolean wantsMessagesFrom(FMSIdentity identity) { + // TODO Auto-generated method stub + return false; + } + + /* + public final void exportXML(OutputStream out) throws IOException { + Writer w = new BufferedWriter(new OutputStreamWriter(out)); + w.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + w.write("<Identity\n"); + w.write("\t<Name><![CDATA["); + XMLUtils.writeEsc(w, getNickName()); + w.write("]]></Name>\n"); + + w.write("\t<SingleUse>false</SingleUse>\n"); + w.write("\t<PublishTrustList>false</PublishTrustList>\n"); + w.write("\t<PublishBoardList>false</PublishBoardList>\n"); + + w.write("<Identity\n"); + w.flush(); + w.close(); + } + */ +}
