I would recommend against doing it in this way. Primarily because it involves polling (the second thread calling getWrittenRequestBodyBytes() repeatedly) and because of the added synchronization overhead.
Yes, I would call it just once a second, but nobody knows what someone else does.
In my experience it is easier and more reusable to handle this at the InputStream level. This involves adding a wrapper class around the InputStream that is being put/posted. It would look something like:> [...]
class ProgressInputStream extends FilterInputStream {
So, maybe I don't need a code change in the class EntityEnclosingMethod, because I could use the ProgressInputStream instead of a simple InputStream in the method
EntityEnclosingMethod#setRequestBody(InputStream body)
But what about the #setRequestBody(String body) method. OK, I could use a
ProgressInputStream(new ByteArrayInputStream(body.getBytes()))
as the body.
But especially for my actual problem (the WebDAV client progressbar), I don't have (real) access to the Source code and the above changes in the httpclient must be added in every implementation that uses the #setRequestBody() method.
I think, it would be easier and better to implement a "ProgressObserver" at the lowest possible position. To avoid waste of resources, it could be possible to add ProgressListener directly to the EntityEnclosingMethod. Example:
public abstract class EntityEnclosingMethod extends GetMethod { [...] private List progressListeners = new ArrayList(); [...] public void addProgressListener(ProgressListener listener) { progressListeners.add(listener); }
public List getProgressListeners() { return progressListeners; }
protected boolean writeRequestBody( HttpState state, HttpConnection conn) { //... if (progressListeners.isEmpty()) { InputStream instream = getRequestBody(); } else { InputStream instream = new ProgressInputStream( getRequestBody(), getProgressListeners()); } // ... }
public class ProgressInputStream extends FilterInputStream { // ... public ProgressInputStream(InputStream is, List progressListeners) { //... } // ... private void bytesRead(int count) { bytesRead+=count; if (progressListeners==null || progressListeners.isEmpty()) return; for (int i=0; i<progressListeners.size();i++) { ProgressListener l = (ProgressListener)progressListeners.get(i); if (bytesRead > l.getThreshold()) { totalBytesRead += bytesRead; bytesRead = 0; l.progressAchieved(totalBytesRead); } } } }
The EVENT_THRESHOLD value should be part of the ProgressListener, should be "setable" and should be checked by the ProgressInputStream. (Different values MUST be possible, for example transfering data over a slow connection should show the transfer of even 10 Bytes).
public Interface ProgressListener { public void progressAchieved(long totalBytesRead); public int getThreshold(); }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]