1   /*
2    *  Copyright (c) 1998-2005, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 11 Apr 2002
10   *
11   *  $Id: ConditionalSerialController.java,v 1.6 2005/01/11 13:51:31 ian Exp $
12   */
13  
14  package gate.creole;
15  
16  import java.util.*;
17  
18  import gate.*;
19  import gate.event.ControllerEvent;
20  import gate.util.Err;
21  
22  /**
23   * Execute a list of PRs serially. For each PR a running strategy is stored
24   * which decides whether the PR will be run always, never or upon a condition
25   * being satisfied.
26   * This controller uses {@link AnalyserRunningStrategy} objects as running
27   * strategies and they only work with {@link LanguageAnalyser}s so the PRs that
28   * are not analysers will get a default "run always" strategy.
29   */
30  public class ConditionalSerialController extends SerialController
31                                           implements ConditionalController{
32  
33    public ConditionalSerialController(){
34      strategiesList = new ArrayList();
35    }
36  
37    public Collection getRunningStrategies(){
38      return Collections.unmodifiableList(strategiesList);
39    }
40  
41    /**
42     * Set a PR at a specified location.
43     * The running strategy defaults to run always.
44     * @param index the position for the PR
45     * @param pr the PR to be set.
46     */
47    public void add(int index, ProcessingResource pr){
48      if(pr instanceof LanguageAnalyser){
49        strategiesList.add(index,
50                           new AnalyserRunningStrategy((LanguageAnalyser)pr,
51                                                        RunningStrategy.RUN_ALWAYS,
52                                                        null, null));
53      }else{
54        strategiesList.add(index, new RunningStrategy.RunAlwaysStrategy(pr));
55      }
56      super.add(index, pr);
57    }
58  
59    /**
60     * Add a PR to the end of the execution list.
61     * @param pr the PR to be added.
62     */
63    public void add(ProcessingResource pr){
64      if(pr instanceof LanguageAnalyser){
65        strategiesList.add(new AnalyserRunningStrategy((LanguageAnalyser)pr,
66                                                        RunningStrategy.RUN_ALWAYS,
67                                                        null, null));
68      }else{
69        strategiesList.add(new RunningStrategy.RunAlwaysStrategy(pr));
70      }
71      super.add(pr);
72    }
73  
74    public ProcessingResource remove(int index){
75      ProcessingResource aPr = super.remove (index);
76      strategiesList.remove(index);
77      fireResourceRemoved(new ControllerEvent(this, 
78              ControllerEvent.RESOURCE_REMOVED, aPr));
79      return aPr;
80    }
81  
82    public boolean remove(ProcessingResource pr){
83      int index = prList.indexOf(pr);
84      if(index != -1){
85        prList.remove(index);
86        strategiesList.remove(index);
87        fireResourceRemoved(new ControllerEvent(this, 
88                ControllerEvent.RESOURCE_REMOVED, pr));
89        return true;
90      }
91      return false;
92    }
93  
94    public void setRunningStrategy(int index, AnalyserRunningStrategy strategy){
95      strategiesList.set(index, strategy);
96    }
97  
98    /**
99     * Populates this controller with the appropiate running strategies from a
100    * collection of running strategies
101    * (optional operation).
102    *
103    * Controllers that are serializable must implement this method needed by GATE
104    * to restore their contents.
105    * @throws UnsupportedOperationException if the <tt>setPRs</tt> method
106    *         is not supported by this controller.
107    */
108   public void setRunningStrategies(Collection strategies){
109     strategiesList.clear();
110     Iterator stratIter = strategies.iterator();
111     while(stratIter.hasNext()) strategiesList.add(stratIter.next());
112   }
113 
114   /**
115    * Executes a {@link ProcessingResource}.
116    */
117   protected void runComponent(int componentIndex) throws ExecutionException{
118     ProcessingResource currentPR = (ProcessingResource)
119                                    prList.get(componentIndex);
120 
121     //create the listeners
122     FeatureMap listeners = Factory.newFeatureMap();
123     listeners.put("gate.event.StatusListener", sListener);
124     int componentProgress = 100 / prList.size();
125     listeners.put("gate.event.ProgressListener",
126                   new IntervalProgressListener(
127                           componentIndex * componentProgress,
128                           (componentIndex +1) * componentProgress)
129                   );
130 
131     //add the listeners
132     try{
133       AbstractResource.setResourceListeners(currentPR, listeners);
134     }catch(Exception e){
135       // the listeners setting failed; nothing important
136       Err.prln("Could not set listeners for " + currentPR.getClass().getName() +
137                "\n" + e.toString() + "\n...nothing to lose any sleep over.");
138     }
139 
140 
141     //run the thing
142     if(((RunningStrategy)strategiesList.get(componentIndex)).shouldRun()){
143       currentPR.execute();
144     }
145 
146 
147     //remove the listeners
148     try{
149       AbstractResource.removeResourceListeners(currentPR, listeners);
150     }catch(Exception e){
151       // the listeners removing failed; nothing important
152       Err.prln("Could not clear listeners for " +
153                currentPR.getClass().getName() +
154                "\n" + e.toString() + "\n...nothing to lose any sleep over.");
155     }
156   }//protected void runComponent(int componentIndex)
157 
158   /**
159    * Cleans the internal data and prepares this object to be collected
160    */
161   public void cleanup(){
162     super.cleanup();
163     strategiesList.clear();
164   }
165 
166 
167   /**
168    * The list of running strategies for the member PRs.
169    */
170   protected List strategiesList;
171 } // class SerialController
172