1   /*
2    *  SerialController.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, 9/Nov/2000
12   *
13   *  $Id: SerialController.java,v 1.19 2002/08/22 14:45:39 nasso Exp $
14   */
15  
16  package gate.creole;
17  
18  import java.util.*;
19  import java.io.*;
20  
21  import gate.*;
22  import gate.util.*;
23  import gate.creole.*;
24  import gate.event.*;
25  
26  /** Execute a list of PRs serially.
27    */
28  public class SerialController extends AbstractController
29                                implements CreoleListener{
30  
31    public SerialController(){
32      prList = Collections.synchronizedList(new ArrayList());
33      sListener = new InternalStatusListener();
34    }
35  
36    /**
37     * Returns all the {@link gate.ProcessingResource}s contained by this
38     * controller as an unmodifiable list.
39     */
40    public Collection getPRs(){
41      return Collections.unmodifiableList(prList);
42    }
43  
44    /**
45     * Populates this controller from a collection of {@link ProcessingResource}s
46     * (optional operation).
47     *
48     * Controllers that are serializable must implement this method needed by GATE
49     * to restore the contents of the controllers.
50     * @throws UnsupportedOperationException if the <tt>setPRs</tt> method
51     *         is not supported by this controller.
52     */
53    public void setPRs(Collection prs){
54      prList.clear();
55      Iterator prIter = prs.iterator();
56      while(prIter.hasNext()) prList.add(prIter.next());
57    }
58  
59    public void add(int index, ProcessingResource pr){
60      prList.add(index, pr);
61    }
62  
63    public void add(ProcessingResource pr){
64      prList.add(pr);
65    }
66  
67    public ProcessingResource remove(int index){
68      return (ProcessingResource)prList.remove(index);
69    }
70  
71    public boolean remove(ProcessingResource pr){
72      return prList.remove(pr);
73    }
74  
75    public ProcessingResource set(int index, ProcessingResource pr){
76      return (ProcessingResource)prList.set(index, pr);
77    }
78  
79    /**
80     * Verifies that all PRs have all their required rutime parameters set.
81     */
82    protected void checkParameters() throws ExecutionException{
83      List badPRs;
84      try{
85        badPRs = getOffendingPocessingResources();
86      }catch(ResourceInstantiationException rie){
87        throw new ExecutionException(
88          "Could not check runtime parameters for the processing resources:\n" +
89          rie.toString());
90      }
91      if(badPRs != null && !badPRs.isEmpty()){
92        throw new ExecutionException(
93          "Some of the processing resources in this controller have unset " +
94          "runtime parameters:\n" +
95          badPRs.toString());
96      }
97    }
98  
99  
100   /** Run the Processing Resources in sequence. */
101   public void execute() throws ExecutionException{
102     //check all the PRs have the right parameters
103     checkParameters();
104 
105     //execute all PRs in sequence
106     interrupted = false;
107     for (int i = 0; i < prList.size(); i++){
108       if(isInterrupted()) throw new ExecutionInterruptedException(
109         "The execution of the " + getName() +
110         " application has been abruptly interrupted!");
111       runComponent(i);
112     }
113   } // execute()
114 
115 
116   /**
117    * Executes a {@link ProcessingResource}.
118    */
119   protected void runComponent(int componentIndex) throws ExecutionException{
120     ProcessingResource currentPR = (ProcessingResource)
121                                    prList.get(componentIndex);
122 
123     //create the listeners
124     FeatureMap listeners = Factory.newFeatureMap();
125     listeners.put("gate.event.StatusListener", sListener);
126     int componentProgress = 100 / prList.size();
127     listeners.put("gate.event.ProgressListener",
128                   new IntervalProgressListener(
129                           componentIndex * componentProgress,
130                           (componentIndex +1) * componentProgress)
131                   );
132 
133     //add the listeners
134     try{
135       AbstractResource.setResourceListeners(currentPR, listeners);
136     }catch(Exception e){
137       // the listeners setting failed; nothing important
138       Err.prln("Could not set listeners for " + currentPR.getClass().getName() +
139                "\n" + e.toString() + "\n...nothing to lose any sleep over.");
140     }
141 
142     //start DB transactions
143 
144     //run the thing
145     currentPR.execute();
146 
147     //commit DB transactions
148 
149 
150     //remove the listeners
151     try{
152       AbstractResource.removeResourceListeners(currentPR, listeners);
153     }catch(Exception e){
154       // the listeners removing failed; nothing important
155       Err.prln("Could not clear listeners for " +
156                currentPR.getClass().getName() +
157                "\n" + e.toString() + "\n...nothing to lose any sleep over.");
158     }
159   }//protected void runComponent(int componentIndex)
160 
161   /**
162    * Cleans the internal data and prepares this object to be collected
163    */
164   public void cleanup(){
165     // Diana desire to remove PR-s
166     Resource res;
167     for(int i=0; i<prList.size(); ++i) {
168       res = (Resource) prList.get(i);
169       Factory.deleteResource(res);
170     } // for
171     prList.clear();
172   }
173 
174   /** The list of contained PRs*/
175   protected List prList;
176 
177   /** A proxy for status events*/
178   protected StatusListener sListener;
179   public void resourceLoaded(CreoleEvent e) {
180   }
181   public void resourceUnloaded(CreoleEvent e) {
182     //remove all occurences of the resource from this controller
183     if(e.getResource() instanceof ProcessingResource)
184       while(prList.remove(e.getResource()));
185   }
186 
187   public void resourceRenamed(Resource resource, String oldName,
188                               String newName){
189   }
190 
191   public void datastoreOpened(CreoleEvent e) {
192   }
193   public void datastoreCreated(CreoleEvent e) {
194   }
195   public void datastoreClosed(CreoleEvent e) {
196   }
197 
198 } // class SerialController
199