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 componentIndex) throws 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
|