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