Source code: com/trapezium/chisel/ChiselEngine.java
1 /*
2 * @(#)ChiselEngine.java
3 *
4 * Copyright (c) 1998-2000 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.chisel;
12
13 import com.trapezium.vrml.Scene;
14 import com.trapezium.edit.TokenEditor;
15 import com.trapezium.parse.TokenEnumerator;
16 import com.trapezium.factory.FactoryResponseAdapter;
17 import com.trapezium.factory.FactoryData;
18 import java.util.Vector;
19 import java.io.File;
20
21 /** Main class for command line version of Chisel.
22 *
23 * @author Johannes N. Johannsen
24 * @version 1.0, 4 Dec 1998
25 *
26 * @since 1.0
27 */
28
29 public class ChiselEngine extends Thread {
30
31 /** files being viewed or processed */
32 Vector filesToProcess;
33 ChiselSet[] sets;
34 ChiselCommandList chiselCommandList;
35 EngineRunner theDriver;
36 boolean doGzip;
37 boolean preserveNames;
38 String outputDir;
39 boolean stripComments;
40 boolean reformat;
41
42 /** Class constructor */
43 public ChiselEngine( Vector filesToProcess, ChiselCommandList chiselCommandList, boolean doGzip, String outputDir, boolean preserveNames, boolean stripComments, boolean reformat ) {
44 this.filesToProcess = filesToProcess;
45 this.chiselCommandList = chiselCommandList;
46 this.doGzip = doGzip;
47 this.outputDir = outputDir;
48 this.preserveNames = preserveNames;
49 this.stripComments = stripComments;
50 this.reformat = reformat;
51 fixOutputDir();
52 sets = ChiselSet.createChiselSets();
53 theDriver = new EngineRunner( this );
54 }
55
56 /** if outputDir exists, make sure it ends with a '/' */
57 void fixOutputDir() {
58 if ( outputDir != null ) {
59 int slashIndex = outputDir.lastIndexOf( '/' );
60 if ( slashIndex == -1 ) {
61 slashIndex = outputDir.lastIndexOf( '\\' );
62 }
63 if ( slashIndex != ( outputDir.length() - 1 )) {
64 slashIndex = -1;
65 }
66 if ( slashIndex == -1 ) {
67 outputDir = outputDir + "/";
68 }
69 }
70 }
71
72
73 /** Strip out all comments and/or reformat */
74 void stripAndReformat( ProcessedFile p ) {
75 Scene scene = p.getScene();
76 TokenEnumerator sceneTokens = scene.getTokenEnumerator();
77 TokenEditor dataSource = new TokenEditor( sceneTokens );
78 if ( sceneTokens instanceof TokenEditor ) {
79 TokenEditor sceneTokenEditor = (TokenEditor)sceneTokens;
80 sceneTokenEditor.disableLineInfo();
81 }
82 if ( stripComments ) {
83 sceneTokens.enableCommentSkipping();
84 } else {
85 sceneTokens.disableCommentSkipping();
86 }
87 TokenPrinter tp = new TokenPrinter( sceneTokens, dataSource );
88
89 // the data sink gets formatted text
90 if ( reformat ) {
91 tp.doPrettyPrint();
92 }
93
94 // generate the new token enumerator
95 tp.printRange( scene.getFirstTokenOffset(), scene.getLastTokenOffset(), true );
96
97 p.setTokenEditor( dataSource );
98 scene.setTokenEnumerator( dataSource );
99 }
100
101 /** running thread */
102 public void run() {
103 int numberFiles = filesToProcess.size();
104 for ( int i = 0; i < numberFiles; i++ ) {
105 String fileName = (String)filesToProcess.elementAt( i );
106 System.out.println( "Processing file #" + (i+1) + ": " + fileName );
107 processFile( fileName, chiselCommandList );
108 Runtime.getRuntime().gc();
109 }
110 }
111
112 /** result, exit with this */
113 public int getResult() {
114 return( 0 );
115 }
116
117 /** Process a single file */
118 void processFile( String fileName, ChiselCommandList chiselCommandList ) {
119 ProcessedFile p = new ProcessedFile( fileName );
120 p.setDoneListener( theDriver );
121
122 /* Create the ChiselFactory with all the factories to run */
123 int numberChisels = chiselCommandList.getNumberCommands();
124 for ( int i = 0; i < numberChisels; i++ ) {
125 Optimizer chisel = chiselCommandList.elementAt( i );
126 chisel.reset();
127 p.addOptimizer( chisel );
128 }
129
130 /** Run all the factories */
131 p.load();
132 waitTilDone();
133 if ( stripComments && reformat ) {
134 System.out.println( "stripping out comments and reformatting..." );
135 stripAndReformat( p );
136 } else if ( stripComments ) {
137 System.out.println( "stripping out comments..." );
138 stripAndReformat( p );
139 } else if ( reformat ) {
140 System.out.println( "reformatting..." );
141 stripAndReformat( p );
142 }
143
144 // set the saved file name, then start file saving thread
145 if ( doGzip ) {
146 String name = null;
147 if ( preserveNames ) {
148 name = p.getLocalName();
149 } else {
150 name = p.generateGzipName();
151 }
152 String saveFile = getOutdirName( name );
153 System.out.println( "Saving file in gzip format to " + saveFile );
154 p.setFile( new File( saveFile ));
155 p.gzipSave();
156 } else {
157 String name = null;
158 if ( preserveNames ) {
159 name = p.getLocalName();
160 } else {
161 name = p.generateChiseledName();
162 }
163 String saveFile = getOutdirName( name );
164 System.out.println( "Saving file to " + saveFile );
165 p.setFile( new File( saveFile ));
166 p.asciiSave();
167 }
168
169 // Wait for file saving thread to complete
170 p.waitForSave();
171 p.wipeout();
172 p = null;
173 }
174
175 /** Get the name of a file by prepending output directory name, if any */
176 String getOutdirName( String fileName ) {
177 if ( outputDir == null ) {
178 return( fileName );
179 } else {
180 return( outputDir + fileName );
181 }
182 }
183
184 void waitTilDone() {
185 suspend();
186 }
187
188 void doneCallback() {
189 resume();
190 }
191
192 /** Process a file with a single chisel */
193 void processUsing( ProcessedFile p, Optimizer chisel ) {
194 RangeReplacer rr = new RangeReplacer();
195 Scene vrmlScene = p.getScene();
196 TokenEnumerator sceneTokenEnumerator = vrmlScene.getTokenEnumerator();
197 NodeLocatorVisitor nlv = new NodeLocatorVisitor( sceneTokenEnumerator );
198 chisel.setRangeReplacer( rr );
199 chisel.setDataSource( sceneTokenEnumerator );
200 nlv.addNodeLocatorListener( chisel );
201 System.out.println( chisel.getActionMessage() );
202 vrmlScene.traverse( nlv );
203 TokenEditor te = rr.recreateTokenStream( "",
204 (TokenEditor)sceneTokenEnumerator, vrmlScene.getFirstTokenOffset(),
205 vrmlScene.getLastTokenOffset(), null );
206 rr.wipeout();
207 p.setTokenEditor( te );
208 p.setScene( vrmlScene );
209 sceneTokenEnumerator.wipeout();
210 }
211 }
212
213 class EngineRunner extends FactoryResponseAdapter {
214 ChiselEngine callback;
215 EngineRunner( ChiselEngine callback ) {
216 this.callback = callback;
217 }
218
219 public void done( FactoryData result ) {
220 callback.doneCallback();
221 }
222 }