| MultiPhaseTransducer.java |
1 /*
2 * MultiPhaseTransducer.java - transducer class
3 *
4 * Copyright (c) 1998-2004, The University of Sheffield.
5 *
6 * This file is part of GATE (see http://gate.ac.uk/), and is free
7 * software, licenced under the GNU Library General Public License,
8 * Version 2, June 1991 (in the distribution as file licence.html,
9 * and also available at http://gate.ac.uk/gate/licence.html).
10 *
11 * Hamish Cunningham, 24/07/98
12 *
13 * $Id: MultiPhaseTransducer.java,v 1.26 2004/07/21 17:10:08 akshay Exp $
14 */
15
16
17 package gate.jape;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21
22 import gate.AnnotationSet;
23 import gate.Document;
24 import gate.creole.ExecutionException;
25 import gate.creole.ExecutionInterruptedException;
26 import gate.creole.ontology.Ontology;
27 import gate.event.ProgressListener;
28 import gate.event.StatusListener;
29 import gate.util.Err;
30 import gate.util.Strings;
31
32
33 /**
34 * Represents a complete CPSL grammar, with a phase name, options and
35 * rule set (accessible by name and by sequence).
36 * Implements a transduce method taking a Document as input.
37 * Constructs from String or File.
38 */
39 public class MultiPhaseTransducer extends Transducer
40 implements JapeConstants, java.io.Serializable
41 {
42 /** Debug flag */
43 private static final boolean DEBUG = false;
44
45 /** Construction from name. */
46 public MultiPhaseTransducer(String name) {
47 this();
48 setName(name);
49 } // constr from name
50
51 /**
52 * Notifies this PR that it should stop its execution as soon as possible.
53 */
54 public synchronized void interrupt(){
55 interrupted = true;
56 Iterator phasesIter = phases.iterator();
57 while(phasesIter.hasNext()){
58 ((Transducer)phasesIter.next()).interrupt();
59 }
60 }
61
62
63 /** Anonymous construction */
64 public MultiPhaseTransducer() {
65 phases = new ArrayList();
66 } // anon construction
67
68 /** Set the name. */
69 public void setName(String name) { this.name = name; }
70
71 /** The SinglePhaseTransducers that make up this one.
72 * Keyed by their phase names.
73 */
74 private ArrayList phases;
75
76
77 /**
78 * Sets the ontology used by this transducer;
79 * @param ontology an {@link gate.creole.ontology.Ontology} value;
80 */
81 public void setOntology(Ontology ontology) {
82 super.setOntology(ontology);
83 Iterator phasesIter = phases.iterator();
84 while(phasesIter.hasNext()){
85 ((Transducer)phasesIter.next()).setOntology(ontology);
86 }
87 }
88
89 /** Add phase. */
90 public void addPhase(String name, Transducer phase) {
91 //Debug.pr(this, "MPT: adding " + name + Debug.getNl());
92 phases.add(phase);
93 } // addPhase
94
95 /** Change the phase order to the one specified in a list of names. */
96 public void orderPhases(String[] phaseNames) {
97 Err.println("oops: MPT.orderPhases not done yet :-(");
98 /*
99 // for each phaseName
100 // destructively get the phase and add to new array map
101 // errors: any phaseName not in phases,
102 HashMap newPhaseMap = new HashMap();
103 for(int i=0; i<phaseNames.length; i++) {
104 Transducer t = (Transducer) phases.remove(phaseNames[i]);
105 if(t == null) {
106 // ERROR
107 }
108 else {
109 newPhaseMap.add(t);
110 }
111 }
112 phases = newPhaseMap;
113 */
114 } // orderPhases
115
116
117 /** Finish: replace dynamic data structures with Java arrays; called
118 * after parsing.
119 */
120 public void finish(){
121 for(Iterator i = phases.iterator(); i.hasNext(); )
122 ((Transducer) i.next()).finish();
123 } // finish
124
125
126 /** Transduce the document by running each phase in turn. */
127 public void transduce(Document doc, AnnotationSet input,
128 AnnotationSet output) throws JapeException,
129 ExecutionException {
130
131 interrupted = false;
132 ProgressListener pListener = null;
133 StatusListener sListener = null;
134 pListener = new ProgressListener(){
135 public void processFinished(){
136 donePhases ++;
137 if(donePhases == phasesCnt) fireProcessFinished();
138 }
139
140 public void progressChanged(int i){
141 int value = (donePhases * 100 + i)/phasesCnt;
142 fireProgressChanged(value);
143 }
144
145 int phasesCnt = phases.size();
146 int donePhases = 0;
147 };
148
149 sListener = new StatusListener(){
150 public void statusChanged(String text){
151 fireStatusChanged(text);
152 }
153 };
154
155 for(Iterator i = phases.iterator(); i.hasNext(); ) {
156 Transducer t = (Transducer) i.next();
157
158 if(isInterrupted()) throw new ExecutionInterruptedException(
159 "The execution of the \"" + getName() +
160 "\" Jape transducer has been abruptly interrupted!");
161
162 try {
163 fireStatusChanged("Transducing " + doc.getName() +
164 " (Phase: " + t.getName() + ")...");
165 t.addProgressListener(pListener);
166 t.addStatusListener(sListener);
167
168 t.transduce(doc, input, output);
169 t.removeProgressListener(pListener);
170 t.removeStatusListener(sListener);
171 fireStatusChanged("");
172 } catch(JapeException e) {
173 String errorMessage = new String(
174 "Error transducing document " + doc.getName() +
175 ", phase " + t.getName() + Strings.getNl() + e.getMessage()
176 );
177 throw(new JapeException(errorMessage));
178 }
179 }
180
181 cleanUp();
182 } // transduce
183
184 public void setEnableDebugging(boolean enableDebugging) {
185 this.enableDebugging = enableDebugging;
186 //propagate
187 for(int i = 0; i < phases.size(); i++){
188 ((Transducer)phases.get(i)).setEnableDebugging(enableDebugging);
189 }
190 }
191
192
193 /** Ask each phase to clean up (delete action class files, for e.g.). */
194 public void cleanUp() {
195
196 for(Iterator i = phases.iterator(); i.hasNext(); )
197 ((Transducer) i.next()).cleanUp();
198
199 } // cleanUp
200
201 /** Create a string representation of the object. */
202 public String toString() { return toString(""); }
203
204 /** Create a string representation of the object. */
205 public String toString(String pad) {
206 String newline = Strings.getNl();
207
208 StringBuffer buf = new StringBuffer(
209 pad + "MPT: name(" + name + "); phases(" + newline + pad
210 );
211
212 for(Iterator i = phases.iterator(); i.hasNext(); )
213 buf.append(
214 ((Transducer) i.next()).toString(
215 Strings.addPadding(pad, INDENT_PADDING)
216 ) + " "
217 );
218
219 buf.append(newline + pad + ")." + newline);
220
221 return buf.toString();
222 } // toString
223
224 //needed by FSM
225 public ArrayList getPhases(){ return phases; }
226
227 } // class MultiPhaseTransducer
228
229
230
231 // $Log: MultiPhaseTransducer.java,v $
232 // Revision 1.26 2004/07/21 17:10:08 akshay
233 // Changed copyright from 1998-2001 to 1998-2004
234 //
235 // Revision 1.25 2004/03/25 13:01:13 valyt
236 // Imports optimisation throughout the Java sources
237 // (to get rid of annoying warnings in Eclipse)
238 //
239 // Revision 1.24 2003/11/14 12:45:47 valyt
240 // enableDebugging parameter
241 //
242 // Revision 1.23 2002/05/14 09:43:17 valyt
243 //
244 // Ontology Aware JAPE transducers
245 //
246 // Revision 1.22 2002/03/13 11:19:37 valyt
247 //
248 // bug fix: doc.getSourceURL() replaced by doc.getName()
249 //
250 // Revision 1.21 2002/02/26 13:27:12 valyt
251 //
252 // Error messages from the compiler
253 //
254 // Revision 1.20 2001/09/28 15:45:23 valyt
255 //
256 // All the PRs are now more or less interruptible
257 //
258 // THE STOP BUTTON shows its face when needed.
259 //
260 // Revision 1.19 2001/09/25 12:04:03 kalina
261 // I commented out temporarily the no events in batch mode code as it was
262 // not working completely correctly, so I want to reinstate it only after
263 // it's fully functional. All tests seems OK on a clean version (well, same
264 // mistakes as today due to the feature comparison stuff).
265 //
266 // Revision 1.18 2001/09/13 12:09:50 kalina
267 // Removed completely the use of jgl.objectspace.Array and such.
268 // Instead all sources now use the new Collections, typically ArrayList.
269 // I ran the tests and I ran some documents and compared with keys.
270 // JAPE seems to work well (that's where it all was). If there are problems
271 // maybe look at those new structures first.
272 //
273 // Revision 1.17 2001/09/12 15:24:44 kalina
274 // Made the batchMode flag in Main public. This is now checked before
275 // events are fired and listeners created. No bugs in tests or anywhere else
276 // yet. To disable events, set batchMode to true in your batch code. By default
277 // it is false, because some batch code e.g., MUSE, use events for progress
278 // indication. Not having events does give some small performance gains, but
279 // not much.
280 //
281 // Revision 1.16 2001/05/17 11:50:41 valyt
282 //
283 // Factory now handles Runtime parameters as well as inittime ones.
284 //
285 // There is a new rule application style Appelt-shortest
286 //
287 // Revision 1.15 2001/05/16 19:03:45 valyt
288 //
289 // Added a new option for jape in order to allow the use of the shortest match in appelt rules
290 //
291 // Revision 1.14 2001/04/30 16:56:32 valyt
292 //
293 //
294 // Unification of the NAME attribute implementation.
295 //
296 // Revision 1.13 2001/04/17 18:18:06 valyt
297 //
298 // events for jape & applications
299 //
300 // Revision 1.12 2001/03/06 20:11:14 valyt
301 //
302 // <b><em><strong>DOCUMENTATION</></></> for most of the GUI classes.
303 //
304 // Cleaned up some obsolete classes
305 //
306 // Revision 1.11 2001/01/21 20:51:31 valyt
307 // Added the DocumentEditor class and the necessary changes to the gate API
308 //
309 // Revision 1.10 2000/11/08 16:35:03 hamish
310 // formatting
311 //
312 // Revision 1.9 2000/10/26 10:45:30 oana
313 // Modified in the code style
314 //
315 // Revision 1.8 2000/10/18 13:26:47 hamish
316 // Factory.createResource now working, with a utility method that uses reflection (via java.beans.Introspector) to set properties on a resource from the
317 // parameter list fed to createResource.
318 // resources may now have both an interface and a class; they are indexed by interface type; the class is used to instantiate them
319 // moved createResource from CR to Factory
320 // removed Transients; use Factory instead
321 //
322 // Revision 1.7 2000/10/16 16:44:34 oana
323 // Changed the comment of DEBUG variable
324 //
325 // Revision 1.6 2000/10/10 15:36:36 oana
326 // Changed System.out in Out and System.err in Err;
327 // Added the DEBUG variable seted on false;
328 // Added in the header the licence;
329 //
330 // Revision 1.5 2000/07/12 14:19:19 valyt
331 // Testing CVS
332 //
333 // Revision 1.4 2000/07/04 14:37:39 valyt
334 // Added some support for Jape-ing in a different annotations et than the default one;
335 // Changed the L&F for the JapeGUI to the System default
336 //
337 // Revision 1.3 2000/07/03 21:00:59 valyt
338 // Added StatusBar and ProgressBar support for tokenisation & Jape transduction
339 // (it looks great :) )
340 //
341 // Revision 1.2 2000/04/14 18:02:46 valyt
342 // Added some gate.fsm classes
343 // added some accessor function in old jape classes
344 //
345 // Revision 1.1 2000/02/23 13:46:08 hamish
346 // added
347 //
348 // Revision 1.1.1.1 1999/02/03 16:23:02 hamish
349 // added gate2
350 //
351 // Revision 1.10 1998/11/01 21:21:39 hamish
352 // use Java arrays in transduction where possible
353 //
354 // Revision 1.9 1998/10/06 16:14:59 hamish
355 // phase ordering prob fixed; made phases an array
356 //
357 // Revision 1.8 1998/10/01 16:06:33 hamish
358 // new appelt transduction style, replacing buggy version
359 //
360 // Revision 1.7 1998/09/26 09:19:17 hamish
361 // added cloning of PE macros
362 //
363 // Revision 1.6 1998/09/18 13:35:59 hamish
364 // made Transducer a class
365 //
366 // Revision 1.5 1998/08/19 20:21:40 hamish
367 // new RHS assignment expression stuff added
368 //
369 // Revision 1.4 1998/08/12 15:39:39 hamish
370 // added padding toString methods
371 //
372 // Revision 1.3 1998/08/10 14:16:37 hamish
373 // fixed consumeblock bug and added batch.java
374 //
375 // Revision 1.2 1998/08/07 16:39:17 hamish
376 // parses, transduces. time for a break
377 //
378 // Revision 1.1 1998/08/07 16:18:45 hamish
379 // parser pretty complete, with backend link done
380