1   /*
2    *  AbstractProcessingResource.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Hamish Cunningham, 10/Nov/2000
12   *
13   *  $Id: AbstractProcessingResource.java,v 1.20 2005/01/11 13:51:31 ian Exp $
14   */
15  
16  package gate.creole;
17  
18  import java.util.Vector;
19  
20  import gate.ProcessingResource;
21  import gate.Resource;
22  import gate.event.ProgressListener;
23  import gate.event.StatusListener;
24  
25  /** A convenience implementation of ProcessingResource with some default
26    * code.
27    */
28  abstract public class AbstractProcessingResource
29  extends AbstractResource implements ProcessingResource, ANNIEConstants
30  {
31    /** Initialise this resource, and return it. */
32    public Resource init() throws ResourceInstantiationException {
33      return this;
34    } // init()
35  
36    /** Run the resource. It doesn't make sense not to override
37     *  this in subclasses so the default implementation signals an
38     *  exception.
39     */
40    public void execute() throws ExecutionException{
41      throw new ExecutionException(
42        "Resource " + getClass() + " hasn't overriden the execute() method"
43      );
44    } // execute()
45  
46    /**
47     * Reinitialises the processing resource. After calling this method the
48     * resource should be in the state it is after calling init.
49     * If the resource depends on external resources (such as rules files) then
50     * the resource will re-read those resources. If the data used to create
51     * the resource has changed since the resource has been created then the
52     * resource will change too after calling reInit().
53     * The implementation in this class simply calls {@link #init()}. This
54     * functionality must be overriden by derived classes as necessary.
55     */
56    public void reInit() throws ResourceInstantiationException{
57      init();
58    } // reInit()
59  
60    /** should clear all internal data of the resource. Does nothing now */
61    public void cleanup() {
62    }
63  
64    /**
65     * Checks whether this PR has been interrupted since the last time its
66     * {@link #execute()} method was called.
67     */
68    public synchronized boolean isInterrupted(){
69      return interrupted;
70    }
71  
72    /**
73     * Notifies this PR that it should stop its execution as soon as possible.
74     */
75    public synchronized void interrupt(){
76      interrupted = true;
77    }
78  
79  
80    /**
81     * Removes a {@link gate.event.StatusListener} from the list of listeners for
82     * this processing resource
83     */
84    public synchronized void removeStatusListener(StatusListener l) {
85      if (statusListeners != null && statusListeners.contains(l)) {
86        Vector v = (Vector) statusListeners.clone();
87        v.removeElement(l);
88        statusListeners = v;
89      }
90    }
91  
92    /**
93     * Adds a {@link gate.event.StatusListener} to the list of listeners for
94     * this processing resource
95     */
96    public synchronized void addStatusListener(StatusListener l) {
97      Vector v = statusListeners == null ? new Vector(2) : (Vector) statusListeners.clone();
98      if (!v.contains(l)) {
99        v.addElement(l);
100       statusListeners = v;
101     }
102   }
103 
104   /**
105    * Notifies all the {@link gate.event.StatusListener}s of a change of status.
106    * @param e the message describing the status change
107    */
108   protected void fireStatusChanged(String e) {
109     if (statusListeners != null) {
110       Vector listeners = statusListeners;
111       int count = listeners.size();
112       for (int i = 0; i < count; i++) {
113         ((StatusListener) listeners.elementAt(i)).statusChanged(e);
114       }
115     }
116   }
117 
118   /**
119    * Adds a {@link gate.event.ProgressListener} to the list of listeners for
120    * this processing resource.
121    */
122   public synchronized void addProgressListener(ProgressListener l) {
123     Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone();
124     if (!v.contains(l)) {
125       v.addElement(l);
126       progressListeners = v;
127     }
128   }
129 
130   /**
131    * Removes a {@link gate.event.ProgressListener} from the list of listeners
132    * for this processing resource.
133    */
134   public synchronized void removeProgressListener(ProgressListener l) {
135     if (progressListeners != null && progressListeners.contains(l)) {
136       Vector v = (Vector) progressListeners.clone();
137       v.removeElement(l);
138       progressListeners = v;
139     }
140   }
141 
142   /**
143    * Notifies all the {@link gate.event.ProgressListener}s of a progress change
144    * event.
145    * @param e the new value of execution completion
146    */
147   protected void fireProgressChanged(int e) {
148     if (progressListeners != null) {
149       Vector listeners = progressListeners;
150       int count = listeners.size();
151       for (int i = 0; i < count; i++) {
152         ((ProgressListener) listeners.elementAt(i)).progressChanged(e);
153       }
154     }
155   }
156 
157   /**
158    * Notifies all the {@link gate.event.ProgressListener}s of a progress
159    * finished.
160    */
161   protected void fireProcessFinished() {
162     if (progressListeners != null) {
163       Vector listeners = progressListeners;
164       int count = listeners.size();
165       for (int i = 0; i < count; i++) {
166         ((ProgressListener) listeners.elementAt(i)).processFinished();
167       }
168     }
169   }
170 
171   /**
172    * A progress listener used to convert a 0..100 interval into a smaller one
173    */
174   protected class IntervalProgressListener implements ProgressListener{
175     public IntervalProgressListener(int start, int end){
176       this.start = start;
177       this.end = end;
178     }
179     public void progressChanged(int i){
180       fireProgressChanged(start + (end - start) * i / 100);
181     }
182 
183     public void processFinished(){
184       fireProgressChanged(end);
185     }
186 
187     int start;
188     int end;
189   }//IntervalProgressListener
190 
191   /**
192    * A simple status listener used to forward the events upstream.
193    */
194   protected class InternalStatusListener implements StatusListener{
195     public void statusChanged(String message){
196       fireStatusChanged(message);
197     }
198   }//InternalStatusListener
199 
200   /**
201    * The list of {@link gate.event.StatusListener}s registered with this
202    * resource
203    */
204   private transient Vector statusListeners;
205 
206   /**
207    * The list of {@link gate.event.ProgressListener}s registered with this
208    * resource
209    */
210   private transient Vector progressListeners;
211 
212   protected boolean interrupted = false;
213 } // class AbstractProcessingResource
214