applied LGPLv3 and source code formatting.
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / WatcherElement.java
1 /*\r
2  * This file is part of the Vamsas Client version 0.1. \r
3  * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, \r
4  *  Andrew Waterhouse and Dominik Lindner.\r
5  * \r
6  * Earlier versions have also been incorporated into Jalview version 2.4 \r
7  * since 2008, and TOPALi version 2 since 2007.\r
8  * \r
9  * The Vamsas Client is free software: you can redistribute it and/or modify\r
10  * it under the terms of the GNU Lesser General Public License as published by\r
11  * the Free Software Foundation, either version 3 of the License, or\r
12  * (at your option) any later version.\r
13  *  \r
14  * The Vamsas Client is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU Lesser General Public License for more details.\r
18  * \r
19  * You should have received a copy of the GNU Lesser General Public License\r
20  * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.\r
21  */\r
22 package uk.ac.vamsas.client.simpleclient;\r
23 \r
24 public abstract class WatcherElement {\r
25 \r
26   private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory\r
27       .getLog(VamsasFileWatcherElement.class);\r
28 \r
29   protected FileWatcher watcher = null;\r
30 \r
31   protected WatcherCallBack handler = null;\r
32 \r
33   /**\r
34    * set this to false to stop the thread\r
35    */\r
36   protected boolean watchForChange = true;\r
37 \r
38   /**\r
39    * true when the handler is being called for this watcher\r
40    */\r
41   protected boolean handlerCalled = false;\r
42 \r
43   public WatcherElement(WatcherCallBack handler) {\r
44     this.handler = handler;\r
45   }\r
46 \r
47   /**\r
48    * will instruct watcher to stop and wait around for one WATCH_SLEEP before\r
49    * returning. If no thread is running then it returns immediately.\r
50    */\r
51   public void haltWatch() {\r
52     // set the flag to skip this watch element.\r
53     watchForChange = false;\r
54     if (log.isDebugEnabled())\r
55       log.debug("haltWatch on " + watcher.getSubject());\r
56     endWatch();\r
57     if (log.isDebugEnabled())\r
58       log.debug("haltWatch completed on " + watcher.getSubject());\r
59   }\r
60 \r
61   /**\r
62    * called by haltWatch before clearing the FileWatcher reference.\r
63    * \r
64    */\r
65   protected abstract void endWatch();\r
66 \r
67   /**\r
68    * called to generate the watcher object by enableWatch and in doWatch\r
69    * \r
70    */\r
71   protected abstract void initWatch();\r
72 \r
73   /**\r
74    * implemented for debug information purposes.\r
75    * \r
76    * @return Informative string about what the watcher is watching\r
77    */\r
78   protected abstract String getSubject();\r
79 \r
80   /**\r
81    * must be called by implementations of enablewatch\r
82    */\r
83   protected void enableWatch() {\r
84     if (log.isDebugEnabled())\r
85       log.debug("enableWatch on " + getSubject());\r
86     watchForChange = true;\r
87     initWatch();\r
88     if (log.isDebugEnabled())\r
89       log.debug("enableWatch returning on " + getSubject());\r
90   }\r
91 \r
92   /**\r
93    * Originally from the uk.ac.vamsas.test.simpleclient.ArchiveClient method\r
94    * \r
95    * @return true if the handler was called for a changeEvent\r
96    */\r
97   public boolean doWatch() {\r
98     if (!watchForChange || handler == null)\r
99       return false;\r
100     if (watcher == null)\r
101       initWatch(); // somehow not done the first time\r
102     handlerCalled = false;\r
103     Lock doclock = null;\r
104     try {\r
105       doclock = watcher.getChangedState();\r
106     } catch (Exception e) {\r
107       log.error("Whilst watching " + watcher.getSubject(), e);\r
108     }\r
109     if (doclock == null)\r
110       return false;\r
111     /*\r
112      * handlerCalled=true; if (log.isDebugEnabled())\r
113      * log.debug("Triggering watchEvent for change on "+watcher.getSubject());\r
114      * boolean finish=!handler.handleWatchEvent(this, doclock); doclock=null; //\r
115      * TODO: check that lock should really be released rather than dereferenced\r
116      * if (finish) haltWatch(); else enableWatch(); handlerCalled=false;\r
117      */\r
118     this.callHandler(doclock);\r
119     return true;\r
120   }\r
121 \r
122   /**\r
123    * Calls the current eventhandler\r
124    * \r
125    * @param doclock\r
126    *          the lock on the watch file\r
127    */\r
128   protected void callHandler(Lock doclock) {\r
129     if (log.isDebugEnabled())\r
130       log.debug("Triggering watchEvent for change on " + watcher.getSubject());\r
131     boolean finish = !handler.handleWatchEvent(this, doclock);\r
132     doclock = null; // TODO: check that lock should really be released rather\r
133                     // than dereferenced\r
134     if (finish)\r
135       haltWatch();\r
136     else\r
137       enableWatch();\r
138     handlerCalled = false;\r
139   }\r
140 \r
141   /**\r
142    * @return the handler\r
143    */\r
144   public WatcherCallBack getHandler() {\r
145     return handler;\r
146   }\r
147 \r
148   /**\r
149    * @return the handlerCalled\r
150    */\r
151   public boolean isHandlerCalled() {\r
152     return handlerCalled;\r
153   }\r
154 \r
155   /**\r
156    * \r
157    * @return true if watcher is enabled\r
158    */\r
159   public boolean isWatchEnabled() {\r
160     return watchForChange;\r
161   }\r
162 \r
163   /**\r
164    * @param handler\r
165    *          the handler to set\r
166    */\r
167   public void setHandler(WatcherCallBack handler) {\r
168     this.handler = handler;\r
169   }\r
170 \r
171   /**\r
172    * @return the watcher\r
173    */\r
174   public FileWatcher getWatcher() {\r
175     return watcher;\r
176   }\r
177 }\r