View Javadoc

1   package net.sf.tomp.xtcl;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import net.sf.tomp.xtcl.command.Call;
7   import net.sf.tomp.xtcl.command.CatchCommand;
8   import net.sf.tomp.xtcl.command.Cd;
9   import net.sf.tomp.xtcl.command.Chain;
10  import net.sf.tomp.xtcl.command.Do;
11  import net.sf.tomp.xtcl.command.Doc;
12  import net.sf.tomp.xtcl.command.Dump;
13  import net.sf.tomp.xtcl.command.DumpContext;
14  import net.sf.tomp.xtcl.command.DumpContexts;
15  import net.sf.tomp.xtcl.command.Echo;
16  import net.sf.tomp.xtcl.command.End;
17  import net.sf.tomp.xtcl.command.Err;
18  import net.sf.tomp.xtcl.command.ExeCommand;
19  import net.sf.tomp.xtcl.command.Fil;
20  import net.sf.tomp.xtcl.command.FilterCommand;
21  import net.sf.tomp.xtcl.command.Function;
22  import net.sf.tomp.xtcl.command.Help;
23  import net.sf.tomp.xtcl.command.JavaCommand;
24  import net.sf.tomp.xtcl.command.STXFilterCommand;
25  import net.sf.tomp.xtcl.command.JoostStyle;
26  import net.sf.tomp.xtcl.command.Label;
27  import net.sf.tomp.xtcl.command.Load;
28  import net.sf.tomp.xtcl.command.PropertiesCommand;
29  import net.sf.tomp.xtcl.command.PropertiesToContext;
30  import net.sf.tomp.xtcl.command.Remove;
31  import net.sf.tomp.xtcl.command.Ret;
32  import net.sf.tomp.xtcl.command.SAXSourceCommand;
33  import net.sf.tomp.xtcl.command.Save;
34  import net.sf.tomp.xtcl.command.SetCommand;
35  import net.sf.tomp.xtcl.command.Str;
36  import net.sf.tomp.xtcl.command.Style;
37  import net.sf.tomp.xtcl.command.TeeFilterCommand;
38  import net.sf.tomp.xtcl.command.Template;
39  import net.sf.tomp.xtcl.command.Transform;
40  import net.sf.tomp.xtcl.command.XSLTFilterCommand;
41  import net.sf.tomp.xtcl.command.TryBlock;
42  import net.sf.tomp.xtcl.command.Verbose;
43  
44  /***
45   * Reads the commands from the underlying CommandLineReader, within a Context
46   * and produces a Command (usually a Sequence)
47   * 
48   * @author tomp
49   */
50  public class XTCompiler extends CompilerBase {
51      /***
52       * The main compile method. <br>
53       * Compiles commands from a String[] followed by a CommandLineReader into a
54       * command Sequence
55       * 
56       * @param cl String[] - array with one input line parsed into tokens
57       * @param clr CommandLineReader - the sources for compilation first the
58       *            String[], then the CLR
59       * @return DOCUMENT ME!
60       * @throws Exception DOCUMENT ME!
61       * @throws IllegalArgumentException DOCUMENT ME!
62       */
63      public Command compile(String[] cl, CommandLineReader clr) throws Exception {
64          // FIXME
65          //listCommandLine(cl);
66          Command commandToReturn = null;
67          Context context = getContext();
68  
69          if (cl.length == 0) {
70              return null;
71          }
72  
73          int i = 0;
74          String ci = cl[i++];
75  
76          // LOAD $varname filename
77          if (ci.equalsIgnoreCase("LOAD")) {
78              Load command = new Load();
79  
80              command.setVar(cl[i++]);
81              command.setFile(cl[i++]);
82  
83              //System.out.println(command);
84              commandToReturn = command;
85  
86              // SAVE $varname filename
87          } else if (ci.equalsIgnoreCase("SAVE")) {
88              Save command = new Save();
89  
90              command.setVar(cl[i++]);
91              command.setFile(cl[i++]);
92  
93              //System.out.println(command);
94              commandToReturn = command;
95  
96              // SET $varname $srcvarname
97          } else if (ci.equalsIgnoreCase("SET")) {
98              SetCommand command = new SetCommand();
99  
100             command.setVar(cl[i++]);
101             command.setSrcVar(cl[i++]);
102 
103             //System.out.println(command);
104             commandToReturn = command;
105 
106             // PROFILINGXINCLUDER $varname $typedbvarname [param1=val1 ...]
107 
108             /*
109              * } else if (ci.equalsIgnoreCase("PROFILINGXINCLUDER")) {
110              * ProfilingXIncluderCommand command = new
111              * ProfilingXIncluderCommand(); command.setVar(cl[i++]);
112              * command.setTypeDatabaseVar(cl[i++]);
113              * //System.out.println(command); while (i < cl.length) { String
114              * param = cl[i++]; StringTokenizer pst = new StringTokenizer(param,
115              * "="); String name = pst.nextToken(); Object value =
116              * pst.nextToken(); command.setParameter(name, value); }
117              * commandToReturn = command;
118              */
119 
120             // DUMP $varname
121         } else if (ci.equalsIgnoreCase("DUMP")) {
122             Dump command = new Dump();
123 
124             if (i < cl.length) {
125                 command.setVar(cl[i++]);
126             }
127 
128             //System.out.println(command);
129             commandToReturn = command;
130 
131             // CONTEXT [DEEP|VAR] - dumps a Context
132         } else if (ci.equalsIgnoreCase("CONTEXT")) {
133             DumpContext command = new DumpContext();
134 
135             command.setDeep((i < cl.length)
136                     && (cl[i].equals("DEEP") || cl[i].startsWith("VAR")));
137 
138             //System.out.println(command);
139             i++;
140             commandToReturn = command;
141 
142             // CONTEXTS [DEEP|VAR] - dumps all Contexts
143         } else if (ci.equalsIgnoreCase("CONTEXTS")) {
144             DumpContexts command = new DumpContexts();
145 
146             command.setDeep((i < cl.length)
147                     && (cl[i].equals("DEEP") || cl[i].startsWith("VAR")));
148 
149             //System.out.println(command);
150             i++;
151             commandToReturn = command;
152 
153             // TRANSFORM sourceref styleref resultref [param1=val1 ...]
154         } else if (ci.equalsIgnoreCase("TRANSFORM")) {
155             Transform command = new Transform();
156 
157             // source
158             command.setSourceRef(cl[i++]);
159             command.setStyleRef(cl[i++]);
160             command.setResultRef(cl[i++]);
161 
162             // set all param=value pairs
163             i = setParameters(cl, i, command);
164 
165             //            command.init(context);
166             //System.out.println(command);
167             commandToReturn = command;
168 
169             // CHAIN sourceref [(filter|style)*] resultref
170             // - creates a transformation chain
171         } else if (ci.equalsIgnoreCase("CHAIN")) {
172             Chain command = new Chain();
173 
174             // source
175             command.setSourceRef(cl[i++]);
176 
177             while (i < (cl.length - 1)) {
178                 String styleRef = cl[i++];
179 
180                 command.addFilterStyleRef(styleRef);
181             }
182 
183             command.setResultRef(cl[i++]);
184 
185             //            command.init(context);
186             //System.out.println(command);
187             commandToReturn = command;
188 
189             // JAVA classname [param*] - executes a Java class
190         } else if (ci.equalsIgnoreCase("JAVA")) {
191             JavaCommand command = new JavaCommand();
192             List params = new ArrayList();
193 
194             // name of the launched Java class
195             if (i < cl.length) {
196                 command.setClassName(cl[i++]);
197             }
198 
199             // params passed to launched Java class
200             while (i < cl.length) {
201                 params.add(cl[i++]); 
202             }
203 
204             command.setArgs((String[]) params.toArray(new String[0]));
205 
206             //System.out.println(command);
207             commandToReturn = command;
208 
209             // RUN command [param*] - executes a native command
210         } else if (ci.equalsIgnoreCase("RUN")) {
211             ExeCommand command = new ExeCommand();
212             List params = new ArrayList();
213 
214             // name and params of the executable program
215             while (i < cl.length) {
216                 params.add(cl[i++]);
217             }
218 
219             command.setCmdArray((String[]) params.toArray(new String[0]));
220 
221             //System.out.println(command);
222             commandToReturn = command;
223 
224             // SAXSOURCE $var xmlreaderclassname inputsource(ref) [param*]
225         } else if (ci.equalsIgnoreCase("SAXSOURCE")) {
226             SAXSourceCommand command = new SAXSourceCommand();
227 
228             command.setVar(cl[i++]);
229 
230             // name of the created XMLFilter class
231             command.setClassName(cl[i++]);
232 
233             // params passed to the created XMLReader
234             command.setInputSource(cl[i++]);
235 
236             i = setParameters(cl, i, command);
237 
238             //System.out.println(command);
239             commandToReturn = command;
240 
241             // FILTER $var xmlfilterclassname [param*]
242         } else if (ci.equalsIgnoreCase("FILTER")) {
243             FilterCommand command = new FilterCommand();
244             List params = new ArrayList();
245 
246             command.setVar(cl[i++]);
247 
248             // name of the created XMLFilter class
249             command.setClassName(cl[i++]);
250 
251             // params passed to the created XMLFilter
252             i = setParameters(cl, i, command);
253 
254             //System.out.println(command);
255             commandToReturn = command;
256 
257             // TRANSFILTER|STYLEFILTER $varname styleref [param*] - defines
258             // a XSLT transformation filter
259         } else if (ci.equalsIgnoreCase("TRANSFILTER")
260                 || ci.equalsIgnoreCase("STYLEFILTER")) {
261             XSLTFilterCommand command = new XSLTFilterCommand();
262             List params = new ArrayList();
263 
264             command.setVar(cl[i++]);
265 
266             // ref to the style
267             command.setStyleRef(cl[i++]);
268 
269             // params passed to the created XMLFilter
270             i = setParameters(cl, i, command);
271 
272             //System.out.println(command);
273             commandToReturn = command;
274 
275             // JOOSTFILTER $varname styleref [param*] - defines
276             // a STX transformation filter (using the Joost processor)
277         } else if (ci.equalsIgnoreCase("JOOSTFILTER")) {
278             STXFilterCommand command = new STXFilterCommand();
279             List params = new ArrayList();
280 
281             command.setVar(cl[i++]);
282 
283             // ref to the style
284             command.setStyleRef(cl[i++]);
285 
286             // params passed to the created XMLFilter
287             i = setParameters(cl, i, command);
288 
289             //System.out.println(command);
290             commandToReturn = command;
291 
292             // TEECHAIN $varname [filterstyleref*] resultref
293             // - defines a tee-like chain filter
294         } else if (ci.equalsIgnoreCase("TEECHAIN")
295                 || ci.equalsIgnoreCase("TEE")) {
296             TeeFilterCommand command = new TeeFilterCommand();
297 
298             // VAR NAME
299             command.setVar(cl[i++]);
300 
301             // style/filter refs
302             while (i < (cl.length - 1)) {
303                 String styleRef = cl[i++];
304 
305                 command.addFilterStyleRef(styleRef);
306             }
307 
308             // result ref
309             command.setResultRef(cl[i++]);
310 
311             //System.out.println(command);
312             commandToReturn = command;
313 
314             // RETURN [values*] - finishes the function and returns values
315         } else if (ci.equalsIgnoreCase("RETURN")) {
316             Ret command = new Ret();
317             List params = new ArrayList();
318 
319             // params returned
320             while (i < cl.length) {
321                 params.add(cl[i++]);
322             }
323 
324             command.setReturns((String[]) params.toArray(new String[0]));
325 
326             //System.out.println(command);
327             commandToReturn = command;
328 
329             // DO templatename [param=value*]
330         } else if (ci.equalsIgnoreCase("DO")) {
331             Do command = new Do();
332             List params = new ArrayList();
333 
334             // name of the template being run
335             command.setTemplateName(cl[i++]);
336 
337             // params passed to the template
338             i = setParameters(cl, i, command);
339 
340             //System.out.println(command);
341             commandToReturn = command;
342 
343             // INCLUDE scriptfilename
344         } else if (ci.equalsIgnoreCase("INCLUDE")) {
345             // INCLUDE: compile the script from file
346             String scriptName = cl[i++];
347 
348             commandToReturn = compile(context.getFile(scriptName));
349 
350             // CALL funcname [param*] - calls the function
351             // and passes real parameters to it
352         } else if (ci.equalsIgnoreCase("CALL")) {
353             Call command = new Call();
354             String name = cl[i++];
355             List params = new ArrayList();
356 
357             // params to be passed
358             while (i < cl.length) {
359                 params.add(cl[i++]);
360             }
361 
362             command.setName(name);
363             command.setPasses((String[]) params.toArray(new String[0]));
364 
365             //System.out.println(command);
366             commandToReturn = command;
367 
368             // REMOVE [varrefs*] - removes the variables from the Context
369         } else if (ci.equalsIgnoreCase("REMOVE")) {
370             Remove command = new Remove();
371             List vars = new ArrayList();
372             // vars to be removed
373             while (i < cl.length) {
374                 vars.add(cl[i++]);
375             }
376             command.setRemoves((String[]) vars.toArray(new String[0]));
377 
378             //System.out.println(command);
379             commandToReturn = command;
380 
381             // FUNCTION funcname [formalparam*] - defines a function
382             // with formal parameters specified
383         } else if (ci.equalsIgnoreCase("FUNCTION")) {
384             Function command = new Function();
385             String name = cl[i++];
386             List params = new ArrayList();
387 
388             // params
389             while (i < cl.length) {
390                 params.add(cl[i++]);
391             }
392 
393             command.setName(name);
394             command.setParams((String[]) params.toArray(new String[0]));
395 
396             command.setCommand(compile(clr));
397 
398             //System.out.println(command);
399             context.put(name, command);
400             commandToReturn = null;
401 
402             // TEMPLATE tempname - defines a template
403             // with possible by-name parameters marked %paramname% in the body
404         } else if (ci.equalsIgnoreCase("TEMPLATE")) {
405             Template command = new Template();
406             String name = cl[i++];
407 
408             command.setName(name);
409 
410             StringBuffer tempBodyComp = new StringBuffer();
411             String line = clr.nextCommandLine();
412 
413             while ((line != null)
414                     && ((line.length() < 3) || !line.trim().substring(0, 3)
415                             .equalsIgnoreCase("END"))) {
416                 tempBodyComp.append(line);
417                 tempBodyComp.append("\n");
418                 line = clr.nextCommandLine();
419             }
420 
421             command.setBody(tempBodyComp.toString());
422 
423             //System.out.println(command);
424             context.put(name, command);
425             commandToReturn = null;
426 
427             // PROPERTIES tempname - introduces a Properties object
428             // with body
429         } else if (ci.equalsIgnoreCase("PROPERTIES")) {
430             PropertiesCommand command = new PropertiesCommand();
431 
432             command.setVar(cl[i++]);
433             if (i < cl.length) {
434                 // has file name or variable reference
435                 command.setFileNameOrRef(cl[i++]);
436             } else {
437                 // has only body
438                 StringBuffer tempBodyComp = new StringBuffer();
439                 String line = clr.nextCommandLine();
440 
441                 while ((line != null)
442                         && ((line.length() < 3) || !line.trim().substring(0, 3)
443                                 .equalsIgnoreCase("END"))) {
444                     tempBodyComp.append(line);
445                     tempBodyComp.append("\n");
446                     line = clr.nextCommandLine();
447                 }
448 
449                 command.setBody(tempBodyComp.toString());
450             }
451             //System.out.println(command);
452             commandToReturn = command;
453 
454             // ERROR errno - throws an error with int value errno
455         } else if (ci.equalsIgnoreCase("ERROR")) {
456             Err command = new Err();
457 
458             if (i < cl.length) {
459                 command.setError(Integer.parseInt(cl[i++]));
460             }
461 
462             //System.out.println(command);
463             commandToReturn = command;
464 
465             // END/QUIT/ABORT/EXIT/BYE - ends a function definition/execution or the program
466             // all are not applicable to template (only END works there)!
467         } else if (ci.equalsIgnoreCase("END") || ci.equalsIgnoreCase("QUIT")
468                 || ci.equalsIgnoreCase("ABORT") || ci.equalsIgnoreCase("EXIT")
469                 || ci.equalsIgnoreCase("BYE")) {
470             End command = new End();
471 
472             //System.out.println(command);
473             commandToReturn = command;
474 
475             // CATCH - catches an error
476         } else if (ci.equalsIgnoreCase("CATCH")) {
477             CatchCommand command = new CatchCommand();
478 
479             //System.out.println(command);
480             commandToReturn = command;
481 
482             // TRY - starts a checked sequence - errors will be caught
483         } else if (ci.equalsIgnoreCase("TRY")) {
484             TryBlock command = new TryBlock();
485             Compiler blockBodyComp = new XTCompiler();
486 
487             context.addCompiler(blockBodyComp);
488 
489             command.setCommand(blockBodyComp.compile(clr));
490 
491             //System.out.println(command);
492             commandToReturn = command;
493 
494             // HELP - prints help
495         } else if (ci.equalsIgnoreCase("HELP")) {
496             Help command = new Help();
497 
498             //System.out.println(command);
499             commandToReturn = command;
500 
501             // ECHO text - prints the text on stout
502         } else if (ci.equalsIgnoreCase("ECHO")) {
503             Echo command = new Echo();
504 
505             command.setEcho(cl[i++]);
506 
507             //System.out.println(command);
508             commandToReturn = command;
509 
510             // VERBOSE [ON|OFF] - set verbose mode on|off
511         } else if (ci.equalsIgnoreCase("VERBOSE")) {
512             Verbose command = new Verbose();
513 
514             if(i < cl.length) {
515                 command.setVerbose(cl[i++].equals("OFF"));
516             } else {
517                 command.setVerbose(true);
518             }
519 
520             //System.out.println(command);
521             commandToReturn = command;
522 
523             // CD directory - changes the directory
524         } else if (ci.equalsIgnoreCase("CD")) {
525             Cd command = new Cd();
526 
527             command.setFile(cl[i++]);
528 
529             //System.out.println(command);
530             commandToReturn = command;
531 
532             // DOCUMENT|DOC varname - creates the document as a DOM tree
533         } else if (ci.equalsIgnoreCase("DOCUMENT")
534                 || ci.equalsIgnoreCase("DOC")) {
535             Doc command = new Doc();
536 
537             command.setVar(cl[i++]);
538 
539             //System.out.println(command);
540             commandToReturn = command;
541 
542             // STRING varname strvalue - creates a String
543         } else if (ci.equalsIgnoreCase("STRING")) {
544             Str command = new Str();
545 
546             command.setVar(cl[i++]);
547 
548             if (i < cl.length) {
549                 command.setValue(cl[i++]);
550             }
551 
552             //System.out.println(command);
553             commandToReturn = command;
554 
555             // PROPERTIES-TO-CONTEXT $propvar [prefix]
556             // default prefix = "$"
557         } else if (ci.equalsIgnoreCase("PROPERTIES-TO-CONTEXT")) {
558             PropertiesToContext command = new PropertiesToContext();
559 
560             command.setVar(cl[i++]);
561 
562             if (i < cl.length) {
563                 command.setPrefix(cl[i++]);
564             }
565 
566             //System.out.println(command);
567             commandToReturn = command;
568 
569             // FILE varname filename - creates a File for "filename"
570         } else if (ci.equalsIgnoreCase("FILE")) {
571             Fil command = new Fil();
572 
573             command.setVar(cl[i++]);
574             command.setFile(cl[i++]);
575 
576             //System.out.println(command);
577             commandToReturn = command;
578 
579             // STYLE varname styleref
580         } else if (ci.equalsIgnoreCase("STYLE")) {
581             Style command = new Style();
582 
583             command.setVar(cl[i++]);
584             command.setStyleRef(cl[i++]);
585 
586             //System.out.println(command);
587             commandToReturn = command;
588 
589             // JOOSTSTYLE varname styleref - creates a Joost (STX) style
590         } else if (ci.equalsIgnoreCase("JOOSTSTYLE")
591                 || ci.equalsIgnoreCase("STXSTYLE")) {
592             JoostStyle command = new JoostStyle();
593 
594             command.setVar(cl[i++]);
595             command.setStyleRef(cl[i++]);
596 
597             //System.out.println(command);
598             commandToReturn = command;
599 
600             // LABEL labelname - creates a label
601         } else if (ci.equalsIgnoreCase("LABEL")) {
602             Label lab = new Label();
603 
604             lab.setName(cl[i]);
605 
606             //System.out.println(lab);
607             context.put(cl[i], lab);
608             i++;
609             commandToReturn = lab;
610 
611             // COMPILER $xtcompilerclassname - will use the specified compiler
612             // until END
613         } else if (ci.equalsIgnoreCase("COMPILER")) {
614             String compClassName = cl[i++];
615             Compiler comp = CompilerFactory.createCompiler(compClassName,
616                     context);
617 
618             if (context.isVerbose()) {
619                 System.out.println("Switching to compiler " + compClassName);
620             }
621 
622             commandToReturn = comp.compile(clr);
623             context.removeCompiler();
624 
625             if (context.isVerbose()) {
626                 System.out.println("Back from compiler " + compClassName);
627             }
628 
629             // empty line or remark - null command
630         } else if (ci.startsWith(" ") || ci.startsWith("#")) {
631             commandToReturn = null;
632         } else {
633             return compileByNextCompiler(ci, cl, clr);
634         }
635 
636         assertWholeLineRead(ci, i, cl, commandToReturn);
637 
638         //System.out.println("Compiled command="+commandToReturn);
639         return commandToReturn;
640     }
641 
642 }
643 
644 /*
645  * The contents of this file are subject to the Mozilla Public License Version
646  * 1.1 (the "License"); you may not use this file except in compliance with the
647  * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
648  * Software distributed under the License is distributed on an "AS IS" basis,
649  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
650  * the specific language governing rights and limitations under the License. The
651  * Original Code is: all this file. The Initial Developer of the Original Code
652  * is: Tomas Pitner, Masaryk University in Brno, Czech Republic. Contributor(s):
653  */