KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > yagga > miniinstaller > MiniInstaller


1 /*
2  * This file is part of MiniInstaller, a self installer builder for Java
3  * Copyright (C) 2002 Walter Gamba
4  * mailto:walter@yagga.net
5  * http://www.yagga.net/java/miniinstaller
6  *
7  * MiniInstaller is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * MiniInstaller is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * As the time of writing, the GNU General Public Licene can be
22  * found at http://www.gnu.org/licenses/gpl.txt
23  *
24  */

25
26 package net.yagga.miniinstaller;
27
28 import net.yagga.util.*;
29 import java.util.*;
30 import net.yagga.miniinstaller.gui.InstallFrame;
31 import java.awt.*;
32 import java.lang.reflect.*;
33 import java.net.*;
34 import java.io.*;
35 import net.yagga.miniinstaller.gui.FinalExecuter;
36
37 /**
38  * <p>Title: MiniInstaller</p>
39  * <p>Description: </p>
40  * <p>Copyright: Copyright (c) 2002</p>
41  * <p>Company: Yagga Soft</p>
42  * Main class of the MiniInstaller software.
43  * It is the engine of everything. Reads config file and execute step by step the installer.
44  * If installation is graphical, uses classes in package net.yagga.miniinstaller.gui
45  * @author Walter Gamba
46  * @version 1.0
47  * @todo e fare ritornare in EXEC_JAR la variabile
48  * @see net.yagga.miniinstaller.gui.InstallFrame
49  */

50 public class MiniInstaller implements FinalExecuter {
51   /**
52    * global flags etc..
53    */

54   private boolean console=false;
55   private boolean debug=false;
56   private boolean stripLastNewLine=true;
57   /**
58    * variables
59    */

60   HashMap vars=new HashMap();
61   public final static int UNZIP_DONE=999;
62
63     //stores every file created/ copied etc..
64
private Vector filesWritten;
65     private Vector dirsCreated;
66
67     Copier copier=null;
68     Unzipper unzipper=null;
69
70     private String JavaDoc shellCommand=null;
71
72     /**
73      * Entry point in the program. It reads commands from a configuration
74      * file, or it can be used as a debug (console) tool.
75      * To use it as debug pass 2 or more parameters:<BR>
76      * 1) Command name, as it appear in a script file (COPY, EXEC_JAVA..)
77      * 2...n) command parameters
78      * @param argv
79      * @author Walter Gamba
80      */

81   public static void main(String JavaDoc argv[]){
82     Ut.setLogChannelEnable(false,false);
83     Version.writeInfo();
84         MiniInstaller mi=null;
85         if(argv.length==1)
86        mi=new MiniInstaller(argv[0]);
87         else{
88             String JavaDoc params[]=new String JavaDoc[argv.length-1];
89             System.arraycopy(argv,1,params,0,params.length);
90             mi=new MiniInstaller(argv[0],params);
91         }
92   }
93
94   ScriptReader sr;
95   InstallFrame frame=null;
96   //horrend!
97
private boolean wait=false;
98   private boolean inputting=false;
99   private String JavaDoc inVarName="";
100   private int currCommand=0;
101   private int maxCmds=0;
102
103     /**
104      * Dirty entry point in miniInstaller
105      * Use it to test specific commands. It is console only, and debug On.
106      * @param command a command (as it is written in the script file)
107      * @param args command arguments. An array of Strings
108      * @deprecated use it only to debug MiniInstaller
109      * @author Walter Gamba
110      */

111     public MiniInstaller(String JavaDoc command, String JavaDoc[] args){
112         debug=true;
113         console=true;
114         initPredefinedVars();
115         //build a fake command
116
Vector v=new Vector();
117         //add fake status name
118
v.add(command);
119         for(int i=0;i<args.length;i++)
120             v.add(args[i]);
121         ScriptCommand com=new ScriptCommand(command,v);
122         //ecxecution
123
initExecute();
124         execute(com);
125     }
126
127     /**
128      * Main entry point in the installer.
129      * @param scriptFile a script file containig Commands to display the Installer
130      * @author Walter Gamba
131      */

132   public MiniInstaller(String JavaDoc scriptFile) {
133     sr=new ScriptReader(scriptFile);
134     if(debug)
135       sr.debug();
136     ScriptCommand cmds[]=sr.scriptCommands;
137     maxCmds=cmds.length;
138     initPredefinedVars();
139     initExecute();
140     if(!console){
141       frame=new InstallFrame(this,Version.getFQName() +" install");
142       frame.setVisible(false);
143       stepExecute(sr);
144     }
145     if(console){
146       for(int i=0;i<cmds.length;i++)
147         execute(cmds[i]);
148     }
149   }
150
151   private void initPredefinedVars(){
152     //initialize predefined varaibles...
153
setVar("USER_NAME",System.getProperty("user.name"));
154     setVar("USER_HOME",System.getProperty("user.home"));
155     setVar("JAVA_HOME",System.getProperty("java.home"));
156     setVar("JAVA_VERSION",System.getProperty("java.version"));
157     setVar("OS_NAME",System.getProperty("os.name"));
158     setVar("OS_ARCH",System.getProperty("os.arch"));
159     setVar("OS_VERSION",System.getProperty("os.version"));
160       //create a var named SHELL ..empty for UNIX, "command" or "cmd"
161
//for windowzes.. so users can issue commands like "dir", "ls" etc..
162
//detect OS...
163
String JavaDoc osName = System.getProperty("os.name" );
164         String JavaDoc osShell="";
165     if( osName.indexOf("Windows")!=-1){
166             if(osName.indexOf("9")!=-1){ //95, 98...
167
osShell="command.com /C ";
168             }
169             else
170                 osShell="cmd.exe /C ";
171         }
172         else
173             osShell="sh -c";
174
175         setVar("OS_SHELL",osShell);
176   }
177
178   public void initExecute(){
179     currCommand=0;
180         dirsCreated=new Vector();
181         filesWritten=new Vector();
182   }
183
184   private void stepExecute(ScriptReader sr){
185
186     ScriptCommand cmds[]=sr.scriptCommands;
187         //currCommand=-1;
188
while(++currCommand<maxCmds){
189       ScriptCommand cmd=cmds[currCommand];
190       if(cmd.isStep)
191         doStep(); //move forward little red arrow
192
if(currCommand>=maxCmds)
193         exit();
194       if(!execute(cmd))
195         break;
196             //Ut.infoln(currCommand+"");
197
}
198   }
199
200   private void stepBackExecute(ScriptReader sr){
201     //currCommand--;
202
if(currCommand<=0)
203       return;
204
205     //Ut.infoln("1stepBackExecute "+currCommand +" "+sr.scriptCommands[currCommand].prevInteractiveCommand);
206
int oldCurrCommand=currCommand;
207     ScriptCommand cmds[]=sr.scriptCommands;
208     //if(!cmds[currCommand].isInteractive)
209
// return;
210

211     currCommand=cmds[currCommand].prevInteractiveCommand;
212     if(currCommand==-1){
213       currCommand=oldCurrCommand;
214       return; //we have reached the last step
215
}
216
217     if(!cmds[currCommand].isInteractive)
218       return;
219     //command MUSt be a step..
220
//do as many step back as needed..
221
frame.revertStep(currCommand); //move backward little red arrow
222
execute(cmds[currCommand]);
223
224   }
225
226
227     /**
228      * Executes a SCriptCommand and tells if engine should execute immediately
229      * again or wait.
230      * returns continue or not continue: call again or not??
231      * default =false (halt);
232      * @param cmd the ScriptCommand we want to execute
233      * @return true or false if the engin should continue or wait user input. Atn
234      * the moment it returns <CODE>true</CODE> for Meta commands, <CODE>false</CODE> otherwise.
235      * @author Walter Gamba
236      */

237   private boolean execute(ScriptCommand cmd){
238     //check for special DEBUG value
239
String JavaDoc deb=getVar(ScriptReader.DEBUG);
240         if(deb!=null)
241             debug=(deb.equals("true") || deb.equals("1"));
242
243     //Ut.infoln("DEBUG is"+debug);
244
inputting=false;
245         unzipper=null;
246         copier=null;
247     //does var subst...
248
//...on a local copy of params
249
String JavaDoc params[]=new String JavaDoc[cmd.params.length];
250     for(int k=0;k<cmd.params.length;k++){
251         params[k]=StringManip.escape(cmd.params[k],true);
252       params[k]=doVarSubst( params[k]);
253       //Ut.infoln(""+k+")=<"+params[k]+">");
254
}
255     //System.err.println("--"+cmd.cmdType);
256
if(!cmd.isMeta())//ho titolo
257
doSetName(cmd.name);
258
259     switch(cmd.cmdType){
260     //meta commands
261
case ScriptCommand._HIDE:
262       doHide();
263       break;
264     case ScriptCommand._SHOW:
265       doShow();
266       break;
267     case ScriptCommand._DIMS:
268       doSetDims(params[0],params[1]);
269       break;
270     case ScriptCommand._TITLE:
271       doSetTitle(params[0]);
272       break;
273     case ScriptCommand._SET_COL:
274       doSetCol(params[0],params[1],params[2],params[3]);
275       break;
276         case ScriptCommand._SET_FONT:
277       doSetFont(params[0],params[1],params[2],params[3]);
278             break;
279         case ScriptCommand._LOOK_AND_FEEL:
280             doChangeLookAndFeel(params[0]);
281             break;
282         case ScriptCommand._STEP_HIDE:
283             doStepVisible(false);
284             break;
285         case ScriptCommand._STEP_SHOW:
286             doStepVisible(true);
287             break;
288     //0 params..
289
//1 param
290
case ScriptCommand.WRITE:
291       doWrite(params[0],params[1]);
292       break;
293     case ScriptCommand.WRITE_CONSOLE:
294       doWriteConsole(params[0]);
295       break;
296     case ScriptCommand.DISPLAY:
297       doDisplay(params[0]);
298       break;
299     case ScriptCommand.DISPLAY_CONSOLE:
300       doDisplayConsole(params[0]);
301       break;
302     case ScriptCommand.FINAL:
303       doFinal(params[0],params[1],params[2],params[3]);
304       break;
305     case ScriptCommand.SHOW:
306       doShow(params[0]);
307       break;
308     //2 params
309
case ScriptCommand.SET:
310       doSet(params[0],params[1]);
311       return true;
312       //break;
313
case ScriptCommand.UNZIP:
314       doUnzip(params[0],params[1],params[2]);
315       break;
316     //3 params
317
case ScriptCommand.INPUT:
318       String JavaDoc defVal=cmd.value != null ? cmd.value : params[3];
319       doInput(params[0],params[1],params[2],defVal);
320       break;
321     case ScriptCommand.INPUT_FILE:
322       defVal=cmd.value != null ? cmd.value : params[3];
323       doInputFile(params[0],params[1],params[2],defVal);
324       break;
325     case ScriptCommand.INPUT_DIR:
326       defVal=cmd.value != null ? cmd.value : params[3];
327       doInputDir(params[0],params[1],params[2],defVal);
328       break;
329     case ScriptCommand.INPUT_CONSOLE:
330       doInputConsole(params[0],params[1],params[2]);
331       break;
332     //special
333
case ScriptCommand.EXEC_JAR_METHOD:
334       String JavaDoc subparams[]=new String JavaDoc[params.length-3];
335       System.arraycopy(params,3,subparams,0,subparams.length);
336       doExecJarMethod(params[0],params[1],params[2],subparams);
337       break;
338     case ScriptCommand.EXEC_JAVA:
339       subparams=new String JavaDoc[params.length-2];
340       System.arraycopy(params,2,subparams,0,subparams.length);
341       doExecJava(params[0],params[1],subparams);
342       break;
343     case ScriptCommand.EXEC_JAR:
344       subparams=new String JavaDoc[params.length-1];
345       System.arraycopy(params,1,subparams,0,subparams.length);
346       doExecJar(params[0],subparams);
347       break;
348     case ScriptCommand.COPY:
349       doCopy(params[0],params[1],params[2]);
350       break;
351     case ScriptCommand.START:
352       doStart(params[0],params[1],false);
353       break;
354     case ScriptCommand.START_IMG:
355       doStart(params[0],params[1],true);
356       break;
357     }
358     if(cmd.isMeta())
359       return true;
360     return false;
361   }
362
363   public Step[] getSteps(){
364     ScriptCommand cmds[]=sr.scriptCommands;
365     Step ss[]=new Step[cmds.length];
366     int i=0,j=0;
367     for(i=0;i<cmds.length;i++){
368       if(!cmds[i].isMeta() && cmds[i].isStep)//ho titolo
369
// ss[j++]=doVarSubst(cmds[i].name); //useless.. no vars defined yet!
370
ss[j++]= new Step(cmds[i].name,i);
371     }
372     Step ret[]=new Step[j];
373     System.arraycopy(ss,0,ret,0,j);
374     return ret;
375   }
376
377   /***
378     utils
379   */

380   private void doStep(){
381     frame.doStep();
382   }
383
384   private String JavaDoc doVarSubst(String JavaDoc strWithVar){
385     if(debug)
386       Ut.infoln("Subst in "+strWithVar+", vars are"+vars.toString());
387     return StringManip.makeSubsts(strWithVar,vars);
388   }
389
390   private void setVar(String JavaDoc varName, String JavaDoc value){
391         if(value!=null && this.stripLastNewLine){
392       if(value.endsWith("\n") || value.endsWith("\r") )
393         value=value.substring(0,value.length()-1);
394       if(value.endsWith("\n") || value.endsWith("\r") )
395         value=value.substring(0,value.length()-1);
396     }
397         else if(value==null)
398             value="";
399     vars.put("$"+varName+"$",value);
400         if(varName.equals(ScriptReader.DEBUG))
401             debug=(value.equals("true") || value.equals("1"));
402   }
403
404   private String JavaDoc getVar(String JavaDoc varName){
405     return (String JavaDoc)vars.get("$"+varName+"$");
406   }
407
408   private void doSetName(String JavaDoc n){
409     if(console){
410       Ut.infoln("############## "+n+" ##############");
411     }
412     else{
413       frame.setName(n);
414     }
415   }
416
417   private void doSetCol(String JavaDoc what, String JavaDoc r,String JavaDoc g, String JavaDoc b){
418     try{
419       int c1=Integer.parseInt(r);
420       int c2=Integer.parseInt(g);
421       int c3=Integer.parseInt(b);
422       frame.setCol(what,c1,c2,c3);
423     }catch(NumberFormatException JavaDoc nfe){
424             Ut.error("Wrong colors "+r+","+g+","+b+".");
425     }
426   }
427
428     /**
429      *
430      * @param font
431      * @param face
432      * @param style as per Font.BOLD, Font.ITALIC or PLAIN:
433      * Bold is 1, Italic 2, Plain is 0
434      * @param size
435      */

436     private void doSetFont(String JavaDoc font, String JavaDoc face, String JavaDoc style, String JavaDoc size){
437     try{
438       int st=Integer.parseInt(style);
439       int sz=Integer.parseInt(size);
440       frame.setFont(font,face,st,sz);
441     }catch(NumberFormatException JavaDoc nfe){
442             Ut.error("Wrong Font "+face+","+style+","+size+".");
443     }
444     }
445     /**
446      * call final state..
447      * @param msg
448      * @param title
449      * @param shellCommand
450      * @param shellCaption
451      */

452   private void doFinal(String JavaDoc msg,String JavaDoc title,String JavaDoc shellCommand,String JavaDoc shellCaption){
453     if(debug)
454       Ut.infoln("-FNIAL '"+msg+"'");
455     if(console){
456       doWriteConsole(msg+"\n"+title);
457         if(shellCommand!=null){
458                 Ut.infoln("Execute '"+shellCommand+"' ("+shellCaption+" ? [N/y]");
459                 String JavaDoc val=Ut.readStringFromSTDIN();
460                 if(val.equalsIgnoreCase("Y"))
461             executeShellCommand(shellCommand);
462             }
463             exit();
464       return;
465     }
466     //
467
frame.doFinal(msg,title,shellCommand,shellCaption);
468         //store for future user, in the exit() method
469
this.shellCommand=shellCommand;
470   }
471
472   private void doWrite(String JavaDoc title,String JavaDoc msg){
473     doWrite(title,msg,true);
474   }
475   private void doWrite(String JavaDoc title,String JavaDoc msg, boolean go){
476     if(debug)
477       Ut.infoln("-WRITE '"+msg+"'");
478     if(console){
479       doWriteConsole(msg);
480       return;
481     }
482     //
483
frame.doWrite(title,msg,go);
484   }
485   private void doStart(String JavaDoc title,String JavaDoc msgOrImg, boolean isImage){
486     if(debug)
487       Ut.infoln("-START '"+msgOrImg+"'");
488     if(console && !isImage){
489       doWriteConsole(title+"\n-----------\n"+msgOrImg);
490       return;
491     }
492     //
493
if(debug)
494             Ut.infoln("Title="+title+", msgOrImg="+msgOrImg+",image?="+isImage);
495     frame.doStart(title,msgOrImg,isImage);
496   }
497   private void doWriteConsole(String JavaDoc msg){
498     if(debug)
499       Ut.infoln("-WRITE_CONSOLE '"+msg+"'");
500     Ut.infoln(">>"+msg);
501   }
502   private void doAlert(String JavaDoc msg){
503     doAlert(msg,true);
504   }
505   /**
506    * display an alert message, blocking or not
507    */

508   private void doAlert(String JavaDoc msg, boolean block){
509     //msg=StringManip.escape(msg,true);
510
if(debug)
511       Ut.infoln("-ALERT '"+msg+"'");
512     if(console){
513       doAlertConsole(msg);
514       return;
515     }
516     //
517
frame.doAlert(msg,block);
518   }
519   private void doAlertConsole(String JavaDoc msg){
520     //msg=StringManip.escape(msg,true);
521
if(debug)
522       Ut.infoln("-ALERT_CONSOLE '"+msg+"'");
523     Ut.infoln("**ALERT>>"+msg);
524   }
525   private void doDisplay(String JavaDoc msgFile){
526     if(debug)
527       Ut.infoln("-DISPLAY '"+msgFile+"'");
528     if(console){
529       doDisplayConsole(msgFile);
530       return;
531     }
532     //String f=Ut.readFile(msgFile);
533
String JavaDoc f=ResourceMgr.retrieveFile(msgFile);
534     frame.doDisplay(f);
535   }
536   private void doDisplayConsole(String JavaDoc msgFile){
537     if(debug)
538       Ut.infoln("-DISPLAY_CONSOLE '"+msgFile+"'");
539     //read file
540
String JavaDoc f=Ut.readFile(msgFile);
541     Ut.infoln("-----------------------------------------------");
542     Ut.infoln(f);
543     Ut.infoln("-----------------------------------------------");
544   }
545
546     private void doChangeLookAndFeel(String JavaDoc laf){
547         if(console)
548             return;
549         frame.setLookAndFeel(laf);
550     }
551
552   private void doShow(String JavaDoc imgFile){
553     if(console)
554       return;
555     frame.doShow(imgFile);
556   }
557   private void doSet(String JavaDoc varName, String JavaDoc value){
558     if(debug)
559       Ut.infoln("-SET '"+varName+"'='"+value+"'");
560     setVar(varName,value);
561   }
562   private void doUnzip(String JavaDoc descr, String JavaDoc zipFile, String JavaDoc destDir){
563     if(debug)
564       Ut.infoln("-UNZIP '"+descr+"' "+zipFile+"' in "+destDir);
565     Unzip u=new Unzip(zipFile,destDir);
566     if(console){
567       Ut.info("Unzipping "+zipFile+"->"+destDir+" :");
568       int ret;
569       int sg=5;
570       while((ret=u.chunkuncompress(false,true,true))!=-1){
571         if(ret>=sg){
572           Ut.info(".");
573           sg+=5;
574         }
575       }
576       Ut.infoln("");
577     }
578     else{
579       frame.doUnzip(descr,zipFile,destDir);
580       unzipper=new Unzipper(u);
581       unzipper.start();
582     }
583   }
584
585   private void doInput(String JavaDoc title, String JavaDoc msg, String JavaDoc varName, String JavaDoc defValue){
586     if(debug)
587       Ut.infoln("-INPUT '"+varName+"' default: '"+defValue+"'");
588     if(console){
589       doInputConsole(title,msg,varName);
590       return;
591     }
592     //String val=frame.doInput(title,msg,false);
593
//setVar(varName,val);
594
frame.doInput(title,msg,defValue);
595     //devo leggere il valore dopo
596
inVarName=varName;
597     inputting=true;
598   }
599
600   private void doInputFile(String JavaDoc title, String JavaDoc msg, String JavaDoc varName, String JavaDoc defValue){
601     if(debug)
602       Ut.infoln("-INPUT FILE'"+varName+"'");
603     if(console){
604       doInputConsole(title,msg,varName);
605       return;
606     }
607     frame.doInputFile(title,msg,defValue,true);
608     //devo leggere il valore dopo
609
inVarName=varName;
610     inputting=true;
611   }
612   private void doInputDir(String JavaDoc title, String JavaDoc msg, String JavaDoc varName, String JavaDoc defValue){
613     if(debug)
614       Ut.infoln("-INPUT DIR'"+varName+"'");
615     if(console){
616       doInputConsole(title,msg,varName);
617       return;
618     }
619     frame.doInputFile(title,msg,defValue,false);
620     //devo leggere il valore dopo
621
inVarName=varName;
622     inputting=true;
623   }
624   private void doInputConsole(String JavaDoc title, String JavaDoc msg, String JavaDoc varName){
625     if(debug)
626       Ut.infoln("-INPUT CONSOLE'"+varName+"'");
627     Ut.infoln("#### "+title+" ####");
628     Ut.info(msg+": ");
629     String JavaDoc val=Ut.readStringFromSTDIN();
630     setVar(varName,val);
631     if(debug)
632       Ut.infoln("Read "+varName+"="+getVar(varName));
633   }
634
635     private void doExecJarMethod(String JavaDoc jarFile, String JavaDoc className, String JavaDoc method, String JavaDoc[] params){
636         if(debug)
637       Ut.infoln("-EXEC jarmethod'"+jarFile+"->"+className+"::"+method+"'");
638     doWrite("Executing ....",null,false);
639     if(method==null || method.equals(""))
640       method="main";
641
642     String JavaDoc ret=execJarMethod(jarFile,className,method,params);
643       if(console)
644         Ut.infoln("Ret val is '"+ret+"'");
645       doWrite("Executing command","result:\n"+ret);
646
647   }
648
649   private void doExecJava(String JavaDoc className, String JavaDoc method, String JavaDoc params[]){
650     if(debug)
651       Ut.infoln("-EXEC java'"+className+"::"+method+"'");
652     //exec..
653
// if method==null call the main.. if any..
654
doWrite("Executing ....",null,false);
655     if(method==null || method.equals("")){
656       if(debug)
657         Ut.infoln(" call main!");
658       execJavaMain(className,params);
659       doWrite("Executing internal command","Done.");
660     }
661     else{
662       String JavaDoc ret=execJavaMethod(className,method,params);
663       if(console)
664         Ut.infoln("Ret val is '"+ret+"'");
665       doWrite("Executing internal command","result:\n"+ret);
666     }
667   }
668     /**
669      * Execute a JAr file and displays any Standard output generated by the jar file.
670      * The value containig all the standard output generated by the application
671      * contained in the jar file is displayed.
672      * @param jarFile the name of the jar file. A path relative to MiniInstaller base dir
673      * @param params an array of strings as it is to be passed to the "main" mehtod
674      * of the "Main-Class" of the jar file. The main class is the main class as
675      * specified in the manifest file.
676      * @author Walter Gamba
677      */

678   private void doExecJar(String JavaDoc jarFile, String JavaDoc params[]){
679     if(debug)
680       Ut.infoln("-EXEC jaR'"+jarFile);
681     //exec..
682
// if method==null call the main.. if any..
683
doWrite("Executing JAR ....",null,false);
684     if(debug)
685       Ut.infoln(" call JAR main!");
686     String JavaDoc ret=execJar(jarFile,params);
687         if(ret==null)
688             doWrite("Executing JAR","Done.");
689         else
690       doWrite("Executing JAR","Done. Results follows:\n"+ret);
691   }
692
693   private String JavaDoc execJavaMethod(String JavaDoc className, String JavaDoc method, String JavaDoc args[])
694   {
695     setVar("_","");
696     //
697
//uso introspection
698
Object JavaDoc ret=null;
699     try
700         {
701
702           Class JavaDoc c=ResourceMgr.retrieveClass(className);
703             //Class cl=Class.forName(className);
704
ret=MetaUt.simpleInvokeStaticMethod(c,method,args);
705         }catch(ClassNotFoundException JavaDoc cnfe){
706           Ut.error("Class '"+className+"' not found.");
707           return null;
708         }
709     //convert result to a concatenation of Strings
710
String JavaDoc s= returnValueToString(ret);
711       setVar("_",s);
712       return s;
713     }
714
715   private void execJavaMain(String JavaDoc className, String JavaDoc[] args){
716     //
717
setVar("_","");
718     try
719         {
720             Class JavaDoc cl=Class.forName(className);
721             MetaUt.simpleInvokeStaticMethod(cl,"main",new Object JavaDoc[]{args});
722         }catch(ClassNotFoundException JavaDoc cnfe){
723           Ut.error("Class '"+className+"' not found.");
724         }
725   }
726
727   private String JavaDoc execJar(String JavaDoc jarFile, String JavaDoc[] args)
728   {
729     setVar("_","");//to initialize it :)
730
String JavaDoc ret=null;
731     URL url = null;
732     try {
733       url = MiniInstaller.class.getResource("/"+jarFile);
734     }
735         catch (Exception JavaDoc e) {
736         Ut.error("Invalid URL: " + jarFile);
737         return null;
738     }
739
740     if(debug)
741       Ut.infoln("URL is '"+url+"' from "+jarFile);
742
743     // Create the class loader for the application jar file
744
MetaJarClassLoader cl = new MetaJarClassLoader(jarFile);
745     // Get the application's main class name
746
String JavaDoc name = null;
747     name = cl.getMainClassName();
748     if (name == null) {
749         Ut.error(jarFile+" does not contain a 'Main-Class' manifest attribute");
750         return null;
751     }
752
753     if(debug)
754       Ut.infoln("URL main class is '"+name+"'");
755     // Get arguments for the application
756
// Invoke application's main class
757

758         ByteArrayOutputStream baos1=new ByteArrayOutputStream();
759         ByteArrayOutputStream baos2=new ByteArrayOutputStream();
760         PrintStream stdOut=new PrintStream(baos1,true);
761         PrintStream stdErr=new PrintStream(baos2,true);
762         PrintStream prevStdOut=System.out;
763         PrintStream prevStdErr=System.err;
764
765     try {
766         //Redirect STDERR and STDOUT
767
System.setErr(stdErr);
768         System.setOut(stdOut);
769         cl.invokeClass(name, args );
770         System.setOut(prevStdOut);
771         System.setErr(prevStdErr);
772         //Ut.infoln("Hai ho!!");
773
cl=null;
774         System.gc();
775         ret=baos1.toString();
776         //Ut.infoln("Hai ho2!!"+ret);
777

778     } catch (ClassNotFoundException JavaDoc e) {
779         System.setOut(prevStdOut);
780         System.setErr(prevStdErr);
781         Ut.error("Class not found: " + name);
782     } catch (NoSuchMethodException JavaDoc e) {
783         System.setOut(prevStdOut);
784         System.setErr(prevStdErr);
785         Ut.error("Class does not define a 'main' method: " + name);
786     } catch (InvocationTargetException e) {
787         System.setOut(prevStdOut);
788         System.setErr(prevStdErr);
789         Ut.error("Invoke excpt: "+e);
790         Ut.error("Invoke excpt: "+e.getTargetException());
791     }
792     this.setVar("_",ret);
793     return ret;
794   }
795
796     /**
797      * Execute a static jar Method inside a Jar.
798      * @param jarFile the name of the jar file
799      * @param className the class name. If it is null, it retrieves mainclass as stored
800      * in the manifest file
801      * @param method method name. Cannot be null.
802      * @param args
803      * @return a String containing the return value of he method, as a String
804      */

805   private String JavaDoc execJarMethod(String JavaDoc jarFile, String JavaDoc className, String JavaDoc method, String JavaDoc[] args)
806   {
807     setVar("_","");//to initialize it :)
808

809         URL url = null;
810         try {
811             url = MiniInstaller.class.getResource("/"+jarFile);
812         }
813         catch (Exception JavaDoc e) {
814             Ut.error("Invalid URL: " + jarFile);
815             return null;
816         }
817
818         if(debug)
819             Ut.infoln("URL is '"+url+"' from "+jarFile);
820         // Create the class loader for the application jar file
821

822         MetaJarClassLoader cl = new MetaJarClassLoader(jarFile);
823         // if classname is null, Get the application's main class name
824
String JavaDoc name = null;
825         if(className==null || className.equals(""))
826             name = cl.getMainClassName();
827         else
828             name=className;
829
830         if (name == null || name.equals("")) {
831             Ut.error("Class not specified or "+jarFile+" does not contain a 'Main-Class' manifest attribute");
832             return null;
833         }
834         if(debug)
835             Ut.infoln("URL main class is '"+name+"'");
836
837         String JavaDoc retS;
838         try{
839             Object JavaDoc ret=MetaUt.simpleInvokeStaticMethod(cl.loadClass(name),method,args);
840         cl=null;
841           System.gc();
842           retS=returnValueToString(ret);
843
844           this.setVar("_",retS);
845           return retS;
846         }
847         catch(ClassNotFoundException JavaDoc cnfe){
848             Ut.error("Class '"+name+"' not found in "+jarFile+"");
849             return null;
850         }
851   }
852
853   /**
854    * Transform a return value, be it array or arrays or simple value, to a String
855    * @param ret an Object, this can be an array or not.
856    */

857   private String JavaDoc returnValueToString(Object JavaDoc ret){
858   if(ret==null)
859             return null;
860         else if(ret instanceof String JavaDoc || ret instanceof Boolean JavaDoc || ret instanceof Long JavaDoc ||
861                 ret instanceof Double JavaDoc || ret instanceof Float JavaDoc || ret instanceof Integer JavaDoc){
862
863                   String JavaDoc s=""+ret.toString();
864
865                   return s;
866                 }
867         else if(ret instanceof String JavaDoc[] || ret instanceof Boolean JavaDoc[] || ret instanceof Long JavaDoc[] ||
868                 ret instanceof Float JavaDoc[] || ret instanceof Double JavaDoc[] || ret instanceof Integer JavaDoc[]
869                 || ret instanceof boolean[] || ret instanceof double[] || ret instanceof long[] ||
870                 ret instanceof float[] || ret instanceof int[]) {
871       String JavaDoc vals[]=new String JavaDoc[Array.getLength(ret)];
872       for(int i=0;i<vals.length;i++)
873         vals[i]=Array.get(ret,i).toString();
874       String JavaDoc r="";
875       for(int i=0;i<vals.length;i++)
876       {
877         if(i<vals.length-1)
878           r+=vals[i].toString()+", ";
879         else
880           r+=vals[i].toString()+", ";
881       }
882
883           return r;
884     }
885     return "";
886
887   }
888
889     /**
890      * Does copy of files from srcdir to dest dir givena a simple filename filter.
891      * It simply starts a Copier thread
892      * @param src the src directory
893      * @param filter a msimple filter. FIlters are very simple.. just one single "*"
894      * in the filter. For further details see @see Copier
895      * @param dest the destination directory
896      * @see Copier
897      * @author Walter Gamba
898      */

899   private void doCopy(String JavaDoc src, String JavaDoc filter, String JavaDoc dest){
900     if(debug)
901       Ut.infoln("-COPY "+src+"("+filter+") to "+dest);
902     doWrite("Copying files "+filter+" from "+src+" to "+dest,null,false);
903     if(debug)
904       Ut.infoln(" Copying!");
905         if(console)
906             Ut.infoln(" Starting Copying!");
907         else
908           frame.doUnzip("Copying files "," from "+src," to "+dest);
909         copier=new Copier(src,dest,filter);
910         copier.start();
911  }
912
913  /**
914   * Class that defines a simple filename filter, it is only for files and discards
915     * automatically directories.
916     * THis class handles very simple filters, with at most one wildcard "*", or the special
917     * wildcard "*.*", but it can handle a multiple filter, where several filters are given
918     * in a comma separated list.<BR>
919     * Accepted filters are:<BR>
920     * <UL>
921     * <LI><CODE>*</CODE> or <CODE>*.*</CODE> whicha are synonims: they always match</LI>
922     * <LI>
923     * </UL>
924     * And a list of the above filter.<BR>
925     * Examples are:<BR>
926     * <CODE>"*"</CODE> cahtches all<BR>
927     * <CODE>"pippo"</CODE> cahtches only files named exactly "pippo"<BR>
928     * <CODE>"a*java"</CODE> cahtches all java files starting with a<BR>
929     * <CODE>"a*pippo*java"</CODE> cahtches all java files starting with "a". Multiple
930     * "*" with the interspaced text are treated as a single "*". So this file mask
931     * is in fact equivalent to the one above.<BR>
932     * <CODE>"*.txt,*.java,te*"</CODE> cahtches all text and java source file, and files
933     * starting with "te" string<BR>
934
935   * @author Walter Gamba
936   * @version 1.0
937   */

938   private class MiniFileFilter implements FileFilter
939   {
940     String JavaDoc filter=null;
941     boolean exact=false;
942     boolean all=false;
943     boolean multi=false;
944     String JavaDoc begin="";
945     String JavaDoc end="";
946     MiniFileFilter[] multiFilter=null;
947
948         /**
949          * Constructor. If the given string contains a list of filters it
950          * builds a private list of MiniFileFilter objects, each one
951          * handling just a single filter. This constructor is kinda recursive
952          *
953          * @param filter a filter as a string as specified above.
954          * @author Walter Gamba
955          */

956     MiniFileFilter(String JavaDoc filter){
957       this.filter=filter;
958       if(filter.indexOf(",")!=-1){
959         multi=true;
960         Vector v=new Vector();
961         StringTokenizer st=new StringTokenizer(filter,",");
962           while (st.hasMoreTokens())
963             v.add(new MiniFileFilter(st.nextToken()));
964         multiFilter=new MiniFileFilter[v.size()];
965         System.arraycopy(v.toArray(),0,multiFilter,0,v.size());
966               if(debug)
967                 Ut.infoln("Built MiniFileFilter: ["+filter+"] multi="+multi+", num="+multiFilter.length);
968         return;
969       }
970       if(filter.equals("*.*") || filter.equals("*"))
971         all=true;
972       else if(filter.indexOf("*")==-1)
973         exact=true;
974       else{
975         int a=filter.indexOf("*");
976         begin=filter.substring(0,a);
977         int b=filter.lastIndexOf("*");
978         end=filter.substring(b+1,filter.length());
979       }
980             if(debug)
981                 Ut.infoln("Built MiniFileFilter: ["+filter+"] multi="+multi+", all="+all+
982                     ", exact="+exact+", begin="+begin+", end="+end);
983     }
984
985         public String JavaDoc toString(){
986         if(multi){
987             StringBuffer JavaDoc sb=new StringBuffer JavaDoc("Built MULTI MiniFileFilter:");
988             for(int i=0;i<multiFilter.length;i++)
989                 sb.append("\t[+"+i+"]="+multiFilter[i].toString());
990             return sb.toString();
991         }
992         else
993           return("Built MiniFileFilter: ["+filter+"] multi="+multi+", all="+all+
994                     ", exact="+exact+", begin="+begin+", end="+end);
995         }
996
997         /**
998          * Implementation of accept method of FileFilter interface.
999          * It scans the filter string and compares it with the given filename.
1000         * It discards automatically directories.
1001         * @param file
1002         * @return tru if the given filename matches the filter
1003         */

1004    public boolean accept(File file){
1005    //
1006
if(file.isDirectory())
1007                return false;
1008            String JavaDoc baseName=file.getName();
1009      if(debug)
1010              Ut.infoln("Accepting of '"+file+"'->'"+baseName+"' for "+this.toString());
1011
1012            boolean ret=true;
1013
1014      if(multi){
1015        boolean m=false;
1016        for(int i=0;i<multiFilter.length;i++)
1017          m = m || multiFilter[i].accept(file);
1018        ret=m;
1019      }
1020      else if(all){
1021        ret=true;
1022      }
1023      else if(exact){
1024        ret= baseName.equals(filter);
1025      }
1026      else{
1027        ret= baseName.startsWith(begin) && baseName.endsWith(end);
1028        //Ut.infoln(baseName+"="+begin+"4" +end);
1029
}
1030
1031      if(debug)
1032                Ut.infoln("accepting="+ret);
1033      return ret;
1034    }
1035  }
1036  /**
1037   * methods of flux control
1038   */

1039    private void close(){
1040        if(!isLastStep()){
1041            cleanup();
1042        }
1043    }
1044
1045    private void cleanup(){
1046        if(debug)
1047          Ut.infoln("Cleanup");
1048
1049        //just one of the two can be (should be) running
1050
//at a given time
1051
if(copier!=null && copier.isAlive()){
1052        copier.halt();
1053            //wait that copiers stops..
1054
while(true){
1055                if(copier.isStopped())
1056                    break;
1057            }
1058        }
1059        if(unzipper!=null && unzipper.isAlive()){
1060            unzipper.halt();
1061            //wait that copiers stops..
1062
while(true){
1063                if(unzipper.isStopped())
1064                    break;
1065            }
1066        }
1067        for(int i=0;i<filesWritten.size();i++){
1068            File f=(File)filesWritten.get(i);
1069            try{
1070                if(debug)
1071                Ut.infoln("FILES WRITTEN: "+f.getCanonicalPath());
1072                FilePermission fp=new FilePermission(f.getCanonicalPath(),"delete");
1073                boolean ret=f.delete();
1074                if(debug)
1075                Ut.infoln("Deleted file rs="+ret+", exist="+f.exists());
1076                //boolean ret=f.deleteOnExit();
1077
}catch(IOException ioe){
1078                Ut.error("Unable to get Canonical path of "+f+":"+ioe);
1079            }
1080        }
1081        for(int i=0;i<dirsCreated.size();i++){
1082            File f=(File)dirsCreated.get(i);
1083            try{
1084              if(debug)
1085                Ut.infoln("DIR CREATED: "+f.getCanonicalPath());
1086                f.delete();
1087                f.deleteOnExit();
1088            }catch(IOException ioe){
1089                Ut.error("Unable to get Canonical path of "+f+":"+ioe);
1090            }
1091        }
1092
1093        if(unzipper!=null && unzipper.isAlive())
1094            unzipper.interrupt();
1095    }
1096
1097    /**
1098     * Called as last step. Does cleaning, if necessary, via close() && cleanup()
1099     * and calls any external shell commands..
1100     */

1101  public void exit(){
1102    close();
1103        boolean exec=frame.shouldExecuteShell();
1104        frame.dispose();
1105        if(!console && exec && shellCommand!=null)
1106          executeShellCommand(shellCommand);
1107        System.exit(0);
1108  }
1109
1110  public void back(){
1111    if(debug)
1112      Ut.infoln("go back..");
1113    wait=false;
1114    //Ut.infoln("bck: "+currCommand);
1115
if(inputting){
1116      String JavaDoc val=frame.getInput();
1117      setVar(inVarName,val);
1118      inputting=false;
1119      //set inputted value for further use
1120
//Ut.infoln("Read:"+val);
1121
//Ut.infoln(this.sr.scriptCommands[currCommand].debug());
1122
this.sr.scriptCommands[currCommand].value=val;
1123    }
1124
1125    if(currCommand==1)
1126      return;
1127    else
1128      stepBackExecute(sr);
1129  }
1130
1131    public boolean isLastStep(){
1132        //Ut.infoln(" currCommand >= maxCmds -> "+currCommand+","+maxCmds);
1133
return currCommand >= this.maxCmds-1;
1134    }
1135
1136  public void goOn(){
1137    if(debug)
1138      Ut.infoln("go on..");
1139    wait=false;
1140    if(inputting){
1141      String JavaDoc val=frame.getInput();
1142      setVar(inVarName,val);
1143      inputting=false;
1144      //set inputted value for further use
1145
//Ut.infoln("Read:"+val);
1146
//Ut.infoln(this.sr.scriptCommands[currCommand].debug());
1147
this.sr.scriptCommands[currCommand].value=val;
1148    }
1149    if(currCommand>=maxCmds)
1150      exit();
1151    else
1152      stepExecute(sr);
1153  }
1154
1155    /**
1156     * Executes a shell command.
1157     * @param shellCommand a shell commands.. a string containig the name of the command (process)
1158     * to invoke, and any further parameters.
1159     * It does not wait for the spawned process to exit..
1160     * Callback from InstallFrame
1161     */

1162  private void executeShellCommand(String JavaDoc shellCommand){
1163      try{
1164            if(debug)
1165                Ut.infoln("Executing <"+shellCommand+">");
1166        Process JavaDoc pr=Runtime.getRuntime().exec(shellCommand);
1167
1168      }catch(IOException ioe){
1169          Ut.error("Error executing shell command '"+shellCommand+"':"+ioe);
1170      }
1171  }
1172  /**
1173    meta command for the isntaller found in install.conf
1174  */

1175  private void doSetDims(String JavaDoc x, String JavaDoc y){
1176    try{
1177      int a=Integer.parseInt(x);
1178      int b=Integer.parseInt(y);
1179      setDims(a,b);
1180    }catch(NumberFormatException JavaDoc nfe){
1181      //setDims(InstallFrame.DEF_X,InstallFrame.DEF_Y);
1182
}
1183  }
1184
1185    private void doStepVisible(boolean show){
1186        frame.setStepVisible(show);
1187    }
1188
1189  private void doHide(){
1190    frame.setVisible(false);
1191  }
1192  private void doShow(){
1193
1194        frame.rebuild();
1195
1196    frame.setVisible(true);
1197  }
1198
1199  private void setDims(int x, int y){
1200    frame.updateDims(new Dimension(x,y));
1201    //frame.refresh();
1202
}
1203
1204  public void doSetTitle(String JavaDoc title){
1205    frame.changeTitle(title);
1206    //frame.refresh();
1207
}
1208    /**
1209     * Inner class thath handles copying of a file in a separate thread, notifying
1210     * main class (or user) of its progresses.
1211     * It DOES NOT COPY DIRECTORIES, nor it does recursive copying.
1212     * @author Walter Gamba
1213     * @version 1.0
1214     */

1215private class Copier extends Thread JavaDoc
1216{
1217    //set by external class to tell Copier to stop.
1218
//copier stops some time later asyncronously
1219
private boolean stop;
1220    //set by Copier itself to tell others that it has stopped
1221
private boolean stopped;
1222  private String JavaDoc src,dest,pattern;
1223  /**
1224     * Initlize class
1225     * @param src src Directory
1226     * @param dest destination Director of copy comamnd. If it does not
1227     * exists, Copier tries to create directories
1228     * @param pattern a file filter as defined in MiniFileFilter
1229     * @see MiniFileFilter
1230     * @author Walter Gamba
1231     */

1232    public Copier(String JavaDoc src, String JavaDoc dest, String JavaDoc pattern){
1233        this.src=src;
1234        this.dest=dest;
1235        this.pattern=pattern;
1236  }
1237
1238    public void halt(){
1239        stop=true;
1240    }
1241
1242    public boolean isStopped(){
1243        return stopped;
1244    }
1245    /**
1246     * Does actual copying.
1247     */

1248  public void run(){
1249        stop=false;
1250        stopped=false;
1251    MiniFileFilter mff=new MiniFileFilter(pattern);
1252    File srcFiles=new File(src);
1253    File[] list=srcFiles.listFiles(mff);
1254    //check that dest directory exists..
1255
File destDir=new File(dest);
1256    if(!destDir.exists() ){
1257      //try to create one. If we can't (in DOS, no drive, in unix, no permissions or whatever. alert)
1258
if(!destDir.mkdirs()){
1259                    Ut.infoln("Could not find destination directory, or could not write to it :'"+dest+"'");
1260                  doAlert("Error copying files to: "+dest+"\nperhaps directory does not exist and cannot be created?");
1261                    return ;
1262            }
1263            dirsCreated.add(destDir);
1264    }
1265        //calculate a prior size of every file
1266
long byteSize=0;
1267        for(int i=0;i<list.length;i++){
1268            byteSize+=list[i].length();
1269        }
1270        if(byteSize==0)
1271            byteSize=100; // :)
1272

1273        int threshold=(int)(byteSize/10L);
1274        long lastCount=0;
1275
1276        if(debug)
1277            Ut.infoln("Total size="+byteSize+" thr="+threshold);
1278
1279      boolean error=false;
1280        long count=0;
1281    for(int i=0;i<list.length;i++){
1282            if(stop)
1283                break;
1284      //copy from list[i] to dest.files..
1285
if(debug)
1286        Ut.infoln("copying '"+list[i]+"' to '"+dest+"':");
1287      String JavaDoc baseName=list[i].getName();
1288      File destFile=new File(dest,baseName);
1289      try{
1290                FileInputStream fis=new FileInputStream(list[i]);
1291                FileOutputStream fos=new FileOutputStream(destFile);
1292                int c;
1293                //save file..
1294
filesWritten.add(destFile);
1295                while((c=fis.available())>0){
1296                    c=c>threshold ? threshold : c ;
1297                  byte b[]=new byte[c];
1298                    if(stop)
1299                        break;
1300                    fis.read(b);
1301                //while((c=fis.read())!=-1){
1302
//fos.write(c);
1303
fos.write(b);
1304                    count+=c;
1305                    if(count-lastCount>threshold){
1306                      int pr=(int)((float)count*100.0f/(float)byteSize);
1307                        if(console)
1308                        Ut.info(pr+"% ");
1309                    else
1310                            frame.setProgress(pr);
1311                        lastCount=count;
1312                    }
1313                }
1314                //Ut.infoln("Close files");
1315
fos.close();
1316                fis.close();
1317                if(stop)
1318                    stopped=true;
1319
1320                int pr=(int)((float)count*100.0f/(float)byteSize);
1321                if(debug)
1322                    Ut.infoln("Perc%="+pr);
1323                if(console)
1324                    Ut.info(pr+"% ");
1325                else
1326                  frame.setProgress(pr);
1327      //Ut.info(pr+" ");
1328
}
1329      catch(FileNotFoundException fnfe){
1330        Ut.infoln("Could not find file '"+list[i]+"' or copy it:"+fnfe);
1331                error=true;
1332        break ;
1333      }
1334      catch(IOException ioe){
1335        Ut.infoln("Generic I/O error copying '"+list[i]+"' to '"+destFile+"':"+ioe);
1336        error=true;
1337        break ;
1338      }
1339     }
1340        if(console)
1341            Ut.infoln(".\nDone");
1342        else
1343        frame.setProgress(UNZIP_DONE);
1344
1345      if(error)
1346            doAlert("Error copying files to: "+dest+"\nperhaps directory does not exist, has no permissions?");
1347        return ;
1348  }
1349}
1350
1351    /**
1352     * Simple class that handles unsipping in a separate thread.
1353     * @author Walter Gamba
1354     * @version 1.0
1355     * @see Unzip
1356     */

1357    private class Unzipper extends Thread JavaDoc
1358    {
1359        private Unzip u;
1360
1361        private boolean stop;
1362        private boolean stopped;
1363
1364        public Unzipper(Unzip u){
1365            this.u=u;
1366        }
1367
1368        public boolean isStopped(){
1369            return stopped;
1370        }
1371
1372        public void halt(){
1373            stop=true;
1374        }
1375
1376        /**
1377         * Runs the unzipping.
1378         * It notifies the main frame of the progress.
1379         * WHen unzipping is complete it calls the MiniInstaller.goOn method
1380         * @author Walter Gamba
1381         * @see MiniInstaller#goOn
1382         */

1383        public void run(){
1384            stop=stopped=false;
1385            int ret;
1386            int sg=2;
1387            while((ret=u.chunkuncompress(false,true,true))!=-1){
1388                if(ret>=sg){
1389                    frame.setProgress(ret);
1390                    sg+=2;
1391                }
1392                if(stop)
1393                    break;
1394            }
1395
1396            frame.setProgress(UNZIP_DONE);
1397
1398            //append(u.getCreatedDirsList());
1399
//appendCreatedFiles(u.getCreatedDirsList());
1400
importVector(dirsCreated,u.getCreatedDirsList());
1401            importVector(filesWritten,u.getExtractedFilesList());
1402          stopped=true;
1403            if(console)
1404                Ut.infoln(".\nDone");
1405            else
1406                frame.setProgress(UNZIP_DONE);
1407
1408        }
1409
1410    }
1411//enfd inner
1412

1413    /**
1414     * Adds elements of a vector toanother vector
1415     * @param container the container vector
1416     * @param imported the Vector to import into the container
1417     */

1418    private void importVector(Vector container, Vector imported){
1419        for(int i=0;i<imported.size();i++)
1420            container.add(imported.get(i));
1421    }
1422  public void executeShellOnExit(boolean execute) {
1423    /**@todo: Implement this net.yagga.miniinstaller.gui.FinalExecuter method*/
1424    throw new java.lang.UnsupportedOperationException JavaDoc("Method executeShellOnExit() not yet implemented.");
1425  }
1426}
Popular Tags