package freenet.client; import freenet.client.InsertException.InsertExceptionMode; import freenet.client.async.BaseClientPutter; import freenet.client.async.ClientContext; import freenet.client.async.ClientPutCallback; import freenet.keys.FreenetURI; import freenet.node.RequestClient; import freenet.support.LogThresholdCallback; import freenet.support.Logger; import freenet.support.Logger.LogLevel; import freenet.support.api.Bucket; /** Provides a blocking wrapper for an insert. Used for simple blocking APIs such as HighLevelSimpleClient. */ public class PutWaiter implements ClientPutCallback { private boolean finished; private boolean succeeded; private FreenetURI uri; private InsertException error; final RequestClient client; private static volatile boolean logMINOR; static { Logger.registerLogThresholdCallback(new LogThresholdCallback(){ @Override public void shouldUpdate(){ logMINOR = Logger.shouldLog(LogLevel.MINOR, this); } }); } public PutWaiter(RequestClient client) { this.client = client; } @Override public synchronized void onSuccess(BaseClientPutter state) { succeeded = true; finished = true; notifyAll(); } @Override public synchronized void onFailure(InsertException e, BaseClientPutter state) { error = e; finished = true; notifyAll(); } @Override public synchronized void onGeneratedURI(FreenetURI uri, BaseClientPutter state) { if(logMINOR) Logger.minor(this, "URI: "+uri); if(this.uri == null) this.uri = uri; if(uri.equals(this.uri)) return; Logger.error(this, "URI already set: "+this.uri+" but new URI: "+uri, new Exception("error")); } /** Waits for the insert to finish, returns the URI generated, throws if it failed. */ public synchronized FreenetURI waitForCompletion() throws InsertException { while(!finished) { try { wait(); } catch (InterruptedException e) { // Ignore } } if(error != null) { error.uri = uri; throw error; } if(succeeded) return uri; Logger.error(this, "Did not succeed but no error"); throw new InsertException(InsertExceptionMode.INTERNAL_ERROR, "Did not succeed but no error", uri); } @Override public void onFetchable(BaseClientPutter state) { // Ignore } @Override public void onGeneratedMetadata(Bucket metadata, BaseClientPutter state) { Logger.error(this, "onGeneratedMetadata() on PutWaiter from "+state, new Exception("error")); metadata.free(); } @Override public void onResume(ClientContext context) { throw new UnsupportedOperationException(); // Not persistent. } @Override public RequestClient getRequestClient() { return client; } }