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