Source code: com/trapezium/factory/FactoryChain.java
1 /*
2 * @(#)FactoryChain.java
3 *
4 * Copyright (c) 1998 by Trapezium Development LLC. All Rights Reserved.
5 *
6 * The information in this file is the property of Trapezium Development LLC
7 * and may be used only in accordance with the terms of the license granted
8 * by Trapezium.
9 *
10 */
11 package com.trapezium.factory;
12
13 import java.util.Vector;
14 import com.trapezium.util.GlobalProgressIndicator;
15 import com.trapezium.util.StringUtil;
16 import com.trapezium.parse.TokenEnumerator;
17 import com.trapezium.chisel.ChiselSet;
18 import com.trapezium.util.ProgressIndicator;
19 import com.trapezium.chisel.ChiselDescriptor;
20 import com.trapezium.chisel.ChiselTable;
21 import com.trapezium.chisel.ChiselRow;
22 import com.trapezium.chisel.RowState;
23 import com.trapezium.chisel.Chisel;
24 import com.trapezium.chisel.Optimizer;
25
26 /*
27 The FactoryChain is a list of file processing factories.
28
29 Each factory in the list may be enabled or disabled.
30
31 A FactoryChain is associated with each ChiselRow of the GUI.
32 */
33 public class FactoryChain extends QueuedRequestFactory {
34 Vector chainLinks;
35 Vector chiselFactories;
36 int chiselGroup;
37
38 public void wipeout() {
39 super.wipeout();
40 int nChainLinks = chainLinks.size();
41 for ( int i = 0; i < nChainLinks; i++ ) {
42 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
43 cfi.wipeout();
44 }
45 chainLinks = null;
46 int nFactories = chiselFactories.size();
47 for ( int i = 0; i < nFactories; i++ ) {
48 ChiselFactory f = (ChiselFactory)chiselFactories.elementAt( i );
49 f.wipeout();
50 }
51 chiselFactories = null;
52 }
53
54 static int idcounter = 1;
55 int id;
56 public FactoryChain( int chiselGroup ) {
57 chainLinks = new Vector();
58 this.chiselGroup = chiselGroup;
59 id = idcounter;
60 idcounter++;
61 }
62
63 String factoryName = null;
64 public String getFactoryName() {
65 if ( factoryName == null ) {
66 return( getFixedFactoryName() );
67 } else {
68 return( factoryName );
69 }
70 }
71
72 static public String getFixedFactoryName() {
73 return( "Factory Chain" );
74 }
75
76 /** Add another factory to the list of factories */
77 public void addFactory( QueuedRequestFactory factory ) {
78 chainLinks.addElement( new ChainedFactoryInstance( factory, chainLinks.size() ));
79 }
80
81 public QueuedRequestFactory getFactoryAt( int offset ) {
82 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( offset );
83 return( cfi.getFactory() );
84 }
85
86 public void setFactoryName( String factoryName ) {
87 this.factoryName = factoryName;
88 }
89
90 public void setFactoryTitle( String factoryTitle ) {
91 // this.factoryTitle = factoryTitle;
92 }
93
94 public void disableChisel( String chiselName ) {
95 for ( int i = 0; i < chainLinks.size(); i++ ) {
96 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
97 cfi.disableChisel( chiselName );
98 }
99 }
100
101 public void removeFactory( String factoryName ) {
102 for ( int i = 0; i < chainLinks.size(); i++ ) {
103 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
104 QueuedRequestFactory f = cfi.getFactory();
105 if ( f.getFactoryName().compareTo( factoryName ) == 0 ) {
106 chainLinks.removeElementAt( i );
107 return;
108 }
109 }
110 }
111
112 public void enableChisel( String chiselName, FactoryResponseListener theListener ) {
113 for ( int i = 0; i < chainLinks.size(); i++ ) {
114 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
115 cfi.enableChisel( chiselName, theListener );
116 }
117 }
118
119 public void insertFactory( QueuedRequestFactory factory, QueuedRequestFactory prev ) {
120 if ( prev != null ) {
121 for ( int i = 0; i < chainLinks.size(); i++ ) {
122 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
123 if ( cfi.getQueuedRequestFactory() == prev ) {
124 if ( i == ( chainLinks.size() - 1 )) {
125 addFactory( factory );
126 } else {
127 chainLinks.insertElementAt( new ChainedFactoryInstance( factory, i + 1 ), i + 1 );
128 }
129 return;
130 }
131 }
132 }
133
134 // didn't find prev or prev is null
135 addFactory( factory );
136 }
137
138
139 /** Start the factory chain, make this object the listener for the chained factory
140 * entries, the original listener is saved in "listener".
141 */
142 public void submit( FactoryData factoryData ) {
143 if ( chainLinks.size() > 0 ) {
144 factoryData.setError( null );
145 factoryData.pushFactoryInfo();
146 runFactory( 0, factoryData );
147 }
148 }
149
150 public int getNumberChainLinks() {
151 return( chainLinks.size() );
152 }
153
154 /** Called when a Factory has finished running, move on to the next Factory */
155 public void done( FactoryData fd ) {
156 int nextFactoryNumber = fd.getFactoryNumber() + 1;
157 // System.out.println( "chain " + id + ", factory " + fd.getFactoryNumber() + " done, chainLinks.size() is " + chainLinks.size() );
158 // System.out.println( "fd.getError() is " + fd.getError() );
159 // System.out.println( "GlobalProgressIndicator.abortCurrentProcess " + GlobalProgressIndicator.abortCurrentProcess );
160 // System.out.println( "nextFactoryNumber " + nextFactoryNumber + ", chainLinks.size() " + chainLinks.size() );
161 if (( fd.getError() == null ) && !fd.errorsCreated() &&
162 !GlobalProgressIndicator.abortCurrentProcess &&
163 (( nextFactoryNumber > 0 ) && ( nextFactoryNumber < chainLinks.size() ))) {
164 fd.setFactoryChain( this );
165 if ( nextFactoryNumber == ( chainLinks.size() - 1 )) {
166 fd.setNodeVerifyChecksEnabled( true );
167 fd.setUsageChecksEnabled( false );
168 } else {
169 fd.setNodeVerifyChecksEnabled( false );
170 fd.setUsageChecksEnabled( false );
171 // here we do additional checks only if the chain after this next one requires it
172 QueuedRequestFactory nextFactory = getFactoryAt( nextFactoryNumber + 1 );
173 if ( nextFactory instanceof ChiselFactory ) {
174 String chiselName = ((ChiselFactory)nextFactory).getChiselName();
175 // At the moment, only the IFS_CoordRemover chisel needs
176 // usage info
177 if ( chiselName != null ) {
178 // System.out.println( "ChiselName is '" + chiselName + "'" );
179 if ( chiselName.indexOf( "IFS_CoordRemover" ) > 0 ) {
180 fd.setUsageChecksEnabled( true );
181 }
182 }
183 }
184 }
185 runFactory( nextFactoryNumber, fd );
186 } else {
187 // System.out.println( "chain " + id + " is totally done!" );
188 fd.popFactoryInfo();
189 if ( listener != null ) {
190 listener.done( fd );
191 }
192 }
193 }
194
195 /** Run a factory in the list */
196 void runFactory( int n, FactoryData factoryData ) {
197 // System.out.println( "Starting factory " + (n+1) + " of " + chainLinks.size() );
198 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( n );
199 if ( !cfi.isEnabled() ) {
200 // System.out.println( "..doing nothing, factory not enabled" );
201 factoryData.setFactoryNumber( n );
202 done( factoryData );
203 } else {
204 QueuedRequestFactory qrf = cfi.getQueuedRequestFactory();
205 // System.out.println( ".." + qrf.getClass().getName() );
206 qrf.setListener( this ); // was addListener
207 ProgressIndicator pl = ChiselSet.getProgressIndicator( chiselGroup );
208 if ( pl != null ) {
209 if ( pl instanceof ChiselTable ) {
210 ChiselTable ct = (ChiselTable)pl;
211 Object cr = ct.getRow( 0 );
212 if ( cr instanceof FactoryResponseListener ) {
213 FactoryResponseListener frl = (FactoryResponseListener)cr;
214 qrf.addListener( frl );
215 }
216 }
217 }
218 factoryData.setFactoryNumber( n );
219 factoryData.setChainDone( false );
220 qrf.submit( factoryData );
221 }
222 }
223
224 public void handleRequest( FactoryData factoryData ) {
225 }
226
227 public void dump() {
228 System.out.println( "Dumping factory chain " + id );
229 dump( 1 );
230 System.out.println( "Dump complete" );
231 }
232
233 void dump( int indentLevel ) {
234 String space = StringUtil.spacer( indentLevel );
235 System.out.println( space + "chain " + id );
236
237 for ( int i = 0; i < chainLinks.size(); i++ ) {
238 ChainedFactoryInstance cfi = (ChainedFactoryInstance)chainLinks.elementAt( i );
239 QueuedRequestFactory qrf = cfi.getQueuedRequestFactory();
240 System.out.println( space + i + ": " + qrf.getClass().getName() + " enabled " + cfi.isEnabled() );
241 if ( qrf instanceof FactoryChain ) {
242 FactoryChain fc = (FactoryChain)qrf;
243 fc.dump( indentLevel+1);
244 } else if ( qrf instanceof ChiselFactory ) {
245 ChiselFactory cf = (ChiselFactory)qrf;
246 cf.dump( indentLevel+1 );
247 }
248 }
249 }
250
251
252 /** Add a chisel to the list of chisels.
253 *
254 * @param chiselName the class name of the chisel to add
255 * @param chiselType category of chisel, to prevent chisels form interfering with each other
256 * @param parser for validating the file
257 * @param baseFilePath path to file, needed for some chisels
258 * @param nameWithoutPath file name without path, needed for some chisels
259 */
260 public void addChisel( String chiselName, int chiselType, QueuedRequestFactory parser, String baseFilePath, String nameWithoutPath, RowState rowState ) {
261 if ( chiselFactories == null ) {
262 chiselFactories = new Vector();
263 addChiselFactory( chiselName, chiselType, baseFilePath, nameWithoutPath, rowState );
264 } else {
265 // add the chisel to the first compatible chisel factory
266 for ( int i = 0; i < chiselFactories.size(); i++ ) {
267 ChiselFactory testFactory = (ChiselFactory)chiselFactories.elementAt( i );
268 if ( testFactory.isCompatible( chiselType )) {
269 testFactory.addChisel( chiselName );
270 return;
271 }
272 }
273
274 // didn't find a compatible factory
275 addFactory( parser );
276 addChiselFactory( chiselName, chiselType, baseFilePath, nameWithoutPath, rowState );
277 }
278 }
279
280
281 void setFactoryTitles() {
282 int numberFactories = chiselFactories.size();
283 if ( numberFactories > 1 ) {
284 for ( int i = 0; i < numberFactories; i++ ) {
285 ChiselFactory f = (ChiselFactory)chiselFactories.elementAt( i );
286 f.setFactoryTitle( "Phase " + (i+1) + " of " + numberFactories + "... " );
287 }
288 }
289 }
290
291 /** Add an optimizer to the factory chain.
292 *
293 * @param theOptimizer the Optimizer to add
294 * @param parser parsing required after optimization to check syntax
295 * @param baseFilePath path to file
296 * @param nameWithoutPath needed by some optimizers
297 */
298 public void addOptimizer( Optimizer theOptimizer, QueuedRequestFactory parser, String baseFilePath, String nameWithoutPath ) {
299 if ( chiselFactories == null ) {
300 chiselFactories = new Vector();
301 addChiselFactory( theOptimizer, baseFilePath, nameWithoutPath );
302 } else {
303 // didn't find a compatible factory
304 addFactory( parser );
305 addChiselFactory( theOptimizer, baseFilePath, nameWithoutPath );
306 }
307 }
308
309 /** Add a factory to the list of factories */
310 public void addChiselFactory( String chiselName, int chiselType, String baseFilePath, String nameWithoutPath, RowState rowState ) {
311 System.out.println( "addChiselFactory '" + chiselName + "'" );
312 ChiselFactory chiselFactory = new ChiselFactory( chiselType, ChiselSet.getProgressIndicator( chiselGroup ), rowState );
313 addFactory( chiselFactory, chiselName, baseFilePath, nameWithoutPath );
314 }
315
316 void addChiselFactory( Optimizer theOptimizer, String baseFilePath, String nameWithoutPath ) {
317 ChiselFactory chiselFactory = new ChiselFactory( ChiselDescriptor.NOTYPE_CHISEL, ChiselSet.getProgressIndicator( chiselGroup ), null );
318 addFactory( chiselFactory, theOptimizer, baseFilePath, nameWithoutPath );
319 }
320
321 void addFactory( ChiselFactory chiselFactory, Object chiselName, String baseFilePath, String nameWithoutPath ) {
322 addFactory( chiselFactory );
323 chiselFactories.addElement( chiselFactory );
324 chiselFactory.setListener( getListener() );
325 if ( chiselName instanceof String ) {
326 chiselFactory.addChisel( (String)chiselName );
327 } else if ( chiselName instanceof Optimizer ) {
328 chiselFactory.addOptimizer( (Optimizer)chiselName );
329 }
330 chiselFactory.setBaseFilePath( baseFilePath );
331 chiselFactory.setBaseFileName( nameWithoutPath );
332 setFactoryTitles();
333 }
334 }