luetzkendorf 2004/07/13 01:47:30
Modified: webdavclient/clientlib/src/java/org/apache/webdav/lib
WebdavResource.java
webdavclient/clientlib/src/java/org/apache/webdav/lib/methods
SubscribeMethod.java UnsubscribeMethod.java
Added: webdavclient/clientlib/src/java/org/apache/webdav/lib
Subscription.java
webdavclient/clientlib/src/java/org/apache/webdav/lib/event
Listener.java Notification.java
NotificationListener.java
NotificationProcessor.java
PrintingNotificationProcessor.java UDPListener.java
package.html
webdavclient/clientlib/src/java/org/apache/webdav/lib/methods
PollMethod.java
Log:
continued to add notification support
Revision Changes Path
1.22 +175 -31
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/WebdavResource.java
Index: WebdavResource.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/WebdavResource.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- WebdavResource.java 6 Jul 2004 12:43:51 -0000 1.21
+++ WebdavResource.java 13 Jul 2004 08:47:30 -0000 1.22
@@ -40,51 +40,29 @@
import java.util.Locale;
import java.util.TimeZone;
import java.util.Vector;
+
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.HttpURL;
+import org.apache.commons.httpclient.HttpsURL;
+import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.util.URIUtil;
+
import org.apache.util.DOMUtils;
-import org.apache.commons.httpclient.HttpURL;
-import org.apache.commons.httpclient.HttpsURL;
-import org.apache.commons.httpclient.URIException;
import org.apache.util.WebdavStatus;
-import org.apache.webdav.lib.methods.AclMethod;
-import org.apache.webdav.lib.methods.AclReportMethod;
-import org.apache.webdav.lib.methods.CheckinMethod;
-import org.apache.webdav.lib.methods.CheckoutMethod;
-import org.apache.webdav.lib.methods.CopyMethod;
-import org.apache.webdav.lib.methods.DeleteMethod;
-import org.apache.webdav.lib.methods.DepthSupport;
-import org.apache.webdav.lib.methods.LabelMethod;
-import org.apache.webdav.lib.methods.LockMethod;
-import org.apache.webdav.lib.methods.MkWorkspaceMethod;
-import org.apache.webdav.lib.methods.MkcolMethod;
-import org.apache.webdav.lib.methods.MoveMethod;
-import org.apache.webdav.lib.methods.OptionsMethod;
-import org.apache.webdav.lib.methods.PropFindMethod;
-import org.apache.webdav.lib.methods.PropPatchMethod;
-import org.apache.webdav.lib.methods.ReportMethod;
-import org.apache.webdav.lib.methods.UncheckoutMethod;
-import org.apache.webdav.lib.methods.UnlockMethod;
-import org.apache.webdav.lib.methods.UpdateMethod;
-import org.apache.webdav.lib.methods.VersionControlMethod;
-import org.apache.webdav.lib.methods.BindMethod;
-import org.apache.webdav.lib.methods.UnbindMethod;
-import org.apache.webdav.lib.methods.RebindMethod;
+import org.apache.webdav.lib.methods.*;
import org.apache.webdav.lib.properties.AclProperty;
import org.apache.webdav.lib.properties.LockDiscoveryProperty;
import org.apache.webdav.lib.properties.PrincipalCollectionSetProperty;
import org.apache.webdav.lib.properties.ResourceTypeProperty;
-import sun.text.Normalizer;
-
/**
* The class <code>WebdavResource</code> is an abstract representation
* for WebDAV resource.<p>
@@ -5037,6 +5015,172 @@
return statusCode >= 200 && statusCode < 300;
}
+ /**
+ * Subscribes for notifications for modifications of WebDAV resources.
+ *
+ * @param path URL path of the resource that is to be subscribed
+ * @param notificationType
+ * @param callback the URL to be registered for notification, may be
+ * <code>null</code> if no callback shall be registered.
+ * @param notificationDelay
+ * @param depth the depth of the subscription (for valid values see
+ * [EMAIL PROTECTED] DepthSupport})
+ * @param lifetime duration of that subscription in seconds (Note: the
+ * server may change this and return an other one;
+ * see [EMAIL PROTECTED] Subscription#getLifetime()}.
+ *
+ * @return a [EMAIL PROTECTED] Subscription} or <code>null</code> if an error
occurs
+ * @throws HttpException
+ * @throws IOException
+ */
+ public Subscription subscribeMethod(String path,
+ String notificationType,
+ String callback,
+ long notificationDelay,
+ int depth,
+ long lifetime)
+ throws HttpException, IOException
+ {
+ setClient();
+
+ SubscribeMethod method = new SubscribeMethod(path);
+ method.setDebug(debug);
+ method.setFollowRedirects(this.followRedirects);
+
+ method.setCallback(callback);
+ method.setDepth(depth);
+ method.setSubsciptionLifetime(lifetime);
+ method.setNotificationType(notificationType);
+ method.setNotificationDelay(notificationDelay);
+
+ int statusCode = client.executeMethod(method);
+
+ if (statusCode == HttpStatus.SC_OK) {
+ return new Subscription(
+ path,
+ method.getResponsedSubscriptionId(),
+ method.getCallback(),
+ method.getResponsedSubscriptionLifetime(),
+ method.getResponsedContentLocation(),
+ method.getNotificationType()
+ );
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Refreshes a subscription.
+ *
+ * @return <code>true</code> on success.
+ * @author Stefan L�tzkendorf
+ */
+ public boolean subscribeMethod(String path, int subscriptionId)
+ throws HttpException, IOException
+ {
+ setClient();
+
+ SubscribeMethod method = new SubscribeMethod(path);
+ method.setDebug(debug);
+ method.setFollowRedirects(this.followRedirects);
+
+ method.setSubscriptionId(subscriptionId);
+
+ int statusCode = client.executeMethod(method);
+
+ if (statusCode == HttpStatus.SC_OK) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Refreshes a subscription.
+ *
+ * @param subscription The subscription to be refreshed.
+ * @return <code>true</code> on success
+ */
+ public boolean subscribeMethod(Subscription subscription)
+ throws HttpException, IOException
+ {
+ return subscribeMethod(subscription.getPath(), subscription.getId());
+ }
+
+ /**
+ * Cancels a subscription.
+ * @param path URL path for that was subscribed
+ * @return <code>true</code> on success
+ */
+ public boolean unsubscribeMethod(String path, int subscriptionId)
+ throws HttpException, IOException
+ {
+ setClient();
+
+ UnsubscribeMethod method = new UnsubscribeMethod(path);
+ method.setDebug(debug);
+ method.setFollowRedirects(this.followRedirects);
+
+ method.addSubscriptionId(subscriptionId);
+
+ int statusCode = client.executeMethod(method);
+
+ if (statusCode == HttpStatus.SC_OK) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Cancels a subscription.
+ * @param subscription
+ * @return <code>true</code> on success
+ */
+ public boolean unsubscribeMethod(Subscription subscription)
+ throws HttpException, IOException
+ {
+ return unsubscribeMethod(subscription.getPath(),subscription.getId());
+ }
+
+ /**
+ * Asks the server whether events for a given subscription are fired.
+ * @param contentLocation URL path returned by the SUBSCRIBE methods
+ * Content-Location header
+ * @param subscriptionId id of the subscription
+ * @return <code>true</code> if an event was fired
+ */
+ public boolean pollMethod(String contentLocation, int subscriptionId)
+ throws HttpException, IOException
+ {
+ setClient();
+
+ PollMethod method = new PollMethod(contentLocation);
+ method.setDebug(debug);
+ method.setFollowRedirects(this.followRedirects);
+
+ method.addSubscriptionId(subscriptionId);
+
+ int statusCode = client.executeMethod(method);
+
+ if (statusCode == HttpStatus.SC_MULTI_STATUS) {
+ return method.getSubscriptionsWithEvents().size() > 0;
+ } else {
+ return false;
+ }
+ }
+ /**
+ * Asks the server whether events for a given subscription are fired.
+ * @param subscription the subscription to ask for
+ * @return <code>true</code> if an event was fired
+ */
+ public boolean pollMethod(Subscription subscription)
+ throws HttpException, IOException
+ {
+ return pollMethod(subscription.getContentLocation(), subscription.getId());
+ }
+
+
+
private static String getName(String uri) {
String escapedName = URIUtil.getName(
uri.endsWith("/") ? uri.substring(0, uri.length() - 1): uri);
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/Subscription.java
Index: Subscription.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib;
/**
* Object that holds information about a single WebDAV subscription.
*
* @see org.apache.webdav.lib.WebdavResource#subscribeMethod(String, String, String,
long, int, long)
* @author Stefan L�tzkendorf
*/
public class Subscription
{
public static final String UPDATE_NOTIFICATION = "update";
public static final String NEW_MEMBER_NOTIFICATION = "update/newmember";
public static final String DELETE_NOTIFICATION = "delete";
public static final String MOVE_NOTIFICATION = "move";
private int id;
private long lifetime;
private String callback;
private String contentLocation;
private String notificationType;
private String path;
public Subscription(String path, int id, String callback, long lifetime,
String contentLocation, String notificationType)
{
this.path = path;
this.id = id;
this.callback = callback;
this.lifetime = lifetime;
this.contentLocation = contentLocation;
this.notificationType = notificationType;
}
public String getCallback()
{
return callback;
}
public String getContentLocation()
{
return contentLocation;
}
public int getId()
{
return id;
}
public long getLifetime()
{
return lifetime;
}
public String getNotificationType()
{
return notificationType;
}
public String getPath()
{
return path;
}
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/Listener.java
Index: Listener.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
/**
* @author Stefan L�tzkendorf
*/
abstract class Listener extends Thread
{
/**
* Returns the count of currenty queued notifications.
*/
public abstract int getNotificationCount();
/**
* Removes the next notification to be processed from the queue and returns
* it.
* @throws java.util.NoSuchElementException if no notification exists.
*/
public abstract Notification popNextNotification();
public abstract Exception getException();
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/Notification.java
Index: Notification.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
import java.net.InetAddress;
/**
* Object that holds information about a single notification.
*
* @author Stefan L�tzkendorf
*/
public final class Notification
{
/** the request uri */
private String url;
private long subscription;
private InetAddress inetAddress;
/**
* Creates a notification object from an URL and a number identifying a
* subscription.
* @param url
* @param subscription
* @param address the address of the host that send the notification
*/
public Notification(String url, long subscription, InetAddress address) {
this.url = url;
this.subscription = subscription;
this.inetAddress = address;
}
/**
* The request uri of the notification. That should match the call back
* registered while subscription.
*/
public String getURL() {
return this.url;
}
/**
* The ID of the subscription that is notified.
*/
public long getSubscriptionId() {
return this.subscription;
}
/**
* The String representation of the IP address of the notifier.
* @return IP address as String, e.g. 192.168.0.1
*/
public String getNotifiersAddress() {
return this.inetAddress.getHostAddress();
}
/**
* The name of the notifier.
* @see InetAddress#getHostName()
*/
public String getNotifiersName() {
return this.inetAddress.getHostName();
}
/**
* The name of the notifier.
* @see InetAddress#getCanonicalHostName()
*/
public String getNotifiersCanonicalName() {
return this.inetAddress.getCanonicalHostName();
}
public String toString() {
return new StringBuffer(120)
.append("url=")
.append(this.url)
.append(", subscription=")
.append(this.subscription)
.toString();
}
/**
* Two notifications are equal if their request uri and id are equal.
*/
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj instanceof Notification) {
Notification that = (Notification)obj;
return (this.subscription == that.subscription &&
this.url.equals(that.url));
}
return false;
}
public int hashCode() {
return (51 * (int)this.subscription) + this.url.hashCode();
}
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/NotificationListener.java
Index: NotificationListener.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
/**
* Listener for WebDAV notifications.
*
* <p><b>Usage:</b>
* <p>
* Implement the interface [EMAIL PROTECTED] NotificationProcessor} to determine how
* do you want to process [EMAIL PROTECTED] Notification}s.
*
* <p> Create your processsor
* <pre>
* NotificationProcessor myProcessor = new MyProcessor();
* </pre>
*
* <p>Determine the port to listen on (should match the port in the URL
* you have provided while subscription, e.g. httpu://localhost:8887).
* <pre>
* int myPort = 8887;
* </pre>
*
* <p>Create a NotificationListner and run it
* <pre>
* NotificationListener listener = NotificationListener.createUDPListener(
* myPort,
* myProcessor);
* listener.start();
* </pre>
*
* @author Stefan L�tzkendorf
*/
public class NotificationListener extends Thread
{
private Listener listener;
private NotificationProcessor processor;
private NotificationListener(Listener listener, NotificationProcessor processor) {
this.listener = listener;
this.processor = processor;
setName("Notification processing thread for " + listener);
}
/**
* Creates a listener that listens on a DatagramSocket and calls
* [EMAIL PROTECTED] NotificationProcessor#processNotification(Notification)} for
* each incomming notification.
*
* @param port Port number to be listened
* @param processor callback to process incomming [EMAIL PROTECTED]
Notification}s.
*/
public static NotificationListener createUDPListener(
int port,
NotificationProcessor processor)
{
return new NotificationListener(
new UDPListener(port),
processor);
}
/**
* Not yet implemented.
*/
public static NotificationListener createTCPListener(
int port,
NotificationProcessor processor)
{
throw new UnsupportedOperationException();
}
public void run()
{
listener.start();
while (true) {
Notification notification;
synchronized(listener) {
while (listener.getNotificationCount() < 1) {
try {
listener.wait(1000);
} catch (InterruptedException e) {
listener.interrupt();
return;
}
if (isInterrupted()) {
listener.interrupt();
return;
}
}
notification = listener.popNextNotification();
}
processor.processNotification(notification);
}
}
/**
* Runs an UDPListener that listens on port 80.
*/
public static void main(String[] args)
{
NotificationListener listener = NotificationListener.createUDPListener(
80,
new PrintingNotificationProcessor());
//listener.setDaemon(false);
listener.start();
try {
listener.join();
} catch (InterruptedException e) {
}
}
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/NotificationProcessor.java
Index: NotificationProcessor.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
/**
* Interface for classes which take responsibility for processing
* incomming notifications.
*
* @see org.apache.webdav.lib.event.NotificationListener
*
* @author Stefan L�tzkendorf
*/
public interface NotificationProcessor
{
public void processNotification(Notification notification);
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/PrintingNotificationProcessor.java
Index: PrintingNotificationProcessor.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
import java.io.PrintStream;
/**
* NotificationProcessor for testing purposes that simply prints all
* notifications to a stream (by default to [EMAIL PROTECTED] System#out}).
*
* @author Stefan L�tzkendorf
*/
public class PrintingNotificationProcessor
implements NotificationProcessor
{
private PrintStream out;
public PrintingNotificationProcessor() {
this.out = System.out;
}
public PrintingNotificationProcessor(PrintStream stream) {
this.out = stream;
}
public void processNotification(Notification notification)
{
this.out.println(notification);
}
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/UDPListener.java
Index: UDPListener.java
===================================================================
// vi: set ts=3 sw=3:
package org.apache.webdav.lib.event;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
/**
* @author Stefan L�tzkendorf
*/
class UDPListener extends Listener
{
private int port = 80;
private DatagramSocket socket;
private byte[] buffer = new byte[1024];
private LinkedList notifications = new LinkedList();
private Exception exception = null;
public UDPListener() {
this(80);
}
public UDPListener(int port) {
this.port = port;
setName(this.toString());
}
public void run() {
try {
this.socket = new DatagramSocket(this.port);
this.socket.setSoTimeout(10000);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
try {
this.socket.receive(packet);
List l = parseRequest(packet);
if (l.size() > 0) {
synchronized (this) {
this.notifications.addAll(l);
this.notify();
}
}
}
catch (SocketTimeoutException e) {
if (isInterrupted()) {
return;
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.exception = e;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.exception = e;
}
}
public Exception getException() {
return this.exception;
}
/**
* Returns the count of currenty queued notifications.
*/
public int getNotificationCount() {
return this.notifications.size();
}
/**
* Removes the next notification to be processed from the queue and returns
* it.
* @throws java.util.NoSuchElementException if no notification exists.
*/
public Notification popNextNotification() {
return (Notification)this.notifications.removeFirst();
}
public String toString() {
return "UDP Notification Listener on port " + this.port;
}
/**
* Parses the packet as NOTIFY request and returns a list of notifications
* contained. The list may be empty if this is not a (valid) NOTIFY request.
*
* @return List of [EMAIL PROTECTED] Notification}s.
*/
private List parseRequest(DatagramPacket packet) {
List result = new LinkedList();
byte[] data = packet.getData();
int pos = packet.getOffset();
int lastPos = packet.getOffset() + packet.getLength();
if (data[pos] == 'N' &&
data[pos+1] == 'O' &&
data[pos+2] == 'T' &&
data[pos+3] == 'I' &&
data[pos+4] == 'F' &&
data[pos+5] == 'Y' &&
data[pos+6] == ' ')
{
int secondSpacePos = indexOf((byte)' ', data, pos+7, lastPos);
if (secondSpacePos == -1) return Collections.EMPTY_LIST;
String url;
try {
url = URLDecoder.decode(new String(data, 7, secondSpacePos-7), "UTF-8");
} catch (UnsupportedEncodingException e) {
url = new String(data, 7, secondSpacePos);
}
// skip command line
pos = 1+indexOfEOL(data, secondSpacePos + 1, lastPos);
while(pos < lastPos) {
int lineEnd = indexOfEOL(data, pos, lastPos);
String line;
if (lineEnd == -1) {
line = new String(data, pos, lastPos-pos);
lineEnd = lastPos;
} else {
line = new String(data, pos, lineEnd-pos);
}
String headerName = line.substring(0, line.indexOf(':')).trim();
if ("Subscription-ID".equalsIgnoreCase(headerName)) {
StringTokenizer tokenizer = new StringTokenizer(
line.substring(line.indexOf(':')+1), ", ");
while(tokenizer.hasMoreTokens()) {
long id = Long.parseLong(tokenizer.nextToken());
Notification n = new Notification(url, id, packet.getAddress());
result.add(n);
}
}
pos = lineEnd+1;
}
}
return result;
}
private int indexOf(byte b, byte[] data, int offset, int end) {
for(int i = offset; i < end; i++) {
if(data[i] == b) return i;
}
return -1;
}
private int indexOfEOL(byte[] data, int offset, int end) {
for(int i = offset; i < end; i++) {
switch (data[i]) {
case '\r':
if (i+1<end && data[i+1] == '\n') return i+1;
case '\n':
return i;
}
}
return -1;
}
}
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/event/package.html
Index: package.html
===================================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML><HEAD>
<TITLE>HTML 4 Strict</TITLE></HEAD>
<BODY>
<P>Package with tools for handling WebDAV events.</P>
<P></P></BODY>
</HTML>
1.2 +53 -20
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/SubscribeMethod.java
Index: SubscribeMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/SubscribeMethod.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SubscribeMethod.java 6 Jul 2004 17:03:56 -0000 1.1
+++ SubscribeMethod.java 13 Jul 2004 08:47:30 -0000 1.2
@@ -46,6 +46,7 @@
private static final String HEADER_NOTIFICATION_DELAY = "Notification-Delay";
private static final String HEADER_DEPTH = "Depth";
private static final String HEADER_CALL_BACK = "Call-Back";
+ private static final String HEADER_CONTENT_LOCATION = "Content-Location";
public static final String TYPE_UPDATE = "update";
public static final String TYPE_UPDATE_NEW_MEMBER = "update/newmember";
@@ -56,23 +57,33 @@
private String notificationType = null;
private int depth = -1;
private long subsciptionLifetime = -1;
- private long subscriptionId = -1;
+ private int subscriptionId = -1;
private long notificationDelay = -1;
private long responsedSubscriptionLifetime = -1;
- private long responsedSubscriptionId = -1;
+ private int responsedSubscriptionId = -1;
+ private String responsedContentLocation = null;
+ public SubscribeMethod() {
+
+ }
+
+ public SubscribeMethod(String path) {
+ super(path);
+ }
public String getCallback()
{
return callback;
}
/**
- * Sets the URI tha's to be notified if the subscribed event does occur.
+ * Sets the URI that's to be notified if the subscribed event does occur.
*/
public void setCallback(String callback)
{
- this.callback = callback;
+ if (callback != null && callback.length() > 0) {
+ this.callback = callback;
+ }
}
public String getNotificationType()
{
@@ -81,8 +92,10 @@
/**
* Sets the notification type, i.e. determines the events that are
* subscribed.
- * @see [EMAIL PROTECTED] #TYPE_DELETE}, [EMAIL PROTECTED] #TYPE_MOVE},
- * [EMAIL PROTECTED] #TYPE_UPDATE}, [EMAIL PROTECTED]
#TYPE_UPDATE_NEW_MEMBER}
+ * @see #TYPE_DELETE
+ * @see #TYPE_MOVE
+ * @see #TYPE_UPDATE
+ * @see #TYPE_UPDATE_NEW_MEMBER
*/
public void setNotificationType(String notificationType)
{
@@ -107,7 +120,7 @@
* Sets the ID of a subscription to be refreshed.
* @param subscriptionId
*/
- public void setSubscriptionId(long subscriptionId)
+ public void setSubscriptionId(int subscriptionId)
{
this.subscriptionId = subscriptionId;
}
@@ -145,7 +158,7 @@
* Returns the subscription ID responsed from the server.
* @return -1 if no subscription id was in the response
*/
- public long getResponsedSubscriptionId() {
+ public int getResponsedSubscriptionId() {
checkUsed();
return this.responsedSubscriptionId;
}
@@ -157,6 +170,15 @@
checkUsed();
return this.responsedSubscriptionLifetime;
}
+ /**
+ * Returns the value of the content-location header of the response.
+ * This shall be used to the request uri for a POLL method querying this
+ * subscription.
+ */
+ public String getResponsedContentLocation() {
+ checkUsed();
+ return this.responsedContentLocation;
+ }
// --------------------------------------------------- WebdavMethod Methods
public String getName()
@@ -185,20 +207,22 @@
super.setRequestHeader(HEADER_CALL_BACK, this.callback);
}
if (this.depth > -1) {
- super.setRequestHeader(HEADER_DEPTH, Integer.toString(this.depth));
+ super.setRequestHeader(HEADER_DEPTH,
+ this.depth == DEPTH_INFINITY ? "infinity"
+ : String.valueOf(this.depth));
}
if (this.notificationType != null) {
super.setRequestHeader(HEADER_NOTIFICATION_TYPE, this.notificationType);
}
- if (this.subsciptionLifetime > -1) {
+ if (this.subsciptionLifetime > 0) {
super.setRequestHeader(HEADER_SUBSCRIPTION_LIFETIME,
Long.toString(this.subsciptionLifetime));
}
- if (this.subscriptionId > -1) {
+ if (this.subscriptionId > 0) {
super.setRequestHeader(HEADER_SUBSCRIPTION_ID, Long.toString(
this.subscriptionId));
}
- if (this.notificationDelay > -1) {
+ if (this.notificationDelay > 0) {
super.setRequestHeader(HEADER_NOTIFICATION_DELAY, Long.toString(
this.notificationDelay));
}
@@ -212,13 +236,17 @@
{
try {
if (headerName.equalsIgnoreCase(HEADER_DEPTH)){
- setDepth(Integer.parseInt(headerValue));
+ if ("infinity".equalsIgnoreCase(headerValue)) {
+ setDepth(DEPTH_INFINITY);
+ } else {
+ setDepth(Integer.parseInt(headerValue));
+ }
}
else if(headerName.equals(HEADER_SUBSCRIPTION_ID)) {
- setSubscriptionId(Long.parseLong(headerValue));
+ setSubscriptionId(Integer.parseInt(headerValue));
}
else if(headerName.equals(HEADER_SUBSCRIPTION_LIFETIME)) {
- setSubscriptionId(Long.parseLong(headerValue));
+ setSubscriptionId(Integer.parseInt(headerValue));
}
else if(headerName.equals(HEADER_NOTIFICATION_DELAY)) {
setNotificationDelay(Long.parseLong(headerValue));
@@ -240,12 +268,17 @@
header = getResponseHeader(HEADER_SUBSCRIPTION_ID);
if (header != null) {
- this.responsedSubscriptionId = Long.parseLong(header.getValue());
+ this.responsedSubscriptionId = Integer.parseInt(header.getValue());
}
- header = getRequestHeader(HEADER_SUBSCRIPTION_LIFETIME);
+ header = getResponseHeader(HEADER_SUBSCRIPTION_LIFETIME);
if (header != null) {
this.responsedSubscriptionLifetime = Long.parseLong(header.getValue());
+ }
+
+ header = getResponseHeader(HEADER_CONTENT_LOCATION);
+ if (header != null) {
+ this.responsedContentLocation = header.getValue();
}
}
}
1.2 +33 -4
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/UnsubscribeMethod.java
Index: UnsubscribeMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/UnsubscribeMethod.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- UnsubscribeMethod.java 6 Jul 2004 17:03:56 -0000 1.1
+++ UnsubscribeMethod.java 13 Jul 2004 08:47:30 -0000 1.2
@@ -1,4 +1,25 @@
-// vi: set ts=3 sw=3:
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2002 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
package org.apache.webdav.lib.methods;
import java.io.IOException;
@@ -24,11 +45,18 @@
private List subscriptionIds = new ArrayList();
+ public UnsubscribeMethod() {
+ }
+
+ public UnsubscribeMethod(String path) {
+ super(path);
+ }
+
/**
* Adds an ID for a subscription that is to be withdrawn.
*/
- public void addSubscriptionId(long id) {
- this.subscriptionIds.add(new Long(id));
+ public void addSubscriptionId(int id) {
+ this.subscriptionIds.add(new Integer(id));
}
// --------------------------------------------------- WebdavMethod Methods
@@ -40,6 +68,7 @@
public void recycle()
{
+ super.recycle();
this.subscriptionIds.clear();
}
@@ -68,7 +97,7 @@
StringTokenizer t = new StringTokenizer(headerValue, ", ");
try {
for(;t.hasMoreTokens();) {
- addSubscriptionId(Long.parseLong(t.nextToken()));
+ addSubscriptionId(Integer.parseInt(t.nextToken()));
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid header value '" +
1.1
jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/PollMethod.java
Index: PollMethod.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-slide/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/PollMethod.java,v
1.1 2004/07/13 08:47:30 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/07/13 08:47:30 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.webdav.lib.methods;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.util.DOMUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Implements the POLL WebDAV method.
*
* @author Stefan L�tzkendorf
* @see <a
href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_webdav_poll.asp">Reference</a>
*/
public class PollMethod extends XMLResponseMethodBase
{
private static final String HEADER_SUBSCRIPTION_ID = "Subscription-Id";
private static final String EXCHANGE_NS =
"http://schemas.microsoft.com/Exchange/";
private List subscriptionIds = new ArrayList();
private List subscriptionsWithEvents = new ArrayList();
private List subscriptionsWithoutEvents = new ArrayList();
public PollMethod() {
}
public PollMethod(String path) {
super(path);
}
/**
* Adds an ID for a subscription that is to be polled. All added subscription
* IDs should have the got same Content-Location uri from the SUBSCRIBE method.
*/
public void addSubscriptionId(int id) {
checkNotUsed();
this.subscriptionIds.add(new Integer(id));
}
/**
* Returns a list of number objects containing the subscription IDs for
* subscriptions for which events are reported.
* @return Collection of [EMAIL PROTECTED] Integer}s
*/
public Collection getSubscriptionsWithEvents() {
checkUsed();
return this.subscriptionsWithEvents;
}
/**
* Returns a list of number objects containing the subscription IDs for
* subscriptions for which <em>NO</em> events are reported.
* @return Collection of [EMAIL PROTECTED] Integer}s
*/
public Collection getSubscriptionsWithoutEvents() {
checkUsed();
return this.subscriptionsWithoutEvents;
}
// --------------------------------------------------- WebdavMethod Methods
public String getName()
{
return "POLL";
}
public void recycle()
{
super.recycle();
this.subscriptionIds.clear();
}
protected void addRequestHeaders(HttpState state, HttpConnection conn)
throws IOException, HttpException
{
super.addRequestHeaders(state, conn);
if (this.subscriptionIds.size() > 0) {
StringBuffer b = new StringBuffer();
boolean first = true;
for (Iterator i = this.subscriptionIds.iterator(); i.hasNext();) {
if (first) first = false; else b.append(", ");
b.append(i.next());
}
super.addRequestHeader(HEADER_SUBSCRIPTION_ID, b.toString());
}
}
/**
* Adds special checking of header values of the POLL method to
* the super class implementation.
*/
public void setRequestHeader(String headerName, String headerValue)
{
if (headerName.equalsIgnoreCase(HEADER_SUBSCRIPTION_ID)){
StringTokenizer t = new StringTokenizer(headerValue, ", ");
try {
for(;t.hasMoreTokens();) {
addSubscriptionId(Integer.parseInt(t.nextToken()));
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid header value '" +
headerValue + "' for header " + headerName + "!");
}
} else {
super.setRequestHeader(headerName, headerValue);
}
}
public void parseResponse(InputStream input, HttpState state,
HttpConnection conn) throws IOException, HttpException
{
int status = getStatusLine().getStatusCode();
if (status == HttpStatus.SC_MULTI_STATUS) {
parseXMLResponse(input);
NodeList list = getResponseDocument().getDocumentElement()
.getElementsByTagNameNS("DAV:", "response");
for(int i = 0; i < list.getLength(); i++) {
Element e = (Element)list.item(i);
NodeList s = e.getElementsByTagNameNS("DAV:", "status");
if (s.getLength() > 0) {
Element response = ((Element)(s.item(0)).getParentNode());
String statusText = DOMUtils.getTextValue((Element)s.item(0));
if (statusText.indexOf(" 200 ") != -1) {
// polled subscriptions for which *AN* event is fired
NodeList p = response.getElementsByTagNameNS(EXCHANGE_NS,
"subscriptionID");
if (p.getLength()>0) {
NodeList li = ((Element)p.item(0)).getElementsByTagName("li");
for(int l = 0; l < li.getLength();++l) {
String id = DOMUtils.getTextValue(li.item(i));
this.subscriptionsWithEvents.add(Integer.getInteger(id));
}
}
} else
if (statusText.indexOf(" 204 ") != -1) {
// polled subscriptions for which *NO* event is fired
NodeList p = response.getElementsByTagNameNS(EXCHANGE_NS,
"subscriptionID");
if (p.getLength()>0) {
NodeList li = ((Element)p.item(0)).getElementsByTagName("li");
for(int l = 0; l < li.getLength();++l) {
String id = DOMUtils.getTextValue(li.item(i));
this.subscriptionsWithoutEvents.add(Integer.getInteger(id));
}
}
}
}
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]