AbstractProcessingResource.java
001 /*
002  *  AbstractProcessingResource.java
003  *
004  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Hamish Cunningham, 10/Nov/2000
013  *
014  *  $Id: AbstractProcessingResource.java 17588 2014-03-08 07:50:36Z markagreenwood $
015  */
016 
017 package gate.creole;
018 
019 import java.util.Vector;
020 
021 import gate.FeatureMap;
022 import gate.Gate;
023 import gate.ProcessingResource;
024 import gate.Resource;
025 import gate.event.ProgressListener;
026 import gate.event.StatusListener;
027 
028 /** A convenience implementation of ProcessingResource with some default
029   * code.
030   */
031 abstract public class AbstractProcessingResource
032 extends AbstractResource implements ProcessingResource, ANNIEConstants
033 {
034   private static final long serialVersionUID = -5919543745701986862L;
035 
036   /** Initialise this resource, and return it. */
037   @Override
038   public Resource init() throws ResourceInstantiationException {
039     return this;
040   // init()
041 
042   /** Run the resource. It doesn't make sense not to override
043    *  this in subclasses so the default implementation signals an
044    *  exception.
045    */
046   @Override
047   public void execute() throws ExecutionException{
048     throw new ExecutionException(
049       "Resource " + getClass() " hasn't overriden the execute() method"
050     );
051   // execute()
052 
053   /**
054    * Reinitialises the processing resource. After calling this method the
055    * resource should be in the state it is after calling init.
056    * If the resource depends on external resources (such as rules files) then
057    * the resource will re-read those resources. If the data used to create
058    * the resource has changed since the resource has been created then the
059    * resource will change too after calling reInit().
060    * The implementation in this class simply calls {@link #init()}. This
061    * functionality must be overriden by derived classes as necessary.
062    */
063   @Override
064   public void reInit() throws ResourceInstantiationException{
065     init();
066   // reInit()
067 
068   /** should clear all internal data of the resource. Does nothing now */
069   @Override
070   public void cleanup() {
071   }
072 
073   /**
074    * Checks whether this PR has been interrupted since the last time its
075    {@link #execute()} method was called.
076    */
077   @Override
078   public boolean isInterrupted(){
079     return interrupted;
080   }
081 
082   /**
083    * Notifies this PR that it should stop its execution as soon as possible.
084    */
085   @Override
086   public void interrupt(){
087     interrupted = true;
088   }
089 
090 
091   /**
092    * Removes a {@link gate.event.StatusListener} from the list of listeners for
093    * this processing resource
094    */
095   public synchronized void removeStatusListener(StatusListener l) {
096     if (statusListeners != null && statusListeners.contains(l)) {
097       @SuppressWarnings("unchecked")
098       Vector<StatusListener> v = (Vector<StatusListener>)statusListeners.clone();
099       v.removeElement(l);
100       statusListeners = v;
101     }
102   }
103 
104   /**
105    * Adds a {@link gate.event.StatusListener} to the list of listeners for
106    * this processing resource
107    */
108   public synchronized void addStatusListener(StatusListener l) {
109     @SuppressWarnings("unchecked")
110     Vector<StatusListener> v = statusListeners == null new Vector<StatusListener>(2(Vector<StatusListener>)statusListeners.clone();
111     if (!v.contains(l)) {
112       v.addElement(l);
113       statusListeners = v;
114     }
115   }
116 
117   /**
118    * Notifies all the {@link gate.event.StatusListener}s of a change of status.
119    @param e the message describing the status change
120    */
121   protected void fireStatusChanged(String e) {
122     if (statusListeners != null) {
123       Vector<StatusListener> listeners = statusListeners;
124       int count = listeners.size();
125       for (int i = 0; i < count; i++) {
126         listeners.elementAt(i).statusChanged(e);
127       }
128     }
129   }
130 
131   /**
132    * Adds a {@link gate.event.ProgressListener} to the list of listeners for
133    * this processing resource.
134    */
135   public synchronized void addProgressListener(ProgressListener l) {
136     @SuppressWarnings("unchecked")
137     Vector<ProgressListener> v = progressListeners == null new Vector<ProgressListener>(2(Vector<ProgressListener>)progressListeners.clone();
138     if (!v.contains(l)) {
139       v.addElement(l);
140       progressListeners = v;
141     }
142   }
143 
144   /**
145    * Removes a {@link gate.event.ProgressListener} from the list of listeners
146    * for this processing resource.
147    */
148   public synchronized void removeProgressListener(ProgressListener l) {
149     if (progressListeners != null && progressListeners.contains(l)) {
150       @SuppressWarnings("unchecked")
151       Vector<ProgressListener> v = (Vector<ProgressListener>)progressListeners.clone();
152       v.removeElement(l);
153       progressListeners = v;
154     }
155   }
156 
157   /**
158    * Notifies all the {@link gate.event.ProgressListener}s of a progress change
159    * event.
160    @param e the new value of execution completion
161    */
162   protected void fireProgressChanged(int e) {
163     if (progressListeners != null) {
164       Vector<ProgressListener> listeners = progressListeners;
165       int count = listeners.size();
166       for (int i = 0; i < count; i++) {
167         listeners.elementAt(i).progressChanged(e);
168       }
169     }
170   }
171 
172   /**
173    * Notifies all the {@link gate.event.ProgressListener}s of a progress
174    * finished.
175    */
176   protected void fireProcessFinished() {
177     if (progressListeners != null) {
178       Vector<ProgressListener> listeners = progressListeners;
179       int count = listeners.size();
180       for (int i = 0; i < count; i++) {
181         listeners.elementAt(i).processFinished();
182       }
183     }
184   }
185   
186   /**
187    * Get the current values for all of a specified resource's
188    * registered runtime parameters.
189    */
190   public static FeatureMap getRuntimeParameterValues(Resource res)
191               throws ResourceInstantiationException {
192     ResourceData rData = Gate.getCreoleRegister().get(
193             res.getClass().getName());
194     if(rData == null)
195       throw new ResourceInstantiationException(
196               "Could not find CREOLE data for " + res.getClass().getName());
197 
198     ParameterList params = rData.getParameterList();
199 
200     return AbstractResource.getParameterValues(res,
201             params.getRuntimeParameters());
202   }
203   
204   /**
205    * Get the current values for all this resource's registered
206    * init-time parameters.
207    */
208   public FeatureMap getRuntimeParameterValues()
209               throws ResourceInstantiationException {
210     return getRuntimeParameterValues(this);
211   }
212 
213   /**
214    * A progress listener used to convert a 0..100 interval into a smaller one
215    */
216   protected class IntervalProgressListener implements ProgressListener{
217     public IntervalProgressListener(int start, int end){
218       this.start = start;
219       this.end = end;
220     }
221     @Override
222     public void progressChanged(int i){
223       fireProgressChanged(start + (end - start* i / 100);
224     }
225 
226     @Override
227     public void processFinished(){
228       fireProgressChanged(end);
229     }
230 
231     int start;
232     int end;
233   }//IntervalProgressListener
234 
235   /**
236    * A simple status listener used to forward the events upstream.
237    */
238   protected class InternalStatusListener implements StatusListener{
239     @Override
240     public void statusChanged(String message){
241       fireStatusChanged(message);
242     }
243   }//InternalStatusListener
244 
245   /**
246    * The list of {@link gate.event.StatusListener}s registered with this
247    * resource
248    */
249   private transient Vector<StatusListener> statusListeners;
250 
251   /**
252    * The list of {@link gate.event.ProgressListener}s registered with this
253    * resource
254    */
255   private transient Vector<ProgressListener> progressListeners;
256 
257   protected volatile boolean interrupted = false;
258 // class AbstractProcessingResource