dflorey     2004/02/24 09:05:37

  Added:       src/webdav/server/org/apache/slide/webdav/event
                        NotificationException.java NotificationTrigger.java
                        NotifyMethod.java Subscriber.java
               src/webdav/server/org/apache/slide/webdav/method
                        PollMethod.java SubscribeMethod.java
               src/webdav/server/org/apache/slide/webdav/util
                        NotificationConstants.java
  Log:
  Added notification support with methods SUBSCRIBE, POLL, NOTIFY
  To do: UNSUBSCRIBE
  
  Revision  Changes    Path
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/NotificationException.java
  
  Index: NotificationException.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/NotificationException.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.event;
  
  import org.apache.slide.common.SlideException;
  
  /**
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   * @version $Revision: 1.1 $
   */
  
  public class NotificationException extends SlideException {
      public NotificationException(String message) {
          super(message);
      }
  
      public NotificationException(String message, boolean showTrace) {
          super(message, showTrace);
      }
  }
  
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/NotificationTrigger.java
  
  Index: NotificationTrigger.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/NotificationTrigger.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.event;
  
  import org.apache.commons.httpclient.HttpConnection;
  import org.apache.commons.httpclient.HttpState;
  import org.apache.slide.common.Domain;
  import org.apache.slide.event.EventCollection;
  import org.apache.slide.event.EventCollectionListener;
  import org.apache.slide.event.VetoException;
  import org.apache.slide.util.conf.Configurable;
  import org.apache.slide.util.conf.Configuration;
  import org.apache.slide.util.conf.ConfigurationException;
  import org.apache.slide.util.logger.Logger;
  import org.apache.slide.webdav.util.NotificationConstants;
  
  import java.io.IOException;
  import java.net.URL;
  import java.util.*;
  
  /**
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   * @version $Revision: 1.1 $
   */
  
  public class NotificationTrigger implements NotificationConstants, 
EventCollectionListener, Configurable {
      protected static final String LOG_CHANNEL = NotificationTrigger.class.getName();
      private final static String A_INCLUDE_EVENTS = "include-events";
      private final static String A_PROTOCOL = "protocol";
      private final static String TCP = "tcp";
      private final static String UDP = "udp";
  
      protected static final Timer timer = new Timer();
  
      protected List subscribers = new ArrayList();
      protected int subscriberId = 0;
      protected String protocol = TCP;
      protected boolean includeEvents = false;
  
      private static NotificationTrigger notificationTrigger = new 
NotificationTrigger();
  
      private NotificationTrigger() {
          Domain.log("Creating notification trigger", LOG_CHANNEL, Logger.INFO);
      }
  
      public static NotificationTrigger getInstance() {
          return notificationTrigger;
      }
  
      public int addSubscriber(Subscriber subscriber) {
          Domain.log("Adding subscriber", LOG_CHANNEL, Logger.INFO);
          subscriberId++;
          subscriber.setId(subscriberId);
          subscribers.add(subscriber);
          refreshSubscriber(subscriber);
          return subscriberId;
      }
  
      public void refreshSubscriber(final Subscriber subscriber) {
          TimerTask lifetimeTask = subscriber.getLifetime();
          if ( lifetimeTask != null ) lifetimeTask.cancel();
          if ( subscriber.getSubscriptionLifetime() > 0 ) {
              Domain.log("Refreshing subscriber with ID: "+subscriber.getId(), 
LOG_CHANNEL, Logger.INFO);
              TimerTask lifetime = new TimerTask() {
                  public void run() {
                      Domain.log("Removing subscriber with ID: "+subscriber.getId(), 
LOG_CHANNEL, Logger.INFO);
                      subscribers.remove(subscriber);
                  }
              };
              subscriber.setLifetime(lifetime);
              timer.schedule(lifetime, subscriber.getSubscriptionLifetime()*1000);
          }
      }
  
      public List getSubscribers() {
          return subscribers;
      }
  
      public Subscriber getSubscriber(int id) {
          for ( Iterator i = subscribers.iterator(); i.hasNext(); ) {
              Subscriber subsciber = (Subscriber)i.next();
              if ( subsciber.getId() == id ) {
                  return subsciber;
              }
          }
          return null;
      }
  
      public void vetoableCollected(EventCollection collection) throws VetoException {
      }
  
      public void collected(EventCollection collection) {
          notifySubscribers(collection);
      }
  
      private void notifySubscribers(EventCollection collection) {
          List events = collection.getCollection();
          Map subscriberEnumerations = new HashMap();
          for ( Iterator i = events.iterator(); i.hasNext(); ) {
              EventCollection.Event event = (EventCollection.Event)i.next();
              Subscriber[] subscribers = getSubscribers(event);
              for ( int j = 0; j < subscribers.length; j++ ) {
                  final Subscriber subscriber = subscribers[j];
                  if ( subscriber.getNotificationDelay() == 0 ) {
                      // send notification without delay
                      List idList = 
(List)subscriberEnumerations.get(subscriber.getCallback());
                      if ( idList == null ) {
                          idList = new ArrayList();
                          subscriberEnumerations.put(subscriber.getCallback(), idList);
                      }
                      idList.add(new Integer(subscriber.getId()));
                  } else {
                      // send delayed notification
                      TimerTask notifyTask = subscriber.getNotify();
                      if ( notifyTask == null ) {
                          Domain.log("Starting notification delay: 
"+subscriber.getNotificationDelay(), LOG_CHANNEL, Logger.INFO);
                          notifyTask = new TimerTask() {
                              public void run() {
                                  notifySubscriber(subscriber.getCallback(), 
String.valueOf(subscriber.getId()));
                                  subscriber.setNotify(null);
                              }
                          };
                          subscriber.setNotify(notifyTask);
                          timer.schedule(notifyTask, 
subscriber.getNotificationDelay()*1000);
                      }
                  }
                  // remember this event for later poll method call
                  ((Subscriber)subscriber).addEvent(event);
              }
          }
          for ( Iterator i = subscriberEnumerations.entrySet().iterator(); 
i.hasNext(); ) {
              Map.Entry entry = (Map.Entry)i.next();
              URL callBack = (URL)entry.getKey();
              List idList = (List)entry.getValue();
              StringBuffer subscriberBuffer = new StringBuffer(128);
              boolean firstSubscriber = true;
              for ( Iterator j = idList.iterator(); j.hasNext(); ) {
                  Integer id = (Integer)j.next();
                  if ( !firstSubscriber ) {
                      subscriberBuffer.append(", ");
                  }
                  firstSubscriber = false;
                  subscriberBuffer.append(id);
              }
              notifySubscriber(callBack, subscriberBuffer.toString());
          }
      }
  
      private void notifySubscriber(URL callback, String subscribers) {
          if ( protocol.equals(TCP) ) {
              Domain.log("Notify subscribers with adress='"+callback+"' via TCP with 
id's "+subscribers, LOG_CHANNEL, Logger.INFO);
              NotifyMethod notifyMethod = new NotifyMethod(callback.toString());
              notifyMethod.addRequestHeader(H_SUBSCRIPTION_ID, subscribers);
              try {
                  int state = notifyMethod.execute(new HttpState(), new 
HttpConnection(callback.getHost(), callback.getPort()));
              } catch (IOException e) {
                  Domain.log("Notification of subscriber '"+callback.toString()+"' 
failed!");
              }
          } else {
              Domain.log("UDP not yet implemented...");
          }
      }
  
      private Subscriber []getSubscribers(EventCollection.Event event) {
          List matchingSubscribers = new ArrayList();
          for ( Iterator i = subscribers.iterator(); i.hasNext(); ) {
              Subscriber subscriber = (Subscriber)i.next();
              if ( subscriber.matches(event)) {
                  matchingSubscribers.add(subscriber);
              }
          }
          Subscriber[] subscribers = new Subscriber[matchingSubscribers.size()];
          return (Subscriber [])matchingSubscribers.toArray(subscribers);
      }
  
      public void configure(Configuration configuration) throws ConfigurationException 
{
          Configuration notification = configuration.getConfiguration("notification");
          protocol = notification.getAttribute(A_PROTOCOL, TCP);
          includeEvents = notification.getAttributeAsBoolean(A_INCLUDE_EVENTS, false);
      }
  }
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/NotifyMethod.java
  
  Index: NotifyMethod.java
  ===================================================================
  package org.apache.slide.webdav.event;
  
  import org.apache.commons.httpclient.methods.PostMethod;
  
  public class NotifyMethod extends PostMethod {
      public NotifyMethod(String s) throws IllegalArgumentException, 
IllegalStateException {
          super(s);
      }
  
      public String getName() {
          return "NOTIFY";
      }
  }
  
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/Subscriber.java
  
  Index: Subscriber.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/event/Subscriber.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.event;
  
  import org.apache.slide.common.Namespace;
  import org.apache.slide.common.Domain;
  import org.apache.slide.content.NodeRevisionContent;
  import org.apache.slide.content.NodeRevisionDescriptor;
  import org.apache.slide.content.NodeRevisionDescriptors;
  import org.apache.slide.util.logger.Logger;
  import org.apache.slide.webdav.method.AbstractWebdavMethod;
  import org.apache.slide.event.EventCollection;
  import org.apache.slide.event.ResourceEvent;
  
  import java.net.URL;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.TimerTask;
  
  /**
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   * @version $Revision: 1.1 $
   */
  
  public class Subscriber {
      protected static final String LOG_CHANNEL = Subscriber.class.getName();
  
      private URL callback;
      private String notificationType, uri;
      private int depth, notificationDelay, subscriptionLifetime, id;
      private List events = new ArrayList();
      private TimerTask lifetime, notify;
  
      public Subscriber(String uri, String contentType, URL callback, String 
notificationType, int notificationDelay, int subscriptionLifetime, int depth) {
          this.callback = callback;
          this.notificationType = notificationType;
          this.notificationDelay = notificationDelay;
          this.subscriptionLifetime = subscriptionLifetime;
          this.uri = uri;
          this.depth = depth;
      }
  
      public void addEvent(EventCollection.Event event) {
          events.add(event);
      }
  
      public List getEvents() {
          return events;
      }
  
      public void clearEvents() {
          events = new ArrayList();
      }
  
      public TimerTask getLifetime() {
          return lifetime;
      }
  
      public void setLifetime(TimerTask lifetime) {
          this.lifetime = lifetime;
      }
  
      public TimerTask getNotify() {
          return notify;
      }
  
      public void setNotify(TimerTask notify) {
          this.notify = notify;
      }
  
      public boolean matches(EventCollection.Event event) {
          boolean matching = false;
          if ( event.getEvent() instanceof ResourceEvent ) {
              String eventUri = ((ResourceEvent)event.getEvent()).getUri();
              if ( eventUri != null && uri != null && ((depth == 
AbstractWebdavMethod.INFINITY && eventUri.startsWith(uri.toString())) || (depth == 0 
&& eventUri.equals(uri.toString())))) {
                  matching = true;
              }
          }
          return matching;
      }
  
      public URL getCallback() {
          return callback;
      }
  
      public String getNotificationType() {
          return notificationType;
      }
  
      public int getNotificationDelay() {
          return notificationDelay;
      }
  
      public void setSubscriptionLifetime(int subscriptionLifetime) {
          this.subscriptionLifetime = subscriptionLifetime;
      }
  
      public int getSubscriptionLifetime() {
          return subscriptionLifetime;
      }
  
      public int getId() {
          return id;
      }
  
      public void setId(int id) {
          this.id = id;
      }
  }
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PollMethod.java
  
  Index: PollMethod.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PollMethod.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.method;
  
  import org.apache.slide.common.NamespaceAccessToken;
  import org.apache.slide.event.EventDispatcher;
  import org.apache.slide.event.EventCollection;
  import org.apache.slide.event.ResourceEvent;
  import org.apache.slide.event.RemoteInformation;
  import org.apache.slide.webdav.WebdavException;
  import org.apache.slide.webdav.WebdavServletConfig;
  import org.apache.slide.webdav.event.WebdavEvent;
  import org.apache.slide.webdav.event.NotificationTrigger;
  import org.apache.slide.webdav.event.Subscriber;
  import org.apache.slide.webdav.util.NotificationConstants;
  import org.apache.util.WebdavStatus;
  import org.jdom.Document;
  import org.jdom.Element;
  import org.jdom.Namespace;
  import org.jdom.Attribute;
  import org.jdom.output.XMLOutputter;
  
  import java.util.List;
  import java.util.Iterator;
  import java.util.EventObject;
  
  
  /**
   * Subscribe Method.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   */
  public class PollMethod extends AbstractWebdavMethod implements 
NotificationConstants {
      protected final static String LOG_CHANNEL = PollMethod.class.getName();
      protected final static Namespace NNSP = Namespace.getNamespace(N_PREFIX, N_URI);
  
      // An XML outputter
      private XMLOutputter xmlOut = new XMLOutputter(XML_RESPONSE_INDENT, true, 
"UTF-8" );
  
  
      // ----------------------------------------------------------- Constructors
      
      
      /**
       * Constructor.
       *
       * @param token     the token for accessing the namespace
       * @param config    configuration of the WebDAV servlet
       */
      public PollMethod(NamespaceAccessToken token, WebdavServletConfig config) {
          super(token, config);
      }
      
      protected void parseRequest() throws WebdavException {
      }
      
      protected void executeRequest() throws WebdavException {
          try {
              if ( WebdavEvent.POLL.isEnabled() ) 
EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.POLL, new 
WebdavEvent(this));
              int []subscriptionID = requestHeaders.getSubscriptionId();
              // includes subscription id's that are not valid any more but requested 
in the poll-request
              resp.setContentType( TEXT_XML_UTF_8 );
              resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
              Element multistatus = new Element(E_MULTISTATUS, DNSP);
              boolean content = false;
              boolean noContent = false;
              Element contentResponse = new Element(E_RESPONSE, DNSP);
              int statusCode = WebdavStatus.SC_OK;
              generateStatusText(contentResponse, req.getRequestURL().toString(), 
statusCode);
              Element noContentResponse = new Element(E_RESPONSE, DNSP);
              statusCode = WebdavStatus.SC_NO_CONTENT;
              generateStatusText(noContentResponse, req.getRequestURL().toString(), 
statusCode);
              Element subscriptionIdContent = new Element(E_SUBSCRIPTION_ID, NNSP);
              Element subscriptionIdNoContent = new Element(E_SUBSCRIPTION_ID, NNSP);
              contentResponse.addContent(subscriptionIdContent);
              noContentResponse.addContent(subscriptionIdNoContent);
              for ( int i = 0; i < subscriptionID.length; i++ ) {
                  // sort subscribers by the occurance of events
                  Subscriber subscriber = 
NotificationTrigger.getInstance().getSubscriber(subscriptionID[i]);
                  if ( subscriber != null ) {
                      NotificationTrigger.getInstance().refreshSubscriber(subscriber);
                      List events = subscriber.getEvents();
                      if ( events.size() == 0 ) {
                          noContent = true;
                          Element listener = new Element(E_LISTENER, NNSP);
                          listener.addContent(String.valueOf(subscriber.getId()));
                          subscriptionIdNoContent.addContent(listener);
                      } else {
                          content = true;
                          Element listener = new Element(E_LISTENER, NNSP);
                          listener.addContent(String.valueOf(subscriber.getId()));
                          subscriptionIdContent.addContent(listener);
                          for ( Iterator j = events.iterator(); j.hasNext(); ) {
                              EventObject event = 
((EventCollection.Event)j.next()).getEvent();
                              if ( event instanceof RemoteInformation ) {
                                  Element eventElement = new Element(E_EVENT, NNSP);
                                  String[][] information = 
((RemoteInformation)event).getInformation();
                                  for ( int k = 0; k < information.length; k++ ) {
                                      Element entry = new Element(E_INFORMATION, NNSP);
                                      entry.setAttribute(A_NAME, information[k][0]);
                                      
entry.addContent(String.valueOf(information[k][1]));
                                      eventElement.addContent(entry);
                                  }
                                  subscriptionIdContent.addContent(eventElement);
                              }
                          }
                          subscriber.clearEvents();
                      }
                  }
              }
              if ( content ) {
                  multistatus.addContent(contentResponse);
              }
              if ( noContent ) {
                  multistatus.addContent(noContentResponse);
              }
              xmlOut.output(new Document(multistatus), resp.getWriter());
          } catch (Exception e) {
              int statusCode = getErrorCode( (Exception)e );
              sendError( statusCode, e );
              throw new WebdavException( statusCode );
          }
      }
  }
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/SubscribeMethod.java
  
  Index: SubscribeMethod.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/SubscribeMethod.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.method;
  
  import org.apache.slide.common.NamespaceAccessToken;
  import org.apache.slide.common.SlideException;
  import org.apache.slide.common.Domain;
  import org.apache.slide.event.EventDispatcher;
  import org.apache.slide.webdav.WebdavException;
  import org.apache.slide.webdav.WebdavServletConfig;
  import org.apache.slide.webdav.event.WebdavEvent;
  import org.apache.slide.webdav.event.NotificationTrigger;
  import org.apache.slide.webdav.event.Subscriber;
  import org.apache.slide.webdav.util.NotificationConstants;
  import org.apache.slide.util.logger.Logger;
  import org.apache.util.WebdavStatus;
  import org.jdom.output.XMLOutputter;
  
  import java.net.URL;
  import java.net.MalformedURLException;
  
  
  /**
   * Subscribe Method.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   */
  public class SubscribeMethod extends AbstractWebdavMethod implements 
NotificationConstants {
      protected static final String LOG_CHANNEL = SubscribeMethod.class.getName();
  
      private final static int DEFAULT_SUBSCRIPTION_LIFETIME = 3600;
  
      // An XML outputter
      private XMLOutputter xmlOut = new XMLOutputter(XML_RESPONSE_INDENT, true, 
"UTF-8" );
      //  private Namespace xmlNs = Namespace.getNamespace(DEFAULT_NAMESPACE);
      
      // ----------------------------------------------------------- Constructors
      
      
      /**
       * Constructor.
       *
       * @param token     the token for accessing the namespace
       * @param config    configuration of the WebDAV servlet
       */
      public SubscribeMethod(NamespaceAccessToken token,
                           WebdavServletConfig config) {
          super(token, config);
      }
      
      protected void parseRequest() throws WebdavException {
      }
      
      protected void executeRequest() throws WebdavException {
          try {
              if ( WebdavEvent.SUBSCRIBE.isEnabled() ) 
EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.SUBSCRIBE, new 
WebdavEvent(this));
              String contentType = null; // FIXME: extend request header
              String callback = requestHeaders.getCallback();
              String notificationType = requestHeaders.getNotificationType();
              int notificationDelay = requestHeaders.getNotificationDelay(0);
              int subscriptionLifetime = 
requestHeaders.getSubscriptionLifetime(DEFAULT_SUBSCRIPTION_LIFETIME);
              int depth = requestHeaders.getDepth(INFINITY);
              int []subscriptionIDs = requestHeaders.getSubscriptionId();
              if ( subscriptionIDs.length > 0 ) {
                  // renew subscribers
                  for ( int i = 0; i < subscriptionIDs.length; i++ ) {
                      Subscriber subscriber = 
NotificationTrigger.getInstance().getSubscriber(subscriptionIDs[i]);
                      if ( subscriber != null ) {
                          
NotificationTrigger.getInstance().refreshSubscriber(subscriber);
                      }
                  }
              } else {
                  Subscriber subscriber = new Subscriber(requestUri, contentType, new 
URL(callback), notificationType, notificationDelay, subscriptionLifetime, depth);
                  int subscriptionID = 
NotificationTrigger.getInstance().addSubscriber(subscriber);
                  resp.setHeader("call-back", callback);
                  resp.setHeader("notification-type", notificationType);
                  resp.setHeader("Subscription-lifetime", 
String.valueOf(subscriptionLifetime));
                  resp.setHeader("Subscription-id", String.valueOf(subscriptionID));
                  resp.setHeader("Content-Location", requestUri);
                  resp.setStatus(WebdavStatus.SC_OK);
              }
          } catch (Exception e) {
              int statusCode = getErrorCode( (Exception)e );
              sendError( statusCode, e );
              throw new WebdavException( statusCode );
          }
      }
  }
  
  
  1.1                  
jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/NotificationConstants.java
  
  Index: NotificationConstants.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/NotificationConstants.java,v
 1.1 2004/02/24 17:05:37 dflorey Exp $
   * $Revision: 1.1 $
   * $Date: 2004/02/24 17:05:37 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Slide", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.slide.webdav.util;
  
  /**
   * DeltaV constants.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Daniel Florey</a>
   */
  public interface NotificationConstants extends WebdavConstants {
      /** Headers */
      String H_NOTIFICATION_TYPE                                            = 
"Notification-type";
      String H_NOTIFICATION_DELAY                                           = 
"Notification-delay";
      String H_SUBSCRIPTION_LIFETIME                                        = 
"Subscription-lifetime";
      String H_SUBSCRIPTION_ID                                              = 
"Subscription-ID";
      String H_CALL_BACK                                                    = 
"Call-back";
  
      /** XML Elements */
      String E_SUBSCRIPTION_ID                                              = 
"subscriptionID";
      String E_LISTENER                                                     = "li";
      String E_EVENT                                                        = "event";
      String E_INFORMATION                                                  = 
"information";
  
      /** Namespace */
      String N_PREFIX                                                       = "N";
      String N_URI                                                          = 
"http://schemas.microsoft.com/Exchange/";;
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to