View Javadoc

1   /*
2    * Copyright (C) 2007 ETH Zurich
3    *
4    * This file is part of Fosstrak (www.fosstrak.org).
5    *
6    * Fosstrak is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License version 2.1, as published by the Free Software Foundation.
9    *
10   * Fosstrak is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with Fosstrak; if not, write to the Free
17   * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18   * Boston, MA  02110-1301  USA
19   */
20  
21  package org.fosstrak.epcis.repository.query;
22  
23  import java.io.Serializable;
24  import java.util.Calendar;
25  import java.util.Date;
26  
27  import javax.management.Notification;
28  import javax.management.NotificationListener;
29  import javax.management.timer.Timer;
30  
31  import org.fosstrak.epcis.model.ImplementationException;
32  import org.fosstrak.epcis.model.QueryParams;
33  import org.fosstrak.epcis.soap.ImplementationExceptionResponse;
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   * Special case of Subscription (from subscribe() on query interface) where the
39   * subscription is scheduled.
40   * 
41   * @author Alain Remund
42   * @author Arthur van Dorp
43   */
44  public class QuerySubscriptionScheduled extends QuerySubscription implements NotificationListener, Serializable {
45  
46      private static final long serialVersionUID = -5073503857856387167L;
47  
48      private static final Log LOG = LogFactory.getLog(QuerySubscriptionScheduled.class);
49  
50      /**
51       * Schedule indicating when subscription query is to be executed.
52       */
53      protected Schedule schedule;
54  
55      /**
56       * Whether to continue with sending results.
57       */
58      protected Boolean doItAgain = Boolean.TRUE;
59  
60      /**
61       * Constructor to be used when recreating from storage.
62       * 
63       * @param subscriptionID
64       *            The subscription ID.
65       * @param queryParams
66       *            Query parameters.
67       * @param dest
68       *            The destination URI.
69       * @param reportIfEmpty
70       *            Whether to report when nothing changed.
71       * @param initialRecordTime
72       *            The initial record time.
73       * @param lastTimeExecuted
74       *            The last time the query was executed.
75       * @param schedule
76       *            The query Schedule.
77       * @param queryName
78       *            The query name.
79       * @throws ImplementationException
80       *             If the Scheduler could not be started.
81       */
82      public QuerySubscriptionScheduled(final String subscriptionID, final QueryParams queryParams, final String dest,
83              final Boolean reportIfEmpty, final Calendar initialRecordTime,
84              final Calendar lastTimeExecuted, final Schedule schedule, final String queryName)
85              throws ImplementationExceptionResponse {
86          super(subscriptionID, queryParams, dest, reportIfEmpty, initialRecordTime, lastTimeExecuted, queryName);
87          this.schedule = schedule;
88          if (LOG.isDebugEnabled()) {
89              Date nextSchedule = schedule.nextScheduledTime().getTime();
90              LOG.debug("Next scheduled time for the subscribed query is '" + nextSchedule + "'.");
91              LOG.debug("URI to which to send results for the subscribed query is " + dest.toString());
92          }
93          startThread();
94      }
95  
96      /**
97       * Starts a Timer to get this query executed in specific time intervals.
98       * 
99       * @throws ImplementationException
100      *             If the next scheduled date cannot be evaluated.
101      */
102     private void startThread() throws ImplementationExceptionResponse {
103         Timer nextAction = new Timer();
104         nextAction.addNotificationListener(this, null, nextAction);
105 
106         Date nextSchedule = schedule.nextScheduledTime().getTime();
107         nextAction.addNotification("SubscriptionSchedule", "Please do the query", null, nextSchedule);
108         nextAction.start();
109     }
110 
111     /**
112      * Stops the re-execution of the schedule. This method is called when a
113      * subscribed query get's unsubscribed.
114      */
115     public void stopSubscription() {
116         doItAgain = Boolean.FALSE;
117     }
118 
119     /**
120      * The Object has definitely been destroyed. This may take a while.
121      */
122     protected void finalize() {
123         LOG.debug("A subscribed query has been garbage collected.");
124     }
125 
126     /**
127      * This method is handles a notification when the Timer for the schedule
128      * times out.
129      * 
130      * @see javax.management.NotificationListener#handleNotification(javax.management.Notification,
131      *      java.lang.Object)
132      * @param pNotification
133      *            The Notification.
134      * @param pHandback
135      *            A Timer stating the time when the Notification should be
136      *            invoked.
137      */
138     public void handleNotification(final Notification pNotification, final Object pHandback) {
139         if (pHandback == null) {
140             LOG.error("The timer stating the next scheduled query execution time is null!");
141             return;
142         }
143         Timer timer = (Timer) pHandback;
144 
145         if (!doItAgain.booleanValue()) {
146             timer.stop();
147         } else {
148             // execute the query and determine next scheduled execution time
149             executeQuery();
150             setNextScheduledExecutionTime(timer);
151         }
152     }
153 
154     /**
155      * Determines the next scheduled execution time for this subscribed query.
156      * 
157      * @param timer
158      *            The Timer to set the next scheduled time.
159      * @throws IllegalArgumentException
160      */
161     protected void setNextScheduledExecutionTime(final Timer timer) throws IllegalArgumentException {
162         try {
163             Date nextSchedule = schedule.nextScheduledTime().getTime();
164             LOG.debug("Next scheduled time for the subscribed query is '" + nextSchedule + "'.");
165             timer.addNotification("SubscriptionSchedule", "Please do the query", timer, nextSchedule);
166         } catch (ImplementationExceptionResponse e) {
167             String msg = "The next scheduled date for the subscribed query with ID '" + getSubscriptionID()
168                     + "' cannot be evaluated: " + e.getMessage();
169             LOG.error(msg, e);
170         }
171     }
172 
173 }