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