Author: xor
Date: 2008-11-15 17:29:32 +0000 (Sat, 15 Nov 2008)
New Revision: 23598

Modified:
   trunk/plugins/WoT/introduction/IntroductionClient.java
   trunk/plugins/WoT/introduction/IntroductionPuzzle.java
Log:
Provide IntroductionClient.insertPuzzleSolution(). This function is to be used 
by the UI for identity announcement: First, the UI should retrieve a list of 
puzzles by IntroductionPuzzles.getPuzzles(), then let the user solve them and 
then call IntroductionClient.insertPuzzleSolution() for the solved puzzles. 
Easy, eh? :)

Modified: trunk/plugins/WoT/introduction/IntroductionClient.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionClient.java      2008-11-14 
23:10:05 UTC (rev 23597)
+++ trunk/plugins/WoT/introduction/IntroductionClient.java      2008-11-15 
17:29:32 UTC (rev 23598)
@@ -5,6 +5,8 @@
  */
 package plugins.WoT.introduction;
 
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashSet;
@@ -12,6 +14,9 @@
 import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
 import plugins.WoT.Identity;
 import plugins.WoT.OwnIdentity;
 import plugins.WoT.exceptions.NotInTrustTreeException;
@@ -20,17 +25,22 @@
 import com.db4o.ObjectSet;
 import com.db4o.query.Query;
 
+import freenet.client.ClientMetadata;
 import freenet.client.FetchContext;
 import freenet.client.FetchException;
 import freenet.client.FetchResult;
 import freenet.client.HighLevelSimpleClient;
+import freenet.client.InsertBlock;
+import freenet.client.InsertContext;
 import freenet.client.InsertException;
 import freenet.client.async.BaseClientPutter;
 import freenet.client.async.ClientCallback;
 import freenet.client.async.ClientGetter;
+import freenet.client.async.ClientPutter;
 import freenet.keys.FreenetURI;
 import freenet.node.RequestStarter;
 import freenet.support.Logger;
+import freenet.support.api.Bucket;
 import freenet.support.io.TempBucketFactory;
 
 /**
@@ -77,6 +87,8 @@
        /* FIXME FIXME FIXME: Use LRUQueue instead. ArrayBlockingQueue does not 
use a Hashset for contains()! */
        private final ArrayBlockingQueue<Identity> mIdentities = new 
ArrayBlockingQueue<Identity>(PUZZLE_POOL_SIZE); /* FIXME: figure out whether my 
assumption that this is just the right size is correct */
        private final HashSet<ClientGetter> mRequests = new 
HashSet<ClientGetter>(PUZZLE_REQUEST_COUNT * 2); /* TODO: profile & tweak */
+       
+       private final HashSet<ClientPutter> mInserts = new 
HashSet<ClientPutter>(PUZZLE_REQUEST_COUNT * 2); 
 
        /**
         * Creates an IntroductionServer
@@ -168,6 +180,38 @@
                return result;
        }
        
+       public synchronized void insertPuzzleSolution(IntroductionPuzzle p, 
String solution, OwnIdentity solver) throws IOException, 
ParserConfigurationException, TransformerException, InsertException {
+               Bucket tempB = mTBF.makeBucket(10 * 1024); /* TODO: set to a 
reasonable value */
+               OutputStream os = tempB.getOutputStream();
+
+               try {
+                       solver.exportIntroductionToXML(os);
+                       os.close(); os = null;
+                       tempB.setReadOnly();
+
+                       ClientMetadata cmd = new ClientMetadata("text/xml");
+                       FreenetURI solutionURI = p.getSolutionURI(solution);
+                       InsertBlock ib = new InsertBlock(tempB, cmd, 
solutionURI);
+
+                       InsertContext ictx = mClient.getInsertContext(true);
+                       
+                       /* FIXME: are these parameters correct? */
+                       ClientPutter pu = mClient.insert(ib, false, null, 
false, ictx, this);
+                       
pu.setPriorityClass(RequestStarter.UPDATE_PRIORITY_CLASS);
+                       mInserts.add(pu);
+                       
+                       Logger.debug(this, "Started to insert puzzle solution 
of " + solver.getNickName() + " at " + solutionURI);
+
+                       p.setSolved(solver, solution);
+                       db.store(p);
+                       db.commit();
+               }
+               finally {
+                       tempB.free();
+                       if(os != null)
+                               os.close();
+               }
+       }
        
        private synchronized void cancelRequests() {
                Iterator<ClientGetter> i = mRequests.iterator();
@@ -280,7 +324,12 @@
        /* Not needed functions from the ClientCallback inteface */
        
        // Only called by inserts
-       public void onSuccess(BaseClientPutter state) {}
+       public void onSuccess(BaseClientPutter state)
+       {
+               Logger.debug(this, "Successful insert of puzzle solution at " + 
state.getURI());
+               state.cancel(); /* FIXME: is this necessary */
+               mInserts.remove(state);
+       }
        
        // Only called by inserts
        public void onFailure(InsertException e, BaseClientPutter state) {}

Modified: trunk/plugins/WoT/introduction/IntroductionPuzzle.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionPuzzle.java      2008-11-14 
23:10:05 UTC (rev 23597)
+++ trunk/plugins/WoT/introduction/IntroductionPuzzle.java      2008-11-15 
17:29:32 UTC (rev 23598)
@@ -8,22 +8,16 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.net.MalformedURLException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
@@ -36,24 +30,19 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import plugins.WoT.Identity;
+import plugins.WoT.OwnIdentity;
+import plugins.WoT.WoT;
+import plugins.WoT.exceptions.UnknownIdentityException;
+
 import com.db4o.ObjectContainer;
 import com.db4o.ObjectSet;
 import com.db4o.query.Query;
 import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
 
-import freenet.crypt.SHA1;
 import freenet.keys.FreenetURI;
 import freenet.support.Logger;
 
-import plugins.WoT.Identity;
-import plugins.WoT.IdentityFetcher;
-import plugins.WoT.OwnIdentity;
-import plugins.WoT.Trustlist;
-import plugins.WoT.WoT;
-import plugins.WoT.IdentityParser.IdentityHandler;
-import plugins.WoT.exceptions.InvalidParameterException;
-import plugins.WoT.exceptions.UnknownIdentityException;
-
 public class IntroductionPuzzle {
        
        public static final String INTRODUCTION_CONTEXT = "introduction";
@@ -78,9 +67,15 @@
        private final int mIndex;
        
        /* Supplied at creation time or by user: */
+
+       /**
+        * We store the solver of the puzzle so that we can insert the solution 
even if the node is shutdown directly after solving puzzles.
+        */
+       private OwnIdentity mSolver = null;
        
-       private final String mSolution;
+       private String mSolution = null;
 
+
        /**
         * Set to true after it was used for introducing a new identity. We 
keep used puzzles in the database until they expire for the purpose of
         * being able to figure out free index values of new puzzles. Storing a 
few KiB for some days will not hurt.
@@ -131,6 +126,12 @@
                mIndex = myIndex;
        }
        
+       /**
+        * Used by the IntroductionServer for downloading solutions.
+        * @param db
+        * @param i
+        * @return
+        */
        public static ObjectSet<IntroductionPuzzle> 
getByInserter(ObjectContainer db, OwnIdentity i) {
                Query q = db.query();
                q.constrain(IntroductionPuzzle.class);
@@ -139,6 +140,13 @@
                return q.execute();
        }
        
+        /**
+         * Used by the IntroductionServer when a solution was downloaded to 
retrieve the IntroductionPuzzle object.
+         * @param db
+         * @param uri
+         * @return
+         * @throws ParseException
+         */
        public static IntroductionPuzzle getBySolutionURI(ObjectContainer db, 
FreenetURI uri) throws ParseException {
                String[] tokens = uri.getDocName().split("|");
                String id = tokens[1];
@@ -157,6 +165,13 @@
                return (result.hasNext() ? result.next() : null);
        }
        
+       /**
+        * Used by the IntroductionServer for inserting new puzzles.
+        * @param db
+        * @param id
+        * @param date
+        * @return
+        */
        public static int getFreeIndex(ObjectContainer db, OwnIdentity id, Date 
date) {
                Query q = db.query();
                q.constrain(IntroductionPuzzle.class);
@@ -167,11 +182,23 @@
                
                return result.size() > 0 ? result.next().getIndex()+1 : 0;
        }
-       
+
+       /**
+        * Used by the IntroductionClient for inserting solutions of solved 
puzzles.
+        * @param db
+        * @return
+        */
+       public static ObjectSet<IntroductionPuzzle> 
getSolvedPuzzles(ObjectContainer db) {
+               Query q = db.query();
+               q.constrain(IntroductionPuzzle.class);
+               q.descend("mSolver").constrain(null).identity().not();
+               return q.execute();
+       }
+
        public String getMimeType() {
                return mMimeType;
        }
-       
+
        /**
         * Get the URI at which to insert this puzzle.
         * [EMAIL PROTECTED]|WoT|introduction|yyyy-MM-dd|#.xml 
@@ -235,10 +262,25 @@
                return mSolution;
        }
        
+       
+       /**
+        * Used by the IntroductionServer to mark a puzzle as solved.
+        */
        public void setSolved() {
                iWasSolved = true;
        }
        
+       /**
+        * Used by the IntroductionClient to mark a puzzle as solved
+        * @param solver
+        * @param solution
+        */
+       public void setSolved(OwnIdentity solver, String solution) {
+               iWasSolved = true;
+               mSolver = solver;
+               mSolution = solution;
+       }
+       
        public Identity getInserter() {
                return mInserter;
        }
@@ -273,6 +315,11 @@
                db.commit();
        }
        
+       /**
+        * Used by the introduction client to delete old puzzles and replace 
them with new ones.
+        * @param db
+        * @param puzzlePoolSize
+        */
        public static void deleteOldestPuzzles(ObjectContainer db, int 
puzzlePoolSize) {
                Query q = db.query();
                q.constrain(IntroductionPuzzle.class);

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to