ConditionalSerialController.java
001 /*
002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Valentin Tablan 11 Apr 2002
011  *
012  *  $Id: ConditionalSerialController.java 13179 2010-11-01 13:02:38Z ian_roberts $
013  */
014 
015 package gate.creole;
016 
017 import java.util.*;
018 
019 import gate.*;
020 import gate.creole.RunningStrategy.UnconditionalRunningStrategy;
021 import gate.creole.metadata.CreoleResource;
022 import gate.event.ControllerEvent;
023 import gate.util.Benchmark;
024 import gate.util.Err;
025 
026 /**
027  * Execute a list of PRs serially. For each PR a running strategy is stored
028  * which decides whether the PR will be run always, never or upon a condition
029  * being satisfied.
030  * This controller uses {@link AnalyserRunningStrategy} objects as running
031  * strategies and they only work with {@link LanguageAnalyser}s so the PRs that
032  * are not analysers will get a default "run always" strategy.
033  */
034 @CreoleResource(name = "Conditional Pipeline",
035     comment = "A simple serial controller for conditionally run PRs.",
036     helpURL = "http://gate.ac.uk/userguide/sec:developer:cond")
037 public class ConditionalSerialController extends SerialController
038                                          implements ConditionalController{
039 
040   public ConditionalSerialController(){
041     strategiesList = new ArrayList();
042   }
043 
044   public Collection getRunningStrategies(){
045     return Collections.unmodifiableList(strategiesList);
046   }
047 
048   /**
049    * Set a PR at a specified location.
050    * The running strategy defaults to run always.
051    @param index the position for the PR
052    @param pr the PR to be set.
053    */
054   public void add(int index, ProcessingResource pr){
055     if(pr instanceof LanguageAnalyser){
056       strategiesList.add(index,
057                          new AnalyserRunningStrategy((LanguageAnalyser)pr,
058                                                       RunningStrategy.RUN_ALWAYS,
059                                                       null, null));
060     }else{
061       strategiesList.add(index, new RunningStrategy.UnconditionalRunningStrategy(pr, true));
062     }
063     super.add(index, pr);
064   }
065 
066   /**
067    * Add a PR to the end of the execution list.
068    @param pr the PR to be added.
069    */
070   public void add(ProcessingResource pr){
071     if(pr instanceof LanguageAnalyser){
072       strategiesList.add(new AnalyserRunningStrategy((LanguageAnalyser)pr,
073                                                       RunningStrategy.RUN_ALWAYS,
074                                                       null, null));
075     }else{
076       strategiesList.add(new RunningStrategy.UnconditionalRunningStrategy(pr, true));
077     }
078     super.add(pr);
079   }
080 
081   public ProcessingResource remove(int index){
082     ProcessingResource aPr = super.remove (index);
083     strategiesList.remove(index);
084     fireResourceRemoved(new ControllerEvent(this, 
085             ControllerEvent.RESOURCE_REMOVED, aPr));
086     return aPr;
087   }
088 
089   public boolean remove(ProcessingResource pr){
090     int index = prList.indexOf(pr);
091     if(index != -1){
092       prList.remove(index);
093       strategiesList.remove(index);
094       fireResourceRemoved(new ControllerEvent(this, 
095               ControllerEvent.RESOURCE_REMOVED, pr));
096       return true;
097     }
098     return false;
099   }
100 
101   public void setRunningStrategy(int index, AnalyserRunningStrategy strategy){
102     strategiesList.set(index, strategy);
103   }
104 
105   /**
106    * Populates this controller with the appropiate running strategies from a
107    * collection of running strategies
108    * (optional operation).
109    *
110    * Controllers that are serializable must implement this method needed by GATE
111    * to restore their contents.
112    @throws UnsupportedOperationException if the <tt>setPRs</tt> method
113    *          is not supported by this controller.
114    */
115   public void setRunningStrategies(Collection strategies){
116     strategiesList.clear();
117     Iterator stratIter = strategies.iterator();
118     while(stratIter.hasNext()) strategiesList.add(stratIter.next());
119   }
120 
121   /**
122    * Executes a {@link ProcessingResource}.
123    */
124   protected void runComponent(int componentIndexthrows ExecutionException{
125     ProcessingResource currentPR = (ProcessingResource)
126                                    prList.get(componentIndex);
127 
128     //create the listeners
129     FeatureMap listeners = Factory.newFeatureMap();
130     listeners.put("gate.event.StatusListener", sListener);
131     int componentProgress = 100 / prList.size();
132     listeners.put("gate.event.ProgressListener",
133                   new IntervalProgressListener(
134                           componentIndex * componentProgress,
135                           (componentIndex +1* componentProgress)
136                   );
137 
138     //add the listeners
139     try{
140       AbstractResource.setResourceListeners(currentPR, listeners);
141     }catch(Exception e){
142       // the listeners setting failed; nothing important
143       Err.prln("Could not set listeners for " + currentPR.getClass().getName() +
144                "\n" + e.toString() "\n...nothing to lose any sleep over.");
145     }
146 
147 
148     //run the thing
149     if(((RunningStrategy)strategiesList.get(componentIndex)).shouldRun()){
150       benchmarkFeatures.put(Benchmark.PR_NAME_FEATURE, currentPR.getName());
151 
152       long startTime = System.currentTimeMillis();
153       // run the thing
154       Benchmark.executeWithBenchmarking(currentPR,
155               Benchmark.createBenchmarkId(Benchmark.PR_PREFIX + currentPR.getName(),
156                       getBenchmarkId()), this, benchmarkFeatures);
157 
158       benchmarkFeatures.remove(Benchmark.PR_NAME_FEATURE);
159     }
160 
161 
162     //remove the listeners
163     try{
164       AbstractResource.removeResourceListeners(currentPR, listeners);
165     }catch(Exception e){
166       // the listeners removing failed; nothing important
167       Err.prln("Could not clear listeners for " +
168                currentPR.getClass().getName() +
169                "\n" + e.toString() "\n...nothing to lose any sleep over.");
170     }
171   }//protected void runComponent(int componentIndex)
172 
173   /**
174    * Cleans the internal data and prepares this object to be collected
175    */
176   public void cleanup(){
177     super.cleanup();
178     strategiesList.clear();
179   }
180 
181   /**
182    * Custom duplication method for conditional controllers to handle
183    * duplicating the running strategies.
184    */
185   public Resource duplicate(Factory.DuplicationContext ctx)
186           throws ResourceInstantiationException {
187     ConditionalController c = (ConditionalController)super.duplicate(ctx);
188     Collection<ProcessingResource> newPRs = c.getPRs();
189     List<RunningStrategy> newStrategies = new ArrayList<RunningStrategy>(
190             strategiesList.size());
191     Iterator<RunningStrategy> oldRSIt = getRunningStrategies().iterator();
192     Iterator<ProcessingResource> prIt = newPRs.iterator();
193     while(oldRSIt.hasNext()) {
194       RunningStrategy oldStrat = oldRSIt.next();
195       ProcessingResource currentPR = prIt.next();
196       if(oldStrat instanceof AnalyserRunningStrategy) {
197         newStrategies.add(new AnalyserRunningStrategy(
198                 (LanguageAnalyser)currentPR,
199                 ((AnalyserRunningStrategy)oldStrat).getRunMode(),
200                 ((AnalyserRunningStrategy)oldStrat).getFeatureName(),
201                 ((AnalyserRunningStrategy)oldStrat).getFeatureValue()));
202       }
203       else {
204         boolean run = true;
205         if(oldStrat instanceof UnconditionalRunningStrategy) {
206           run = oldStrat.shouldRun();
207         }
208         // assume an unconditional strategy.  Subclasses that know about other types
209         // of strategies can fix this up later
210         newStrategies.add(new RunningStrategy.UnconditionalRunningStrategy(currentPR, run));
211       }
212     }
213     c.setRunningStrategies(newStrategies);
214     
215     return c;
216   }
217 
218   /**
219    * The list of running strategies for the member PRs.
220    */
221   protected List strategiesList;
222 // class SerialController