Hi!

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]



Reply via email to