Source code: com/trapezium/cdk/ChiselGenerator.java
1 package com.trapezium.cdk;
2 import java.lang.*;
3 import java.io.*;
4 import java.util.Hashtable;
5 import java.util.Enumeration;
6 import com.trapezium.vrml.grammar.VRML97;
7
8 public class ChiselGenerator extends java.lang.Object implements java.io.Serializable
9 {
10 static final int MaxOptions = 8;
11 OptionInfo[] optionInfo;
12 boolean modifiesNodes;
13 boolean modifiesRoutes;
14 String nodeType;
15
16 public ChiselGenerator() {
17 modifiesNodes = true;
18 modifiesRoutes = false;
19 optionInfo = new OptionInfo[MaxOptions];
20 for ( int i = 0; i < MaxOptions; i++ ) {
21 optionInfo[i] = new OptionInfo();
22 }
23 nodeType = null;
24 }
25
26 public void setNodeType( String nodeType ) {
27 this.nodeType = nodeType;
28 }
29
30 public void setNodeModifier( boolean value ) {
31 modifiesNodes = value;
32 }
33
34 public void setRouteModifier( boolean value ) {
35 modifiesRoutes = value;
36 }
37
38 public int getNumberOptions() {
39 int numberOptions = 0;
40 for ( int i = 0; i < MaxOptions; i++ ) {
41 if ( optionInfo[i].hasDescription() ) {
42 numberOptions++;
43 }
44 }
45 return( numberOptions );
46 }
47
48 public OptionInfo getValidOption( int offset ) {
49 int currentOffset = 0;
50 for ( int i = 0; i < MaxOptions; i++ ) {
51 if ( optionInfo[i].hasDescription() ) {
52 if ( offset == currentOffset ) {
53 return( optionInfo[i] );
54 } else {
55 currentOffset++;
56 }
57 }
58 }
59 return( null );
60 }
61
62 public OptionInfo getOptionInfo( int offset ) {
63 offset--;
64 return( optionInfo[offset] );
65 }
66
67 /** This is the generic java code generating stuff... */
68 String codeveloperFile;
69 String getGeneratedFileName() {
70 return( codeveloperFile + ".java" );
71 }
72 void genChisel( String codeveloper, String shortDescription, String longDescription ) {
73 String packageName = genPackageName( shortDescription );
74 try {
75 FileOutputStream fos = new FileOutputStream( new File( codeveloperFile + ".java" ));
76 System.out.println( "Generating file " + codeveloperFile + ".java" );
77 PrintStream ps = new PrintStream( fos );
78 ps.println( "/*" );
79 ps.println( " * @(#)" + codeveloperFile + ".java" );
80 ps.println( " *" );
81 ps.println( " * Copyright (c) 1999 by Trapezium Development LLC. All Rights Reserved." );
82 ps.println( " *" );
83 ps.println( " * The information in this file is the property of Trapezium Development LLC" );
84 ps.println( " * and may be used only in accordance with the terms of the license granted" );
85 ps.println( " * by Trapezium." );
86 ps.println( " *" );
87 ps.println( " */" );
88 ps.println( "package com.trapezium.chisel.codeveloper;" );
89 ps.println( "" );
90 ps.println( "import com.trapezium.chisel.Optimizer;" );
91 ps.println( "import com.trapezium.chisel.TokenPrinter;" );
92 ps.println( "import com.trapezium.chisel.IntegerConstraints;" );
93 ps.println( "import com.trapezium.vrml.node.*;" );
94 ps.println( "import com.trapezium.vrml.fields.*;" );
95 ps.println( "" );
96 ps.println( "/**" );
97 ps.println( " * " + codeveloperFile + " is a custom chisel designed by " + codeveloper );
98 ps.println( " *" );
99 ps.println( " * This code was generated by Chisel Developer Kit version 1.0" );
100 ps.println( " */" );
101 ps.println( "public class " + codeveloperFile + " extends Optimizer {" );
102
103 int numberOptions = getNumberOptions();
104 String[] optionConstants = null;
105 String[] optionVariables = null;
106 boolean[] optionIsBool = null;
107 String[] optionDescriptions = null;
108 boolean[] optionBoolVal = null;
109 int[] optionDefaultVal = null;
110 int[] optionMinVal = null;
111 int[] optionMaxVal = null;
112 int[] optionIncVal = null;
113 if ( numberOptions > 0 ) {
114 optionConstants = new String[ numberOptions ];
115 optionVariables = new String[ numberOptions ];
116 optionIsBool = new boolean[ numberOptions ];
117 optionDescriptions = new String[ numberOptions ];
118 optionBoolVal = new boolean[ numberOptions ];
119 optionDefaultVal = new int[ numberOptions ];
120 optionMinVal = new int[ numberOptions ];
121 optionMaxVal = new int[ numberOptions ];
122 optionIncVal = new int[ numberOptions ];
123 for ( int i = 0; i < numberOptions; i++ ) {
124 OptionInfo option = getValidOption( i );
125 optionConstants[i] = strToUpper( option.getDescription() ) + "_OPTION";
126 optionVariables[i] = strToName( option.getDescription() );
127 optionDescriptions[i] = option.getDescription();
128 optionIsBool[i] = option.isBool();
129 optionBoolVal[i] = option.getBoolVal();
130 optionDefaultVal[i] = option.getDefaultVal();
131 optionMinVal[i] = option.getMinVal();
132 optionMaxVal[i] = option.getMaxVal();
133 optionIncVal[i] = option.getIncVal();
134 }
135 ps.println( "\t// constants defining options by offset" );
136 for ( int i = 0; i < numberOptions; i++ ) {
137 ps.println( "\tstatic final int " + optionConstants[i] + " = " + i + ";" );
138 }
139 ps.println( "" );
140 ps.println( "\t// variables for storing option values" );
141 for ( int i = 0; i < numberOptions; i++ ) {
142 if ( optionIsBool[i] ) {
143 ps.println( "\tboolean " + optionVariables[i] + ";" );
144 } else {
145 ps.println( "\tint " + optionVariables[i] + ";" );
146 }
147 }
148 ps.println( "" );
149 }
150
151 ps.println( "\tpublic " + codeveloperFile + "() {" );
152 if ( nodeType != null ) {
153 ps.println( "\t\tsuper( \"" + nodeType + "\", \"" + longDescription + "\" );" );
154 }
155 if ( numberOptions > 0 ) {
156 for ( int i = 0; i < numberOptions; i++ ) {
157 if ( optionIsBool[i] ) {
158 genOptionBool( ps, optionVariables[i], optionBoolVal[i] );
159 } else {
160 genOptionDefault( ps, optionVariables[i], optionDefaultVal[i] );
161 }
162 }
163 }
164 ps.println( "\t}" );
165 ps.println( "" );
166 ps.println( "\t/** reset called just before chisel is run on a new file */" );
167 ps.println( "\tpublic void reset() {" );
168 ps.println( "\t}" );
169 ps.println( "" );
170 if ( numberOptions > 0 ) {
171 ps.println( "\t/** Get the number of options available for this chisel */" );
172 ps.println( "\tpublic int getNumberOptions() {" );
173 ps.println( "\t\treturn( " + numberOptions + " );" );
174 ps.println( "\t}" );
175 ps.println( "" );
176 ps.println( "\t/** Get the data type of an option */" );
177 ps.println( "\tpublic Class getOptionClass( int offset ) {" );
178 for ( int i = 0; i < numberOptions; i++ ) {
179 genOptionTypeReturn( ps, optionConstants[i], optionIsBool[i] );
180 }
181 ps.println( "\t\treturn( null );" );
182 ps.println( "\t}" );
183 ps.println( "" );
184 ps.println( "\t/** Get the label for an option */" );
185 ps.println( "\tpublic String getOptionLabel( int offset ) {" );
186 for ( int i = 0; i < numberOptions; i++ ) {
187 genOptionLabelReturn( ps, optionConstants[i], optionDescriptions[i] );
188 }
189 ps.println( "\t\treturn( null );" );
190 ps.println( "\t}" );
191 ps.println( "" );
192 ps.println( "\t/** Get the value of an option */" );
193 ps.println( "\tpublic Object getOptionValue( int offset ) {" );
194 for ( int i = 0; i < numberOptions; i++ ) {
195 genOptionValueReturn( ps, optionConstants[i], optionIsBool[i], optionVariables[i] );
196 }
197 ps.println( "\t\treturn( null );" );
198 ps.println( "\t}" );
199 ps.println( "" );
200 ps.println( "\t/** Set the value of an option */" );
201 ps.println( "\tpublic void setOptionValue( int offset, Object value ) {" );
202 for ( int i = 0; i < numberOptions; i++ ) {
203 genOptionValueSet( ps, optionConstants[i], optionIsBool[i], optionVariables[i] );
204 }
205 ps.println( "\t}" );
206 ps.println( "" );
207 ps.println( "\t/** Get the constraints on an option */" );
208 ps.println( "\tpublic Object getOptionConstraints( int offset ) {" );
209 for ( int i = 0; i < numberOptions; i++ ) {
210 genOptionConstraints( ps, optionConstants[i], optionIsBool[i], optionMinVal[i], optionMaxVal[i], optionIncVal[i] );
211 }
212 ps.println( "\t\treturn( null );" );
213 ps.println( "\t}" );
214 ps.println( "" );
215 }
216 if ( modifiesNodes ) {
217 ps.println( "\t/** Check if Node should be modified." );
218 ps.println( "\t * TODO: user defined" );
219 ps.println( "\t */" );
220 ps.println( "\tboolean optimizationOK( Node n ) {" );
221 ps.println( "\t\t// MUST BE USER DEFINED" );
222 ps.println( "\t\treturn( true );" );
223 ps.println( "\t}" );
224 ps.println( "" );
225 ps.println( "\t/** Called when node of specified type found in graph traversal */" );
226 ps.println( "\tpublic void attemptOptimization( Node n ) {" );
227 ps.println( "\t\tif ( optimizationOK( n )) {" );
228 if ( nodeType != null ) {
229 ps.println( "\t\t\t// if you need to access any of the fields, here they are" );
230 ps.println( "\t\t\t// Field value is null if field not specified in file" );
231 String[] fieldNameList = getFieldNames( nodeType );
232 if ( fieldNameList == null ) {
233 ps.println( "\t\t\t// '" + nodeType + "' is not a build in node type" );
234 } else {
235 for ( int i = 0; i < fieldNameList.length; i++ ) {
236 ps.println( "\t\t\tField " + fieldNameList[i] + " = n.getField( \"" + fieldNameList[i] + "\" );" );
237 }
238 }
239 ps.println( "" );
240 }
241 ps.println( "\t\t\t// register entire node for regeneration" );
242 ps.println( "\t\t\t// last parameter can be any object, it is passed to \"optimize\" method" );
243 ps.println( "\t\t\t// as the \"param\" parameter" );
244 ps.println( "\t\t\treplaceRange( n.getFirstTokenOffset(), n.getLastTokenOffset(), n );" );
245 ps.println( "\t\t}" );
246 ps.println( "\t}" );
247 ps.println( "" );
248 }
249 if ( modifiesRoutes ) {
250 ps.println( "\t/** Check if ROUTE should be modified." );
251 ps.println( "\t * TODO: user defined" );
252 ps.println( "\t */" );
253 ps.println( "\tboolean optimizationOK( ROUTE route ) {" );
254 ps.println( "\t\t// MUST BE USER DEFINED" );
255 ps.println( "\t\treturn( true );" );
256 ps.println( "\t}" );
257 ps.println( "" );
258 ps.println( "\t/** Called when a ROUTE is found in graph traversal */" );
259 ps.println( "\tpublic void attemptOptimization( ROUTE route ) {" );
260 ps.println( "\t\tif ( optimizationOK( route )) {" );
261 ps.println( "\t\t\t// register entire node for regeneration" );
262 ps.println( "\t\t\t// last parameter can be any object, it is passed to \"optimize\" method" );
263 ps.println( "\t\t\t// as the \"param\" parameter" );
264 ps.println( "\t\t\treplaceRange( route.getFirstTokenOffset(), route.getLastTokenOffset(), route );" );
265 ps.println( "\t\t}" );
266 ps.println( "\t}" );
267 ps.println( "" );
268 }
269
270 ps.println( "\t/** Called to regenerate a portion of the text in a file." );
271 ps.println( "\t *" );
272 ps.println( "\t * @param tp object that takes regenerated text, similar to a PrintStream" );
273 ps.println( "\t * @param param Object passed to \"replaceRange\" in \"attemptOptimization\" method above" );
274 ps.println( "\t * @param startTokenOffset offset of first token in sequence being regenerated" );
275 ps.println( "\t * @param endTokenOffset offset of last token in sequence being regenerated" );
276 ps.println( "\t */" );
277 ps.println( "\tpublic void optimize( TokenPrinter tp, Object param, int startTokenOffset, int endTokenOffset ) {" );
278 ps.println( "\t\t// TODO: user defined" );
279 ps.println( "\t\t// if nothing done here, entire range is removed" );
280 ps.println( "\t}" );
281 ps.println( "" );
282
283 ps.println( "}" );
284 ps.flush();
285 ps.close();
286 } catch ( Exception e ) {
287 e.printStackTrace();
288 }
289 }
290
291 public String[] getFieldNames( String nodeName ) {
292 String[] fieldNameList;
293 Hashtable hashTable = VRML97.getFieldTable( nodeName );
294 if ( hashTable == null ) {
295 return( null );
296 } else {
297 int size = hashTable.size();
298 fieldNameList = new String[ size ];
299 Enumeration keys = hashTable.keys();
300 int resultIdx = 0;
301 while ( keys.hasMoreElements() ) {
302 String x = (String)keys.nextElement();
303 if ( resultIdx < size ) {
304 fieldNameList[ resultIdx++ ] = x;
305 }
306 }
307 return( fieldNameList );
308 }
309 }
310
311
312 void genOptionConstraints( PrintStream ps, String constantName, boolean isBool, int minVal, int maxVal, int incVal ) {
313 if ( !isBool ) {
314 ps.println( "\t\tif ( offset == " + constantName + " ) {" );
315 ps.println( "\t\t\treturn( new IntegerConstraints( " + minVal + ", " + maxVal + ", " + incVal + " ));" );
316 ps.println( "\t\t}" );
317 }
318 }
319
320 void genOptionValueSet( PrintStream ps, String constantname, boolean isBool, String varName ) {
321 ps.println( "\t\tif ( offset == " + constantname + " ) {" );
322 if ( isBool ) {
323 ps.println( "\t\t\t" + varName + " = optionValueToBoolean( value );" );
324 } else {
325 ps.println( "\t\t\t" + varName + " = optionValueToInt( value );" );
326 }
327 ps.println( "\t\t}" );
328 }
329
330 void genOptionValueReturn( PrintStream ps, String constantname, boolean isBool, String varName ) {
331 ps.println( "\t\tif ( offset == " + constantname + " ) {" );
332 if ( isBool ) {
333 ps.println( "\t\t\treturn( booleanToOptionValue( " + varName + " ));" );
334 } else {
335 ps.println( "\t\t\treturn( intToOptionValue( " + varName + " ));" );
336 }
337 ps.println( "\t\t}" );
338 }
339
340 void genOptionTypeReturn( PrintStream ps, String constantName, boolean isBool ) {
341 ps.println( "\t\tif ( offset == " + constantName + " ) {" );
342 if ( isBool ) {
343 ps.println( "\t\t\treturn( Boolean.TYPE );" );
344 } else {
345 ps.println( "\t\t\treturn( Integer.TYPE );" );
346 }
347 ps.println( "\t\t}" );
348 }
349
350 void genOptionLabelReturn( PrintStream ps, String constantName, String optionLabel ) {
351 ps.println( "\t\tif ( offset == " + constantName + " ) {" );
352 ps.println( "\t\t\treturn( \"" + optionLabel + "\" );" );
353 ps.println( "\t\t}" );
354 }
355
356 void genOptionBool( PrintStream ps, String variable, boolean boolval ) {
357 ps.println( "\t\t" + variable + " = " + boolval + ";" );
358 }
359
360 void genOptionDefault( PrintStream ps, String variable, int val ) {
361 ps.println( "\t\t" + variable + " = " + val + ";" );
362 }
363
364 String genPackageName( String shortDesc ) {
365 codeveloperFile = strToName( shortDesc );
366 return( "com.trapezium.codeveloper." + codeveloperFile );
367 }
368
369 String strToUpper( String s ) {
370 StringBuffer sb = new StringBuffer();
371 int len = s.length();
372 for ( int i = 0; i < len; i++ ) {
373 char x = s.charAt( i );
374 if ( Character.isLetterOrDigit( x )) {
375 if ( Character.isLowerCase( x )) {
376 x = Character.toUpperCase( x );
377 }
378 sb.append( x );
379 } else if ( Character.isSpace( x )) {
380 sb.append( '_' );
381 }
382 }
383 return( sb.toString() );
384 }
385
386 String strToName( String s ) {
387 StringBuffer sb = new StringBuffer();
388 int len = s.length();
389 if ( len == 0 ) {
390 return( "empty" );
391 }
392 if ( !Character.isLetter( s.charAt( 0 ))) {
393 sb.append( "J" );
394 }
395 for ( int i = 0; i < len; i++ ) {
396 char x = s.charAt( i );
397 if ( Character.isLetterOrDigit( x )) {
398 sb.append( x );
399 } else if ( Character.isSpace( x )) {
400 sb.append( '_' );
401 }
402 }
403 return( sb.toString() );
404 }
405 }