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 08/10/2001
10   *
11   *  $Id: SerialAnalyserController.java,v 1.19 2006/04/06 13:02:29 valyt Exp $
12   *
13   */
14  
15  package gate.creole;
16  
17  import java.util.*;
18  
19  import gate.*;
20  import gate.event.CreoleEvent;
21  import gate.util.*;
22  
23  /**
24   * This class implements a SerialController that only contains
25   * {@link gate.LanguageAnalyser}s.
26   * It has a {@link gate.Corpus} and its execute method runs all the analysers in
27   * turn over each of the documents in the corpus.
28   */
29  public class SerialAnalyserController extends SerialController
30                implements CorpusController{
31  
32    /** Debug flag */
33    private static final boolean DEBUG = false;
34  
35    public gate.Corpus getCorpus() {
36      return corpus;
37    }
38  
39    public void setCorpus(gate.Corpus corpus) {
40      this.corpus = corpus;
41    }
42  
43    /** Run the Processing Resources in sequence. */
44    public void execute() throws ExecutionException{
45      interrupted = false;
46      if(corpus == null) throw new ExecutionException(
47        "(SerialAnalyserController) \"" + getName() + "\":\n" +
48        "The corpus supplied for execution was null!");
49      //iterate through the documents in the corpus
50      for(int i = 0; i < corpus.size(); i++){
51        if(isInterrupted()) throw new ExecutionInterruptedException(
52          "The execution of the " + getName() +
53          " application has been abruptly interrupted!");
54  
55        boolean docWasLoaded = corpus.isDocumentLoaded(i);
56        Document doc = (Document)corpus.get(i);
57        //run the system over this document
58        //set the doc and corpus
59        for(int j = 0; j < prList.size(); j++){
60          ((LanguageAnalyser)prList.get(j)).setDocument(doc);
61          ((LanguageAnalyser)prList.get(j)).setCorpus(corpus);
62        }
63  
64  //      try{
65        if (DEBUG) 
66          Out.pr("SerialAnalyserController processing doc=" + doc.getName()+ "...");      
67        super.execute();
68        if (DEBUG) 
69          Out.prln("done.");      
70  //      }catch(Exception e){
71  //        e.printStackTrace(Err.getPrintWriter());
72  //      }
73  
74        //unset the doc and corpus
75        for(int j = 0; j < prList.size(); j++){
76          ((LanguageAnalyser)prList.get(j)).setDocument(null);
77          ((LanguageAnalyser)prList.get(j)).setCorpus(null);
78        }
79  
80        if(!docWasLoaded){
81          //trigger saving
82          corpus.unloadDocument(doc);
83          //close the previoulsy unloaded Doc
84          Factory.deleteResource(doc);
85        }
86      }
87    }
88  
89    /**
90     * Overidden from {@link SerialController} to only allow
91     * {@link LanguageAnalyser}s as components.
92     */
93    public void add(ProcessingResource pr){
94      if(pr instanceof LanguageAnalyser){
95        super.add(pr);
96      }else{
97        throw new GateRuntimeException(getClass().getName() +
98                                       "only accepts " +
99                                       LanguageAnalyser.class.getName() +
100                                      "s as components\n" +
101                                      pr.getClass().getName() +
102                                      " is not!");
103     }
104   }
105   /**
106    * Sets the current document to the memeber PRs
107    */
108   protected void setDocToPrs(Document doc){
109     Iterator prIter = getPRs().iterator();
110     while(prIter.hasNext()){
111       ((LanguageAnalyser)prIter.next()).setDocument(doc);
112     }
113   }
114 
115 
116   /**
117    * Checks whether all the contained PRs have all the required runtime
118    * parameters set. Ignores the corpus and document parameters as these will
119    * be set at run time.
120    *
121    * @return a {@link List} of {@link ProcessingResource}s that have required
122    * parameters with null values if they exist <tt>null</tt> otherwise.
123    * @throws {@link ResourceInstantiationException} if problems occur while
124    * inspecting the parameters for one of the resources. These will normally be
125    * introspection problems and are usually caused by the lack of a parameter
126    * or of the read accessor for a parameter.
127    */
128   public List getOffendingPocessingResources()
129          throws ResourceInstantiationException{
130     //take all the contained PRs
131     ArrayList badPRs = new ArrayList(getPRs());
132     //remove the ones that no parameters problems
133     Iterator prIter = getPRs().iterator();
134     while(prIter.hasNext()){
135       ProcessingResource pr = (ProcessingResource)prIter.next();
136       ResourceData rData = (ResourceData)Gate.getCreoleRegister().
137                                               get(pr.getClass().getName());
138       //this is a list of lists
139       List parameters = rData.getParameterList().getRuntimeParameters();
140       //remove corpus and document
141       List newParameters = new ArrayList();
142       Iterator pDisjIter = parameters.iterator();
143       while(pDisjIter.hasNext()){
144         List aDisjunction = (List)pDisjIter.next();
145         List newDisjunction = new ArrayList(aDisjunction);
146         Iterator internalParIter = newDisjunction.iterator();
147         while(internalParIter.hasNext()){
148           Parameter parameter = (Parameter)internalParIter.next();
149           if(parameter.getName().equals("corpus") ||
150              parameter.getName().equals("document")) internalParIter.remove();
151         }
152         if(!newDisjunction.isEmpty()) newParameters.add(newDisjunction);
153       }
154 
155       if(AbstractResource.checkParameterValues(pr, newParameters)){
156         badPRs.remove(pr);
157       }
158     }
159     return badPRs.isEmpty() ? null : badPRs;
160   }
161 
162 
163   private gate.Corpus corpus;
164 
165   /**
166    * Overridden to also clean up the corpus value.
167    */
168   public void resourceUnloaded(CreoleEvent e) {
169     super.resourceUnloaded(e);    
170     if(e.getResource() == corpus){
171       setCorpus(null);
172     }
173   }
174 }