You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Main.java 54KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886
  1. /* *******************************************************************
  2. * Copyright (c) 2000-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v 2.0
  7. * which accompanies this distribution and is available at
  8. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package $installer$.org.aspectj;
  14. import java.awt.BorderLayout;
  15. import java.awt.Component;
  16. import java.awt.Dimension;
  17. import java.awt.FlowLayout;
  18. import java.awt.Font;
  19. import java.awt.GridBagConstraints;
  20. import java.awt.GridBagLayout;
  21. import java.awt.Toolkit;
  22. import java.awt.event.ActionEvent;
  23. import java.awt.event.ActionListener;
  24. import java.awt.event.WindowAdapter;
  25. import java.awt.event.WindowEvent;
  26. import java.awt.event.WindowListener;
  27. import java.io.BufferedOutputStream;
  28. import java.io.BufferedReader;
  29. import java.io.BufferedWriter;
  30. import java.io.File;
  31. import java.io.FileInputStream;
  32. import java.io.FileOutputStream;
  33. import java.io.FileWriter;
  34. import java.io.IOException;
  35. import java.io.InputStream;
  36. import java.io.InputStreamReader;
  37. import java.io.OutputStream;
  38. import java.io.PrintStream;
  39. import java.lang.reflect.InvocationTargetException;
  40. import java.net.JarURLConnection;
  41. import java.net.URL;
  42. import java.util.Enumeration;
  43. import java.util.Map;
  44. import java.util.Properties;
  45. import java.util.jar.JarEntry;
  46. import java.util.jar.JarFile;
  47. import java.util.zip.ZipEntry;
  48. import java.util.zip.ZipInputStream;
  49. import javax.swing.BorderFactory;
  50. import javax.swing.BoxLayout;
  51. import javax.swing.Icon;
  52. import javax.swing.JButton;
  53. import javax.swing.JEditorPane;
  54. import javax.swing.JFileChooser;
  55. import javax.swing.JFrame;
  56. import javax.swing.JLabel;
  57. import javax.swing.JOptionPane;
  58. import javax.swing.JPanel;
  59. import javax.swing.JProgressBar;
  60. import javax.swing.JTextArea;
  61. import javax.swing.JTextField;
  62. import javax.swing.SwingUtilities;
  63. import javax.swing.border.Border;
  64. import javax.swing.border.CompoundBorder;
  65. import javax.swing.border.EmptyBorder;
  66. /**
  67. * Invoke the Installer gui. There are two ways to run without GUI by passing parameters to main:
  68. * <ol>
  69. * <li>pass <code>-text {pathToPropertiesFile}</code>:
  70. * <ul>
  71. * <li>"-text".equals(arg[0])</li>
  72. * <li>arg[1] is the path to a properties file which defines name="output.dir" value="{path to output dir}" name="context.javaPath"
  73. * value="{path to JDKDIR}", i.e,.
  74. *
  75. * <pre>
  76. * output.dir=c:/latest
  77. * "context.javaPath=c:/apps/jdk1.3.1
  78. * </pre>
  79. *
  80. * </li>
  81. * <li>outputDir must be created and empty (i.e., no overwriting</li>
  82. * <li>the VM being invoked should be the target vm</li>
  83. * </ul>
  84. * </li>
  85. * <li>pass <code>-to {pathToTargetDir}</code>:
  86. * <ul>
  87. * <li>"-to".equals(arg[0])</li>
  88. * <li>arg[1] is the path to a writable install directory.</li>
  89. * </ul>
  90. * </li>
  91. */
  92. public class Main {
  93. public static void main(String[] args) {
  94. Options.loadArgs(args);
  95. boolean hasGui = true;
  96. Properties properties = new Properties();
  97. InputStream istream = null;
  98. try {
  99. istream = Main.class.getResourceAsStream(Installer.RESOURCE_DIR + "/properties.txt");
  100. if (istream == null) {
  101. System.err.println("unable to load properties.txt using Main.class - exiting");
  102. Main.exit(-1);
  103. }
  104. properties.load(istream);
  105. // when running outside GUI, load values into properties
  106. // so that property-value resolution works
  107. // (otherwise, could just set values below).
  108. // XXX not sure if this indirection is actually needed.
  109. if (null != Options.textProperties) {
  110. istream.close();
  111. istream = new FileInputStream(Options.textProperties);
  112. properties.load(istream);
  113. hasGui = false;
  114. } else if (null != Options.targetDir) {
  115. String path = null;
  116. try {
  117. path = Options.targetDir.getCanonicalPath();
  118. } catch (IOException e) {
  119. path = Options.targetDir.getAbsolutePath();
  120. }
  121. String javaPath = ConfigureLauncherPane.getDefaultJavaHomeLocation();
  122. if (null == javaPath) {
  123. System.err.println("using GUI - unable to find java");
  124. } else {
  125. properties.setProperty("output.dir", path);
  126. properties.setProperty("context.javaPath", javaPath);
  127. hasGui = false;
  128. }
  129. }
  130. } catch (IOException ioe) {
  131. handleException(ioe);
  132. } finally {
  133. if (null != istream) {
  134. try {
  135. istream.close();
  136. } catch (IOException e) {
  137. } // ignore
  138. }
  139. }
  140. try {
  141. String className = (String) properties.get("installer.main.class");
  142. //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  143. Installer installer = (Installer) Class.forName(className).getDeclaredConstructor().newInstance();
  144. InstallContext installerContext = new InstallContext(properties);
  145. installerContext.setHasGui(hasGui);
  146. installer.setContext(installerContext);
  147. if (installerContext.hasGui()) { // let context force whether or not to run gui
  148. installer.runGUI();
  149. } else {
  150. // set output dir and java path in context after minimal validation
  151. String propName = "output.dir";
  152. String propValue = properties.getProperty(propName);
  153. if (null == propValue) {
  154. throw new Exception("expecting property " + propName);
  155. }
  156. String outputDirName = propValue;
  157. propName = "context.javaPath";
  158. propValue = properties.getProperty(propName);
  159. if (null == propValue) {
  160. throw new Exception("expecting property " + propName);
  161. }
  162. String javaPath = propValue;
  163. File outputDir = new File(outputDirName);
  164. if (!outputDir.isDirectory()) {
  165. throw new Exception("not a dir outputDirName: " + outputDirName + " dir: " + outputDir);
  166. }
  167. if (!outputDir.canWrite()) {
  168. throw new Exception("cannot write outputDirName: " + outputDirName + " dir: " + outputDir);
  169. }
  170. InstallContext context = installer.getContext(); // todo: why not use installerContext?
  171. context.setOutputDir(outputDir);
  172. context.javaPath = new File(javaPath);
  173. // todo: check javaPath for ... bin/java? lib/rt.jar?
  174. if (!outputDir.isDirectory() || !outputDir.canRead()) {
  175. throw new Exception("invalid javaPath: " + javaPath);
  176. }
  177. // directly set context and run
  178. WizardPane.setContext(installerContext);
  179. installer.run();
  180. }
  181. } catch (Exception e) {
  182. handleException(e);
  183. }
  184. }
  185. public static void handleException(Throwable e) {
  186. System.out.println("internal error: " + e.toString());
  187. e.printStackTrace();
  188. Main.exit(-1);
  189. }
  190. /** indirection for System.exit - todo apply cleanup here as necessary */
  191. public static void exit(int value) {
  192. System.exit(value);
  193. }
  194. } // class Main
  195. class Options {
  196. public static boolean verbose = false;
  197. public static String textProperties = null;
  198. public static File targetDir = null;
  199. public static boolean forceError1 = false;
  200. public static boolean forceError2 = false;
  201. public static boolean forceHandConfigure = false;
  202. public static void loadArgs(String[] args) {
  203. if (args == null) {
  204. return;
  205. }
  206. for (int i = 0; i < args.length; i++) {
  207. String arg = args[i];
  208. if (arg == null) {
  209. continue;
  210. }
  211. if (arg.equals("-verbose")) {
  212. verbose = true;
  213. } else if (arg.equals("-forceError1")) {
  214. forceError1 = true;
  215. } else if (arg.equals("-forceError2")) {
  216. forceError2 = true;
  217. } else if (arg.equals("-forceHandConfigure")) {
  218. forceHandConfigure = true;
  219. } else if (arg.equals("-text")) {
  220. if (i + 1 < args.length) {
  221. textProperties = args[++i];
  222. }
  223. } else if (arg.equals("-to")) {
  224. String next = "no argument";
  225. if (i + 1 < args.length) {
  226. next = args[++i];
  227. File targDir = new File(next);
  228. if (targDir.isDirectory() && targDir.canWrite()) {
  229. targetDir = targDir;
  230. }
  231. }
  232. if (null == targetDir) {
  233. System.err.println("invalid -to dir: " + next);
  234. }
  235. }
  236. }
  237. }
  238. }
  239. /** tools installer installs the entire 1.1+ distribution */
  240. class ToolsInstaller extends Installer {
  241. public String getTitle() {
  242. return "Installer for AspectJ(TM)";
  243. }
  244. public String getPrefix() {
  245. return "tools";
  246. }
  247. public String getReadmeFilename() {
  248. return "README-AspectJ.html";
  249. }
  250. public ToolsInstaller() {
  251. InstallPane installPane = new InstallPane(true);
  252. setInstallPane(installPane);
  253. panes = new WizardPane[] { new IntroPane(), new ConfigureLauncherPane(), new LocationPane(), installPane, new FinishPane() };
  254. }
  255. }
  256. class DocsInstaller extends Installer {
  257. public String getTitle() {
  258. return "AspectJ(TM) Documentation and Examples Installer";
  259. }
  260. public String getPrefix() {
  261. return "docs";
  262. }
  263. public DocsInstaller() {
  264. InstallPane installPane = new InstallPane(false);
  265. setInstallPane(installPane);
  266. panes = new WizardPane[] { new IntroPane(), new LocationPane(), installPane, new FinishPane() };
  267. }
  268. }
  269. class AJDEForJBuilderInstaller extends Installer {
  270. public String getTitle() {
  271. return "AspectJ(TM) Support for JBuilder";
  272. }
  273. public String getPrefix() {
  274. return "ajdeForJBuilder";
  275. }
  276. public AJDEForJBuilderInstaller() {
  277. InstallPane installPane = new InstallPane(false);
  278. setInstallPane(installPane);
  279. panes = new WizardPane[] { new IntroPane(), new LocationPane() {
  280. public String getDefaultLocation() {
  281. if (context.onWindows()) {
  282. // check some default locations
  283. String[] paths = { "c:\\JBuilder6\\lib\\ext", "c:\\apps\\JBuilder6\\lib\\ext",
  284. "c:\\Program Files\\JBuilder6\\lib\\ext" };
  285. int pathIndex = 0;
  286. for (; pathIndex < paths.length; pathIndex++) {
  287. if (new File(paths[pathIndex]).exists()) {
  288. return paths[pathIndex];
  289. }
  290. }
  291. return "c:\\JBuilder6\\lib\\ext";
  292. } else {
  293. return "/usr/JBuilder6/lib/ext";
  294. }
  295. }
  296. /**
  297. * Make sure that the old jar file gets removed.
  298. */
  299. public void verify() {
  300. File jbuilder = new File(location.getText() + "/../../lib/jbuilder.jar");
  301. if (!jbuilder.exists() && hasGui()) {
  302. int ret = JOptionPane.showConfirmDialog(frame, "The location you specified does not seem to be a "
  303. + "valid JBuilder install directory." + " Continue?", "Confirm Install", JOptionPane.YES_NO_OPTION,
  304. JOptionPane.QUESTION_MESSAGE);
  305. if (ret != JOptionPane.YES_OPTION) {
  306. Main.exit(-1);
  307. } else {
  308. // do nothing
  309. }
  310. }
  311. File oldFile = new File(location.getText() + "/ajbuilder.jar");
  312. if (oldFile.exists() && hasGui()) {
  313. int ret = JOptionPane.showConfirmDialog(frame,
  314. "This old version of AJDE for JBuilder (\"ajbuilder.jar\") exists"
  315. + " and must be removed from the install directory." + " OK to delete?", "Confirm Delete",
  316. JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
  317. if (ret != JOptionPane.YES_OPTION) {
  318. Main.exit(-1);
  319. } else {
  320. oldFile.delete();
  321. }
  322. }
  323. }
  324. }, installPane, new FinishPane() };
  325. }
  326. }
  327. class AJDEForForteInstaller extends Installer {
  328. public String getTitle() {
  329. return "AspectJ(TM) Support for Forte 4J";
  330. }
  331. public String getPrefix() {
  332. return "ajdeForForte";
  333. }
  334. private String installLoc = "";
  335. public AJDEForForteInstaller() {
  336. InstallPane installPane = new InstallPane(false);
  337. setInstallPane(installPane);
  338. panes = new WizardPane[] { new IntroPane(), new LocationPane() {
  339. public String getDefaultLocation() {
  340. if (context.onWindows()) {
  341. // check some default locations
  342. String[] paths = { "c:\\forte4j\\modules", "c:\\apps\\forte4j\\modules", "c:\\Program Files\\forte4j\\modules" };
  343. int pathIndex = 0;
  344. for (; pathIndex < paths.length; pathIndex++) {
  345. if (new File(paths[pathIndex]).exists()) {
  346. return paths[pathIndex];
  347. }
  348. }
  349. return "c:\\forte4j\\modules";
  350. } else {
  351. return "/usr/forte4j/modules";
  352. }
  353. }
  354. public void verify() {
  355. File forte = new File(location.getText() + "/../lib/openide.jar");
  356. installLoc = location.getText();
  357. if (!forte.exists() && hasGui()) {
  358. int ret = JOptionPane.showConfirmDialog(frame, "The location you specified does not seem to be a "
  359. + "valid Forte install directory." + " Continue?", "Confirm Install", JOptionPane.YES_NO_OPTION,
  360. JOptionPane.QUESTION_MESSAGE);
  361. if (ret != JOptionPane.YES_OPTION) {
  362. Main.exit(-1);
  363. } else {
  364. // do nothing
  365. }
  366. }
  367. }
  368. }, installPane, new FinishPane() {
  369. public void finalActions() { // todo verify dir ../lib/ext exists?
  370. // !!! this should be done with two install locations, not by moving a file
  371. new File(installLoc + "/../lib/ext/aspectjrt.jar").delete();
  372. new File(installLoc + "/aspectjrt.jar").renameTo(new File((installLoc + "/../lib/ext/aspectjrt.jar")));
  373. new File(installLoc + "/aspectjrt.jar").delete();
  374. }
  375. } };
  376. }
  377. }
  378. class SrcInstaller extends Installer {
  379. public String getTitle() {
  380. return "AspectJ(TM) Compiler and Core Tools Sources Installer";
  381. }
  382. public String getPrefix() {
  383. return "sources";
  384. }
  385. public SrcInstaller() {
  386. InstallPane installPane = new InstallPane(false);
  387. setInstallPane(installPane);
  388. panes = new WizardPane[] { new IntroPane(), new LocationPane(), installPane, new FinishPane() };
  389. }
  390. }
  391. abstract class Installer {
  392. static final String EXIT_MESSAGE = "Are you sure you want to cancel the installation?";
  393. static final String EXIT_TITLE = "Exiting installer";
  394. /**
  395. * relative directory in jar from package $installer$.org.aspectj for loading resources - todo must be tracked during build
  396. */
  397. public static final String RESOURCE_DIR = "resources";
  398. JFrame frame;
  399. InstallContext context;
  400. /** special pane that actually does the installation */
  401. InstallPane installPane;
  402. public Installer() {
  403. }
  404. protected void setInstallPane(InstallPane installPane) {
  405. this.installPane = installPane;
  406. }
  407. public InstallPane getInstallPane() {
  408. return installPane;
  409. }
  410. /** directly run the install pane, if any */
  411. public void run() {
  412. if (null != installPane) {
  413. installPane.run();
  414. }
  415. }
  416. public abstract String getPrefix();
  417. public String getReadmeFilename() {
  418. return "README-" + getPrefix().toUpperCase() + ".html";
  419. }
  420. public void setContext(InstallContext context) {
  421. this.context = context;
  422. context.installer = this;
  423. }
  424. public InstallContext getContext() {
  425. return context;
  426. }
  427. public String getTitle() {
  428. return "AspectJ(TM) Installer";
  429. }
  430. public int getWidth() {
  431. return 640;
  432. }
  433. public int getHeight() {
  434. return 460;
  435. }
  436. protected WizardPane[] panes = new WizardPane[0];
  437. public WizardPane[] getPanes() {
  438. return panes;
  439. }
  440. public int findPaneIndex(WizardPane pane) {
  441. for (int i = 0; i < panes.length; i++) {
  442. if (panes[i] == pane) {
  443. return i;
  444. }
  445. }
  446. return -1;
  447. }
  448. Component header, footer, body;
  449. public void runGUI() {
  450. frame = new JFrame(getTitle());
  451. WindowListener wl = new WindowAdapter() {
  452. public void windowClosing(WindowEvent arg0) {
  453. Main.exit(-1); // -1 unless exiting through done button
  454. }
  455. };
  456. frame.addWindowListener(wl);
  457. if (Options.forceError1) {
  458. throw new RuntimeException("forced error1 for testing purposes");
  459. }
  460. Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
  461. int x = (int) (size.getWidth() - getWidth()) / 2;
  462. int y = (int) (size.getHeight() - getHeight()) / 2;
  463. //include a few sanity checks on starting position
  464. if (x < 0) {
  465. x = 0;
  466. }
  467. if (x > 600) {
  468. x = 600;
  469. }
  470. if (y < 0) {
  471. y = 0;
  472. }
  473. if (y > 400) {
  474. y = 400;
  475. }
  476. frame.setLocation(x, y);
  477. frame.setSize(getWidth(), getHeight());
  478. moveToPane(getPanes()[0]);
  479. frame.setVisible(true);
  480. }
  481. public void moveToPane(WizardPane pane) {
  482. WizardPane.setContext(this.context);
  483. Dimension size = frame.getContentPane().getSize();
  484. JPanel contents = new JPanel();
  485. contents.setLayout(new BorderLayout());
  486. header = makeHeader();
  487. contents.add(header, BorderLayout.NORTH);
  488. body = pane.getPanel();
  489. contents.add(body, BorderLayout.CENTER);
  490. footer = pane.getButtons();
  491. contents.add(footer, BorderLayout.SOUTH);
  492. contents.revalidate();
  493. contents.setSize(size);
  494. frame.setContentPane(contents);
  495. //XXX deal with threading here?
  496. pane.run();
  497. }
  498. public Icon loadImage(String name) {
  499. return new javax.swing.ImageIcon(this.getClass().getResource(name));
  500. }
  501. public Component makeHeader() {
  502. return new JLabel(loadImage(Installer.RESOURCE_DIR + "/aspectjBanner.gif"));
  503. }
  504. public ActionListener makeNextAction(final WizardPane pane) {
  505. int nextPaneIndex = findPaneIndex(pane) + 1;
  506. if (nextPaneIndex >= getPanes().length) {
  507. return null;
  508. }
  509. final WizardPane nextPane = getPanes()[nextPaneIndex];
  510. return new ActionListener() {
  511. public void actionPerformed(ActionEvent e) {
  512. pane.finish();
  513. moveToPane(nextPane);
  514. }
  515. };
  516. }
  517. public ActionListener makeBackAction(final WizardPane pane) {
  518. int nextPaneIndex = findPaneIndex(pane) - 1;
  519. if (nextPaneIndex < 0) {
  520. return null;
  521. }
  522. final WizardPane nextPane = getPanes()[nextPaneIndex];
  523. return new ActionListener() {
  524. public void actionPerformed(ActionEvent e) {
  525. moveToPane(nextPane);
  526. }
  527. };
  528. }
  529. public ActionListener makeCancelAction(WizardPane pane) {
  530. return new ActionListener() {
  531. public void actionPerformed(ActionEvent e) {
  532. int ret = JOptionPane.showConfirmDialog(frame, EXIT_MESSAGE, EXIT_TITLE, JOptionPane.YES_NO_OPTION,
  533. JOptionPane.QUESTION_MESSAGE);
  534. if (ret == JOptionPane.YES_OPTION) {
  535. Main.exit(-1);
  536. }
  537. }
  538. };
  539. }
  540. public ActionListener makeFinishAction(WizardPane pane) {
  541. return new ActionListener() {
  542. public void actionPerformed(ActionEvent e) {
  543. Main.exit(0);
  544. }
  545. };
  546. }
  547. }
  548. // willing to go up to 3 levels deep to find either jre or jdk
  549. // jre\[*\]lib\ext
  550. // jdk*\lib\tools.jar
  551. /*****
  552. * final static int MAX_DEPTH = 4; public static void findPaths(String prefix, File currentDir, int currentDepth) { if (currentDepth
  553. * > MAX_DEPTH) return; if (!currentDir.exists() || !currentDir.isDirectory()) return; File [] files = currentDir.listFiles(); if
  554. * (files == null) return; for (int i=0; i<files.length; i++) { if (files[i] == null) continue; if (!files[i].isDirectory())
  555. * continue; if (files[i].getName().startsWith(prefix)) { System.out.println("found: " + files[i]); } else { findPaths(prefix,
  556. * files[i], currentDepth + 1); } } }
  557. *
  558. * public static void findPaths(String prefix) { File [] files = File.listRoots(); for (int i=1; i<files.length; i++) { if
  559. * (!files[i].isDirectory()) continue; if (files[i].getName().toLowerCase().startsWith(prefix)) { System.out.println("found: " +
  560. * files[i]); } else { findPaths(prefix, files[i], 1); } } }
  561. *****/
  562. class InstallContext {
  563. public InstallContext(Map properties) {
  564. this.properties = properties;
  565. properties.put("user.home", System.getProperty("user.home"));
  566. //System.out.println("new install context");
  567. }
  568. private File outputDir;
  569. public void setOutputDir(File outputDir) {
  570. this.outputDir = outputDir;
  571. properties.put("installer.output.dir", outputDir.getAbsolutePath());
  572. properties.put("installer.output.dir.bin", new File(outputDir, "bin").getAbsolutePath());
  573. properties.put("installer.output.dir.doc", new File(outputDir, "doc").getAbsolutePath());
  574. properties.put("installer.output.aspectjrt", new File(new File(outputDir, "lib"), "aspectjrt.jar").getAbsolutePath());
  575. properties.put("installer.output.readme", new File(outputDir, installer.getReadmeFilename()).getAbsolutePath());
  576. }
  577. public File getOutputDir() {
  578. return outputDir;
  579. }
  580. private boolean hasGui;
  581. public File javaPath;
  582. public File toolsJarPath;
  583. public Installer installer;
  584. private Map<String,String> properties;
  585. public boolean hasGui() {
  586. return hasGui;
  587. }
  588. public void setHasGui(boolean hasGui) {
  589. if (this.hasGui != hasGui) {
  590. this.hasGui = hasGui;
  591. }
  592. }
  593. public Font getFont() {
  594. return new Font("Serif", Font.PLAIN, 14);
  595. }
  596. public String getOS() {
  597. return System.getProperty("os.name");
  598. }
  599. public boolean onOS2() {
  600. return getOS().equals("OS2") || getOS().equals("OS/2");
  601. }
  602. public boolean onWindows() {
  603. return getOS().startsWith("Windows") || onOS2();
  604. }
  605. public boolean onWindowsPro() {
  606. // TODO: Think about a more future-proof solution also checking 'os.version' system property. See also this table:
  607. // https://github.com/openjdk/jdk/blob/9604ee82690f89320614b37bfef4178abc869777/src/java.base/windows/native/libjava/java_props_md.c#L446
  608. // Alternatively, explicitly exclude unsupported versions because those won't change in the future.
  609. return getOS().matches("^Windows (NT|2000|XP|Vista|Server|7|8|10).*");
  610. }
  611. public boolean onMacintosh() {
  612. return getOS().startsWith("Mac");
  613. }
  614. public boolean onUnix() {
  615. return !onWindows();
  616. }
  617. static final String[] TEXT_EXTENSIONS = { ".txt", ".text", ".htm", ".html", ".java", ".ajava", "README", ".lst" };
  618. public boolean isTextFile(File file) {
  619. String name = file.getName();
  620. for (String textExtension : TEXT_EXTENSIONS) {
  621. if (name.endsWith(textExtension)) {
  622. return true;
  623. }
  624. }
  625. return false;
  626. }
  627. public void handleException(Throwable e) {
  628. System.out.println("internal error: " + e.toString());
  629. e.printStackTrace();
  630. if (hasGui()) {
  631. JOptionPane.showMessageDialog(installer.frame, e.toString(), "Unexpected Exception", JOptionPane.ERROR_MESSAGE);
  632. }
  633. }
  634. final static String OVERWRITE_MESSAGE = "Overwrite file ";
  635. final static String OVERWRITE_TITLE = "Overwrite?";
  636. final static String[] OVERWRITE_OPTIONS = { "Yes", "No", "Yes to all" //, "No to all"
  637. };
  638. final static int OVERWRITE_YES = 0;
  639. final static int OVERWRITE_NO = 1;
  640. final static int OVERWRITE_ALL = 2;
  641. //final static int OVERWRITE_NONE = 3;
  642. int overwriteState = OVERWRITE_NO;
  643. boolean shouldOverwrite(final File file) {
  644. //System.out.println("overwrite: " + file + " state " + overwriteState);
  645. if (overwriteState == OVERWRITE_ALL) {
  646. return true;
  647. //if (overwriteState == OVERWRITE_NONE) return false;
  648. }
  649. try {
  650. SwingUtilities.invokeAndWait(new Runnable() {
  651. public void run() {
  652. int ret = JOptionPane.showOptionDialog(installer.frame, OVERWRITE_MESSAGE + file.getPath(), OVERWRITE_TITLE,
  653. JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, OVERWRITE_OPTIONS,
  654. OVERWRITE_OPTIONS[OVERWRITE_YES]);
  655. overwriteState = ret;
  656. }
  657. });
  658. } catch (InvocationTargetException ite) {
  659. handleException(ite.getTargetException());
  660. } catch (InterruptedException ie) {
  661. }
  662. return overwriteState == OVERWRITE_YES || overwriteState == OVERWRITE_ALL;
  663. }
  664. public Map<String,String> getProperties() {
  665. return properties;
  666. }
  667. }
  668. abstract class WizardPane {
  669. static InstallContext context;
  670. protected JButton backButton = null;
  671. protected JButton nextButton = null;
  672. protected JButton cancelButton = null;
  673. public static void setContext(InstallContext con) {
  674. context = con;
  675. }
  676. public abstract JPanel makePanel();
  677. protected JTextArea makeTextArea(String data) {
  678. JTextArea text = new JTextArea(data);
  679. text.setOpaque(false);
  680. text.setFont(context.getFont());
  681. text.setEditable(false);
  682. return text;
  683. }
  684. /** @return false only if there is an InstallContext saying there is no GUI */
  685. protected boolean hasGui() {
  686. final InstallContext icontext = context;
  687. return ((null == icontext) || icontext.hasGui());
  688. }
  689. public static String stringFromStream(InputStream stream) throws IOException {
  690. BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "US-ASCII"));
  691. StringBuilder ret = new StringBuilder();
  692. int data;
  693. while ((data = reader.read()) != -1) {
  694. ret.append((char) data);
  695. }
  696. return ret.toString();
  697. }
  698. public static String removeHead(String text) {
  699. int startIndex = text.indexOf("<head>");
  700. int stopIndex = text.indexOf("</head>");
  701. if (startIndex == -1 || stopIndex == -1) {
  702. return text;
  703. }
  704. stopIndex += 7;
  705. return text.substring(0, startIndex) + text.substring(stopIndex);
  706. }
  707. static String styleHeader = "<head></head>";/*
  708. * <STYLE TYPE=\"text/css\"><!--\n" + " h2 {\n" + " font-size: x-large;\n" +
  709. * " font-family: Serif;\n" + " font-weight: normal;\n" + " }\n" + " p {\n" +
  710. * " font-family: Serif;\n" + " font-weight: normal;\n" + //" color:black;\n"
  711. * + "}</head>\n";
  712. */
  713. public static String applyProperties(String text, Map<String,String> map) {
  714. // ${name} -> map.get(name).toString()
  715. int lastIndex = 0;
  716. StringBuilder buf = new StringBuilder();
  717. int startIndex;
  718. while ((startIndex = text.indexOf("${", lastIndex)) != -1) {
  719. int endIndex = text.indexOf('}', startIndex);
  720. //XXX internal error here
  721. if (endIndex == -1) {
  722. break;
  723. }
  724. buf.append(text.substring(lastIndex, startIndex));
  725. String key = text.substring(startIndex + 2, endIndex);
  726. lastIndex = endIndex + 1;
  727. Object replaceText = (map == null ? null : map.get(key));
  728. //System.out.println("key: " + key + " -> " + replaceText);
  729. if (replaceText == null) {
  730. replaceText = "NOT_FOUND";
  731. }
  732. buf.append(replaceText.toString());
  733. }
  734. buf.append(text.substring(lastIndex));
  735. return buf.toString();
  736. }
  737. public static String applyProperties(String text) {
  738. return applyProperties(text, (context == null ? null : context.getProperties()));
  739. }
  740. protected String loadText(String filename) {
  741. String fullname = Installer.RESOURCE_DIR + "/" + filename;
  742. //context.installer.getPrefix() + "-" + filename;
  743. try {
  744. String text = stringFromStream(getClass().getResourceAsStream(fullname));
  745. text = styleHeader + removeHead(text);
  746. text = applyProperties(text);
  747. //System.out.println(text);
  748. return text;
  749. } catch (IOException e) {
  750. context.handleException(e);
  751. return "";
  752. }
  753. }
  754. protected JEditorPane makeHTMLArea(String filename) {
  755. JEditorPane editorPane = new JEditorPane("text/html", loadText(filename));
  756. /*
  757. * { public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  758. * RenderingHints.VALUE_ANTIALIAS_ON); super.paint(g2); } };
  759. */
  760. editorPane.setEditable(false);
  761. editorPane.setOpaque(false);
  762. return editorPane;
  763. }
  764. protected void setHTMLArea(JEditorPane pane, String filename) {
  765. pane.setText(loadText(filename));
  766. }
  767. protected JPanel makeLocationBox(String label, JTextField textField, JButton browseButton) {
  768. JPanel box = new JPanel();
  769. box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
  770. textField.setFont(context.getFont());
  771. textField.selectAll();
  772. box.add(textField);
  773. box.add(browseButton);
  774. Border border = BorderFactory.createTitledBorder(label);
  775. final int INSET = 8;
  776. border = new CompoundBorder(border, new EmptyBorder(1, INSET, INSET, INSET));
  777. box.setBorder(border);
  778. return box;
  779. }
  780. private JPanel panel = null;
  781. public JPanel getPanel() {
  782. if (panel == null) {
  783. panel = makePanel();
  784. panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
  785. }
  786. return panel;
  787. }
  788. protected void setListener(JButton button, ActionListener listener) {
  789. if (listener == null) {
  790. button.setEnabled(false);
  791. } else {
  792. button.addActionListener(listener);
  793. }
  794. }
  795. protected Component makeButtons(Installer installer) {
  796. JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  797. backButton = new JButton("Back");
  798. setListener(backButton, installer.makeBackAction(this));
  799. panel.add(backButton);
  800. nextButton = new JButton("Next");
  801. setListener(nextButton, installer.makeNextAction(this));
  802. panel.add(nextButton); //.setDefaultCapable(true);
  803. JLabel space = new JLabel();
  804. space.setPreferredSize(new Dimension(20, 0));
  805. panel.add(space);
  806. cancelButton = new JButton("Cancel");
  807. setListener(cancelButton, installer.makeCancelAction(this));
  808. panel.add(cancelButton);
  809. return panel;
  810. }
  811. private Component buttons = null;
  812. public Component getButtons() {
  813. if (buttons == null) {
  814. buttons = makeButtons(context.installer);
  815. //buttons.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
  816. }
  817. context.installer.frame.getRootPane().setDefaultButton(nextButton);
  818. return buttons;
  819. }
  820. public void finish() {
  821. if (Options.forceError2) {
  822. throw new RuntimeException("forced error2 for testing purposes");
  823. }
  824. }
  825. public void run() {
  826. }
  827. }
  828. class IntroPane extends WizardPane {
  829. public JPanel makePanel() {
  830. Component text = makeHTMLArea("intro.html");
  831. JPanel panel = new JPanel(new BorderLayout());
  832. panel.add(text);
  833. return panel;
  834. }
  835. }
  836. class FinishPane extends WizardPane {
  837. public JPanel makePanel() {
  838. Component text = makeHTMLArea("finish.html");
  839. JPanel panel = new JPanel(new BorderLayout());
  840. panel.add(text);
  841. finalActions();
  842. return panel;
  843. }
  844. public Component makeButtons(Installer installer) {
  845. Component ret = super.makeButtons(installer);
  846. nextButton.setText("Finish");
  847. nextButton.setEnabled(true);
  848. nextButton.addActionListener(installer.makeFinishAction(this));
  849. backButton.setEnabled(false);
  850. cancelButton.setEnabled(false);
  851. return ret;
  852. }
  853. public void finalActions() {
  854. }
  855. }
  856. class LocationPane extends WizardPane implements ActionListener {
  857. //XXX need more sophisticated default location finding
  858. //XXX would like to find the place they last chose...
  859. public String getDefaultLocation() {
  860. if (context.onWindows()) {
  861. return "c:\\aspectj1.9";
  862. } else {
  863. return new File(System.getProperty("user.home"), "aspectj1.9").getAbsolutePath();
  864. }
  865. }
  866. protected JTextField location;
  867. public JPanel makePanel() {
  868. Component text = makeHTMLArea("location.html");
  869. location = new JTextField(getDefaultLocation());
  870. JButton browse = new JButton("Browse...");
  871. browse.addActionListener(this);
  872. JPanel locationBox = makeLocationBox("installation directory", location, browse);
  873. GridBagLayout bag = new GridBagLayout();
  874. GridBagConstraints c = new GridBagConstraints();
  875. JPanel panel = new JPanel(bag);
  876. c.fill = GridBagConstraints.BOTH;
  877. c.weightx = 1.0;
  878. c.gridwidth = GridBagConstraints.REMAINDER;
  879. bag.setConstraints(text, c);
  880. panel.add(text);
  881. c.weighty = 1.0;
  882. c.fill = GridBagConstraints.HORIZONTAL;
  883. c.gridwidth = GridBagConstraints.REMAINDER;
  884. bag.setConstraints(locationBox, c);
  885. panel.add(locationBox);
  886. //XXX set next button to read install
  887. //context.nextButton.setText("Install");
  888. return panel;
  889. }
  890. public Component makeButtons(Installer installer) {
  891. Component ret = super.makeButtons(installer);
  892. nextButton.setText("Install");
  893. return ret;
  894. }
  895. public void actionPerformed(ActionEvent e) {
  896. JFileChooser chooser = new JFileChooser(); // {
  897. // public void approveSelection() {
  898. // System.out.println("approved selection");
  899. // }
  900. //}; //field.getText());
  901. chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
  902. int returnVal = chooser.showDialog(location, "Select");
  903. if (returnVal == JFileChooser.APPROVE_OPTION) {
  904. File file = chooser.getSelectedFile();
  905. if (!file.isDirectory()) {
  906. file = file.getParentFile();
  907. }
  908. String name = file.getPath();
  909. location.setText(name);
  910. location.selectAll();
  911. }
  912. }
  913. /**
  914. * Override to do any additional checks.
  915. */
  916. protected void verify() {
  917. }
  918. public void finish() {
  919. verify();
  920. context.setOutputDir(new File(location.getText()));
  921. }
  922. }
  923. class ConfigureLauncherPane extends WizardPane {
  924. /*
  925. * //XXX check that the returned file is valid public String getDefaultJavaLocation() { String name = "java"; if
  926. * (context.onWindows()) name += ".exe";
  927. *
  928. * if (Options.verbose) { System.out.println("java.home: " + System.getProperty("java.home")); System.out.println(" java: " +
  929. * new File(new File(System.getProperty("java.home"), "bin"), name)); System.out.println(" java: " + new File(new
  930. * File(System.getProperty("java.home"), "bin"), name).getPath()); }
  931. *
  932. * return new File(new File(System.getProperty("java.home"), "bin"), name).getPath(); }
  933. */
  934. public static String getDefaultJavaHomeLocation() {
  935. if (!Options.forceHandConfigure) {
  936. File javaHome = findJavaHome();
  937. if (javaHome != null) {
  938. return javaHome.getPath();
  939. }
  940. }
  941. return null;
  942. }
  943. public void chooseFile(JTextField field) {
  944. JFileChooser chooser = new JFileChooser(); //field.getText());
  945. chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  946. int returnVal = chooser.showDialog(field, "Select");
  947. if (returnVal == JFileChooser.APPROVE_OPTION) {
  948. String name = chooser.getSelectedFile().getPath();
  949. field.setText(name);
  950. field.selectAll();
  951. }
  952. }
  953. public ActionListener makeJavaLocationBrowseListener() {
  954. return new ActionListener() {
  955. public void actionPerformed(ActionEvent e) {
  956. chooseFile(javaLocation);
  957. }
  958. };
  959. }
  960. // public ActionListener makeToolsJarLocationBrowseListener() {
  961. // return new ActionListener() {
  962. // public void actionPerformed(ActionEvent e) {
  963. // chooseFile(toolsJarLocation);
  964. // }
  965. // };
  966. // }
  967. private JTextField javaLocation;
  968. //private JTextField toolsJarLocation;
  969. public JPanel makePanel() {
  970. String javaPath = getDefaultJavaHomeLocation();
  971. //String toolsJarPath = getDefaultToolsJarLocation();
  972. Component text;
  973. if (javaPath == null) {
  974. javaPath = "<java home not found>";
  975. text = makeHTMLArea("configure-hand.html");
  976. } else {
  977. text = makeHTMLArea("configure-auto.html");
  978. }
  979. javaLocation = new JTextField(javaPath);
  980. JButton javaLocationBrowse = new JButton("Browse...");
  981. javaLocationBrowse.addActionListener(makeJavaLocationBrowseListener());
  982. JPanel javaLocationBox = makeLocationBox("java home directory", javaLocation, javaLocationBrowse);
  983. // toolsJarLocation = new JTextField(toolsJarPath);
  984. // JButton toolsJarLocationBrowse = new JButton("Browse...");
  985. // toolsJarLocationBrowse.addActionListener(makeToolsJarLocationBrowseListener());
  986. // JPanel toolsJarLocationBox = makeLocationBox("full path to tools.jar", toolsJarLocation, toolsJarLocationBrowse);
  987. GridBagLayout bag = new GridBagLayout();
  988. GridBagConstraints c = new GridBagConstraints();
  989. JPanel panel = new JPanel(bag);
  990. c.fill = GridBagConstraints.BOTH;
  991. c.weightx = 1.0;
  992. c.weighty = 1.0;
  993. //c.ipady = 10;
  994. c.gridwidth = GridBagConstraints.REMAINDER;
  995. bag.setConstraints(text, c);
  996. panel.add(text);
  997. c.weighty = 0.0;
  998. //c.fill = GridBagConstraints.VERTICAL;
  999. bag.setConstraints(javaLocationBox, c);
  1000. panel.add(javaLocationBox);
  1001. // c.weighty = 0.25;
  1002. // JLabel space = new JLabel();
  1003. // bag.setConstraints(space, c);
  1004. // panel.add(space);
  1005. // c.weighty = 0.0;
  1006. // bag.setConstraints(toolsJarLocationBox, c);
  1007. // panel.add(toolsJarLocationBox);
  1008. c.weighty = 0.5;
  1009. JLabel space = new JLabel();
  1010. bag.setConstraints(space, c);
  1011. panel.add(space);
  1012. return panel;
  1013. }
  1014. public void finish() {
  1015. context.javaPath = new File(javaLocation.getText());
  1016. // context.toolsJarPath = new File(toolsJarLocation.getText());
  1017. //XXX need much more work on helping the user get these paths right
  1018. // if (context.javaPath.isDirectory()) {
  1019. // context.javaPath = new File(context.javaPath, "java");
  1020. // }
  1021. // if (context.toolsJarPath.isDirectory()) {
  1022. // context.toolsJarPath = new File(context.toolsJarPath, "tools.jar");
  1023. // }
  1024. }
  1025. //XXX add user.home to prefixes in a rational way
  1026. public static final String[] windowsPaths = { "c:\\jdk", "c:\\apps\\jdk", "${user.home}\\jdk" };
  1027. public static final String[] unixPaths = { "/usr/local/bin/jdk", "/usr/bin/jdk", "/usr/bin/jdk", "${user.home}/jdk" };
  1028. public static final String[] suffixes = { "1.3.1", "1.3", "1.2", "13", "12", "2", "", "1.4" };
  1029. public static boolean windows = true;
  1030. public static boolean isLegalJavaHome(File home) {
  1031. File bin = new File(home, "bin");
  1032. return new File(bin, "java").isFile() || new File(bin, "java.exe").isFile();
  1033. }
  1034. public static boolean isLegalJDKHome(File home) {
  1035. File lib = new File(home, "lib");
  1036. return new File(lib, "tools.jar").isFile();
  1037. }
  1038. public static File findJavaHome() {
  1039. String s = System.getProperty("java.home");
  1040. File javaHome = null;
  1041. if (s != null) {
  1042. javaHome = new File(s);
  1043. if (isLegalJDKHome(javaHome)) {
  1044. return javaHome;
  1045. }
  1046. if (isLegalJavaHome(javaHome)) {
  1047. File parent = javaHome.getParentFile();
  1048. if (parent != null && isLegalJDKHome(parent)) {
  1049. return parent;
  1050. }
  1051. }
  1052. }
  1053. String[] paths;
  1054. if (windows) {
  1055. paths = windowsPaths;
  1056. } else {
  1057. paths = unixPaths;
  1058. }
  1059. for (String suffix : suffixes) {
  1060. for (String path : paths) {
  1061. String prefix = path;
  1062. prefix = applyProperties(prefix);
  1063. File test = new File(prefix + suffix);
  1064. if (isLegalJavaHome(test)) {
  1065. if (isLegalJDKHome(test)) {
  1066. return test;
  1067. } else if (javaHome == null) {
  1068. javaHome = test;
  1069. }
  1070. }
  1071. }
  1072. }
  1073. return javaHome;
  1074. }
  1075. }
  1076. class InstallPane extends WizardPane {
  1077. private JProgressBar progressBar;
  1078. private JTextField progressItem;
  1079. private JEditorPane message;
  1080. private boolean makeLaunchScripts = false;
  1081. public InstallPane(boolean makeLaunchScripts) {
  1082. this.makeLaunchScripts = makeLaunchScripts;
  1083. }
  1084. public JPanel makePanel() {
  1085. message = makeHTMLArea("install-start.html");
  1086. progressBar = new JProgressBar();
  1087. progressItem = new JTextField();
  1088. progressItem.setOpaque(false);
  1089. progressItem.setFont(context.getFont());
  1090. progressItem.setEditable(false);
  1091. GridBagLayout bag = new GridBagLayout();
  1092. GridBagConstraints c = new GridBagConstraints();
  1093. JPanel panel = new JPanel(bag);
  1094. c.fill = GridBagConstraints.BOTH;
  1095. c.weightx = 1.0;
  1096. c.weighty = 1.0;
  1097. //c.ipady = 10;
  1098. c.gridwidth = GridBagConstraints.REMAINDER;
  1099. bag.setConstraints(message, c);
  1100. panel.add(message);
  1101. c.weighty = 0.0;
  1102. //c.fill = GridBagConstraints.VERTICAL;
  1103. bag.setConstraints(progressBar, c);
  1104. panel.add(progressBar);
  1105. c.weighty = 0.1;
  1106. JLabel space = new JLabel();
  1107. bag.setConstraints(space, c);
  1108. panel.add(space);
  1109. c.weighty = 0.0;
  1110. bag.setConstraints(progressItem, c);
  1111. panel.add(progressItem);
  1112. c.weighty = 0.5;
  1113. space = new JLabel();
  1114. bag.setConstraints(space, c);
  1115. panel.add(space);
  1116. return panel;
  1117. }
  1118. class InstallRunner implements Runnable {
  1119. public InstallRunner() {
  1120. }
  1121. public void run() {
  1122. try {
  1123. new CurrentJarUnpacker(context, InstallPane.this).unpack(Installer.RESOURCE_DIR + "/contents.txt",
  1124. context.getOutputDir());
  1125. if (makeLaunchScripts) {
  1126. LaunchScriptMaker lsm = new LaunchScriptMaker(context);
  1127. lsm.writeScript("ajc");
  1128. lsm.writeScript("ajdoc");
  1129. //lsm.writeScript("ajdb");
  1130. lsm.writeScript("ajbrowser");
  1131. // Moved to the bin dir in 1.2.1
  1132. // we should now come back and make the generation of this
  1133. // script uniform with those above.
  1134. lsm.writeAJLaunchScript("aj", false);
  1135. lsm.writeAJLaunchScript("aj5", true);
  1136. }
  1137. if (hasGui()) {
  1138. progressBar.setValue(100);
  1139. setHTMLArea(message, "install-finish.html");
  1140. }
  1141. } catch (IOException ioe) {
  1142. context.handleException(ioe);
  1143. }
  1144. if (hasGui()) {
  1145. cancelButton.setEnabled(false);
  1146. nextButton.setEnabled(true);
  1147. }
  1148. }
  1149. }
  1150. public Component makeButtons(Installer installer) {
  1151. Component ret = super.makeButtons(installer);
  1152. //nextButton.setText("Finish");
  1153. nextButton.setEnabled(false);
  1154. //nextButton.addActionListener(installer.makeFinishAction(this));
  1155. backButton.setEnabled(false);
  1156. return ret;
  1157. }
  1158. public void run() {
  1159. Thread thread = new Thread(new InstallRunner());
  1160. thread.start();
  1161. }
  1162. public void progressMessage(final String message) {
  1163. if (!hasGui()) {
  1164. return;
  1165. }
  1166. try {
  1167. //XXX performance tradeoff between invokeAndWait and invokeLater...
  1168. SwingUtilities.invokeAndWait(new Runnable() {
  1169. public void run() {
  1170. progressItem.setText(message);
  1171. }
  1172. });
  1173. } catch (InvocationTargetException ite) {
  1174. context.handleException(ite.getTargetException());
  1175. } catch (InterruptedException ie) {
  1176. }
  1177. }
  1178. int nBytes = 0;
  1179. int bytesWritten = 0;
  1180. public void progressBytesWritten(int bytes) {
  1181. if (!hasGui()) {
  1182. return;
  1183. }
  1184. bytesWritten += bytes;
  1185. final int PCT = (int) (100.0 * bytesWritten / nBytes);
  1186. //System.out.println("bytesWritten: " + bytesWritten);
  1187. try {
  1188. //XXX performance tradeoff between invokeAndWait and invokeLater...
  1189. SwingUtilities.invokeAndWait(new Runnable() {
  1190. public void run() {
  1191. progressBar.setValue(PCT);
  1192. }
  1193. });
  1194. } catch (InvocationTargetException ite) {
  1195. context.handleException(ite.getTargetException());
  1196. } catch (InterruptedException ie) {
  1197. }
  1198. }
  1199. }
  1200. class CurrentJarUnpacker {
  1201. InstallContext context;
  1202. InstallPane installPane;
  1203. public CurrentJarUnpacker(InstallContext context, InstallPane installPane) {
  1204. this.context = context;
  1205. this.installPane = installPane;
  1206. }
  1207. public File makeOutputFile(String name, File outputFile) {
  1208. int index;
  1209. int lastIndex = 0;
  1210. while ((index = name.indexOf('/', lastIndex)) != -1) {
  1211. outputFile = new File(outputFile, name.substring(lastIndex, index));
  1212. lastIndex = index + 1;
  1213. }
  1214. return new File(outputFile, name.substring(lastIndex));
  1215. }
  1216. final static int BUF_SIZE = 4096;
  1217. public void writeStream(InputStream zis, File outputFile) throws IOException {
  1218. if (outputFile.exists()) {
  1219. if (!context.shouldOverwrite(outputFile)) {
  1220. return;
  1221. }
  1222. }
  1223. installPane.progressMessage("writing " + outputFile.getAbsolutePath());
  1224. outputFile.getParentFile().mkdirs();
  1225. if (context.isTextFile(outputFile)) {
  1226. writeTextStream(zis, outputFile);
  1227. } else {
  1228. writeBinaryStream(zis, outputFile);
  1229. }
  1230. }
  1231. public void writeBinaryStream(InputStream zis, File outputFile) throws IOException {
  1232. byte[] buffer = new byte[BUF_SIZE];
  1233. int nRead = 0;
  1234. OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
  1235. while ((nRead = zis.read(buffer)) != -1) {
  1236. os.write(buffer, 0, nRead);
  1237. installPane.progressBytesWritten(nRead);
  1238. }
  1239. os.close();
  1240. }
  1241. public void writeTextStream(InputStream zis, File outputFile) throws IOException {
  1242. BufferedWriter os = new BufferedWriter(new FileWriter(outputFile));
  1243. BufferedReader r = new BufferedReader(new InputStreamReader(zis, "US-ASCII"));
  1244. String l;
  1245. while ((l = r.readLine()) != null) {
  1246. os.write(l);
  1247. os.newLine();
  1248. installPane.progressBytesWritten(l.length() + 1);
  1249. }
  1250. os.close();
  1251. }
  1252. public void writeResource(String name, File outputDir) throws IOException {
  1253. File outputFile = makeOutputFile(name, outputDir);
  1254. //System.out.println("finding name: " + name);
  1255. writeStream(getClass().getResourceAsStream("/" + name), outputFile);
  1256. }
  1257. public void writeResource(JarFile jarFile, JarEntry entry, File outputDir) throws IOException {
  1258. String name = entry.getName().substring(6);
  1259. File outputFile = makeOutputFile(name, outputDir);
  1260. //System.out.println("finding name: " + name);
  1261. // writeStream(getClass().getResourceAsStream("/" + name), outputFile);
  1262. writeStream(jarFile.getInputStream(entry), outputFile);
  1263. }
  1264. public void unpack(String contentsName, File outputDir) throws IOException {
  1265. URL url = getClass().getResource(contentsName);
  1266. // Process everything under 'files/**' copying to the target
  1267. // install directory with 'files/' removed
  1268. JarURLConnection juc = (JarURLConnection) url.openConnection();
  1269. JarFile jf = juc.getJarFile();
  1270. Enumeration<JarEntry> entries = jf.entries();
  1271. while (entries.hasMoreElements()) {
  1272. JarEntry je = entries.nextElement();
  1273. if (je.getName().startsWith("files/") && !je.getName().endsWith("/")) {
  1274. writeResource(jf, je, outputDir);
  1275. }
  1276. }
  1277. // InputStream stream = url.openStream();
  1278. // BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "US-ASCII"));
  1279. // String line = reader.readLine();
  1280. // installPane.nBytes = Integer.parseInt(line);
  1281. //
  1282. // while ((line = reader.readLine()) != null) {
  1283. // writeResource(line, outputDir);
  1284. // }
  1285. installPane.progressMessage("done writing");
  1286. }
  1287. }
  1288. class LaunchScriptMaker {
  1289. static final String toolsPackage = "org.aspectj.tools";
  1290. InstallContext context;
  1291. public LaunchScriptMaker(InstallContext context) {
  1292. this.context = context;
  1293. }
  1294. /**
  1295. *
  1296. */
  1297. public void writeAJLaunchScript(String name, boolean isJava5) throws IOException {
  1298. if (!context.onUnix()) {
  1299. if (context.onOS2()) {
  1300. name += ".cmd";
  1301. } else if (context.onWindows()) {
  1302. name += ".bat";
  1303. }
  1304. }
  1305. File destDir = new File(context.getOutputDir(), "bin");
  1306. destDir.mkdirs();
  1307. File file = new File(destDir, name);
  1308. PrintStream ps = getPrintStream(file);
  1309. writeAJLaunchScriptContent(ps, isJava5);
  1310. ps.close();
  1311. if (context.onUnix()) {
  1312. makeExecutable(file);
  1313. }
  1314. }
  1315. /**
  1316. * @param ps
  1317. */
  1318. private void writeAJLaunchScriptContent(PrintStream ps, boolean isJava5) {
  1319. if (context.onUnix()) {
  1320. writeUnixHeader(ps);
  1321. if (isJava5) {
  1322. writeAJ5UnixLaunchLine(ps);
  1323. } else {
  1324. writeAJUnixLaunchLine(ps);
  1325. }
  1326. } else {
  1327. writeWindowsHeader(ps);
  1328. if (isJava5) {
  1329. writeAJ5WindowsLaunchLine(ps);
  1330. } else {
  1331. writeAJWindowsLaunchLine(ps);
  1332. }
  1333. }
  1334. }
  1335. /**
  1336. * @param ps
  1337. */
  1338. private void writeAJWindowsLaunchLine(PrintStream ps) {
  1339. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " + "\"%ASPECTJ_HOME%\\lib\\aspectjweaver.jar\""
  1340. + " \"-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader\""
  1341. + " \"-Daj.class.path=%ASPECTPATH%;%CLASSPATH%\"" + " \"-Daj.aspect.path=%ASPECTPATH%\"" + " "
  1342. + makeScriptArgs(false));
  1343. }
  1344. /**
  1345. * @param ps
  1346. */
  1347. private void writeAJ5WindowsLaunchLine(PrintStream ps) {
  1348. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " + "\"%ASPECTJ_HOME%\\lib\\aspectjweaver.jar;%CLASSPATH%\""
  1349. + " \"-javaagent:%ASPECTJ_HOME%\\lib\\aspectjweaver.jar\"" + " " + makeScriptArgs(false));
  1350. }
  1351. /**
  1352. * @param ps
  1353. */
  1354. private void writeAJUnixLaunchLine(PrintStream ps) {
  1355. ps.println("\"$JAVA_HOME/bin/java\" -classpath" + " \"$ASPECTJ_HOME/lib/aspectjweaver.jar\""
  1356. + " \"-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader\""
  1357. + " \"-Daj.class.path=$ASPECTPATH:$CLASSPATH\"" + " \"-Daj.aspect.path=$ASPECTPATH\"" + " " + makeScriptArgs(true));
  1358. }
  1359. /**
  1360. * @param ps
  1361. */
  1362. private void writeAJ5UnixLaunchLine(PrintStream ps) {
  1363. ps.println("\"$JAVA_HOME/bin/java\" -classpath" + " \"$ASPECTJ_HOME/lib/aspectjweaver.jar:$CLASSPATH\""
  1364. + " \"-javaagent:$ASPECTJ_HOME/lib/aspectjweaver.jar\"" + " " + makeScriptArgs(true));
  1365. }
  1366. private void writeWindowsHeader(PrintStream ps) {
  1367. ps.println("@echo off");
  1368. ps.println("REM This file generated by AspectJ installer");
  1369. ps.println("REM Created on " + new java.util.Date() + " by " + System.getProperty("user.name"));
  1370. ps.println("");
  1371. ps.println("if \"%JAVA_HOME%\" == \"\" set JAVA_HOME=" + context.javaPath.getAbsolutePath());
  1372. ps.println("if \"%ASPECTJ_HOME%\" == \"\" set ASPECTJ_HOME=" + context.getOutputDir().getAbsolutePath());
  1373. ps.println("");
  1374. ps.println("if exist \"%JAVA_HOME%\\bin\\java.exe\" goto haveJava");
  1375. ps.println("if exist \"%JAVA_HOME%\\bin\\java.bat\" goto haveJava");
  1376. ps.println("if exist \"%JAVA_HOME%\\bin\\java\" goto haveJava");
  1377. ps.println("echo java does not exist as %JAVA_HOME%\\bin\\java");
  1378. ps.println("echo please fix the JAVA_HOME environment variable");
  1379. ps.println(":haveJava");
  1380. }
  1381. private void writeWindowsLaunchLine(String className, PrintStream ps) {
  1382. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " +
  1383. // "\"%ASPECTJ_HOME%\\lib\\aspectjtools.jar;%CLASSPATH%\""+
  1384. "\"%ASPECTJ_HOME%\\lib\\aspectjtools.jar;%JAVA_HOME%\\lib\\tools.jar;%CLASSPATH%\"" + " -Xmx64M " + className + //" -defaultClasspath " + "\"%CLASSPATH%\"" +
  1385. " " + makeScriptArgs(false));
  1386. }
  1387. private void writeUnixHeader(PrintStream ps) {
  1388. File binsh = new File(File.separator + "bin", "sh");
  1389. if (binsh.canRead()) {
  1390. ps.println("#!" + binsh.getPath());
  1391. }
  1392. ps.println("# This file generated by AspectJ installer");
  1393. ps.println("# Created on " + new java.util.Date() + " by " + System.getProperty("user.name"));
  1394. ps.println("");
  1395. ps.println("if [ \"$JAVA_HOME\" = \"\" ] ; then JAVA_HOME=" + quote(true, false, context.javaPath.getAbsolutePath()));
  1396. ps.println("fi");
  1397. ps.println("if [ \"$ASPECTJ_HOME\" = \"\" ] ; then ASPECTJ_HOME=" + quote(true, false, context.getOutputDir()));
  1398. ps.println("fi");
  1399. ps.println("");
  1400. }
  1401. private void writeUnixLaunchLine(String className, PrintStream ps) {
  1402. String sep = File.pathSeparator;
  1403. ps.println("\"$JAVA_HOME/bin/java\" -classpath " + "\"$ASPECTJ_HOME/lib/aspectjtools.jar" + sep
  1404. + "$JAVA_HOME/lib/tools.jar" + sep + "$CLASSPATH\"" + " -Xmx64M " + className + " " + makeScriptArgs(true));
  1405. }
  1406. private void makeExecutable(File file) {
  1407. try {
  1408. Runtime curRuntime = Runtime.getRuntime();
  1409. curRuntime.exec("chmod 777 " + quote(true, false, file));
  1410. } catch (Throwable t) {
  1411. // ignore any errors that occur while trying to chmod
  1412. }
  1413. }
  1414. private String makeScriptArgs(boolean unixStyle) {
  1415. if (unixStyle) {
  1416. return "\"$@\"";
  1417. } else if (context.onWindowsPro()) {
  1418. return "%*";
  1419. } else {
  1420. return "%1 %2 %3 %4 %5 %6 %7 %8 %9";
  1421. }
  1422. }
  1423. private String quote(boolean unixStyle, boolean forceQuotes, File file) {
  1424. return quote(unixStyle, forceQuotes, file.getAbsolutePath());
  1425. }
  1426. private String quote(boolean unixStyle, boolean forceQuotes, String s) {
  1427. if (context.onWindows() && unixStyle) {
  1428. s = s.replace('\\', '/');
  1429. }
  1430. if (!forceQuotes && s.indexOf(' ') == -1) {
  1431. return s;
  1432. }
  1433. return "\"" + s + "\"";
  1434. }
  1435. private File makeScriptFile(String name, boolean unixStyle) throws IOException {
  1436. if (!unixStyle) {
  1437. if (context.onOS2()) {
  1438. name += ".cmd";
  1439. } else if (context.onWindows()) {
  1440. name += ".bat";
  1441. }
  1442. }
  1443. //XXX probably want a context.getOutputBinDir()
  1444. File bindir = new File(context.getOutputDir(), "bin");
  1445. bindir.mkdirs();
  1446. File file = new File(bindir, name);
  1447. return file;
  1448. }
  1449. private PrintStream getPrintStream(File file) throws IOException {
  1450. return new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
  1451. }
  1452. String makeClassPathVar(boolean unixStyle) {
  1453. if (unixStyle) {
  1454. return "$CLASSPATH";
  1455. } else {
  1456. return "%CLASSPATH%";
  1457. }
  1458. }
  1459. public String makeClassPath(boolean unixStyle) throws IOException {
  1460. return context.toolsJarPath.getAbsolutePath() + File.pathSeparator
  1461. +
  1462. //XXX want context.getOutputLibDir()
  1463. new File(new File(context.getOutputDir(), "lib"), "aspectjtools.jar").getAbsolutePath() + File.pathSeparator
  1464. + makeClassPathVar(unixStyle);
  1465. }
  1466. public void writeScript(String className, PrintStream ps, boolean unixStyle) throws IOException {
  1467. if (unixStyle) {
  1468. writeUnixHeader(ps);
  1469. writeUnixLaunchLine(className, ps);
  1470. } else {
  1471. writeWindowsHeader(ps);
  1472. writeWindowsLaunchLine(className, ps);
  1473. }
  1474. /*
  1475. * ps.print(quote(unixStyle, false, context.javaPath.getAbsolutePath())); ps.print(" "); ps.print("-classpath ");
  1476. * ps.print(quote(unixStyle, true, makeClassPath(unixStyle))); ps.print(" "); ps.print("-Xmx64M "); ps.print(className);
  1477. * ps.print(" "); ps.print(makeScriptArgs(unixStyle));
  1478. */
  1479. }
  1480. public void writeScript(String className, boolean unixStyle) throws IOException {
  1481. File file = makeScriptFile(className, unixStyle);
  1482. if (!checkExistingFile(file)) {
  1483. return;
  1484. }
  1485. PrintStream ps = getPrintStream(file);
  1486. writeScript(toolsPackage + '.' + className + ".Main", ps, unixStyle);
  1487. ps.close();
  1488. //??? unixStyle vs. onUnix()
  1489. if (context.onUnix()) {
  1490. makeExecutable(file);
  1491. }
  1492. }
  1493. public boolean checkExistingFile(File file) {
  1494. if (!file.exists()) {
  1495. return true;
  1496. }
  1497. return context.shouldOverwrite(file);
  1498. }
  1499. /*
  1500. * final static String OVERWRITE_MESSAGE = "Overwrite launch script "; final static String OVERWRITE_TITLE = "Overwrite?";
  1501. *
  1502. * final static String[] OVERWRITE_OPTIONS = { "Yes", "No", "Yes to all", "No to all" };
  1503. *
  1504. * final static int OVERWRITE_YES = 0; final static int OVERWRITE_NO = 1; final static int OVERWRITE_ALL = 2; final static int
  1505. * OVERWRITE_NONE = 3;
  1506. *
  1507. * int overwriteState = OVERWRITE_NO; boolean shouldOverwrite(final File file) { if (overwriteState == OVERWRITE_ALL) return
  1508. * true; if (overwriteState == OVERWRITE_NONE) return false;
  1509. *
  1510. * try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { int ret =
  1511. * JOptionPane.showOptionDialog(context.installer.frame, OVERWRITE_MESSAGE+file.getPath(), OVERWRITE_TITLE,
  1512. * JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, OVERWRITE_OPTIONS, OVERWRITE_OPTIONS[OVERWRITE_YES]);
  1513. *
  1514. * overwriteState = ret; } }); } catch (InvocationTargetException ite) { context.handleException(ite.getTargetException()); }
  1515. * catch (InterruptedException ie) { }
  1516. *
  1517. * return overwriteState == OVERWRITE_YES || overwriteState == OVERWRITE_ALL; }
  1518. */
  1519. public void writeScript(String className) throws IOException {
  1520. writeScript(className, true);
  1521. if (context.onWindows()) {
  1522. writeScript(className, false);
  1523. }
  1524. }
  1525. }
  1526. class JarUnpacker {
  1527. InstallContext context;
  1528. InstallPane installPane;
  1529. public JarUnpacker(InstallContext context, InstallPane installPane) {
  1530. this.context = context;
  1531. this.installPane = installPane;
  1532. }
  1533. public File makeOutputFile(String name, File outputFile) {
  1534. int index;
  1535. int lastIndex = 0;
  1536. while ((index = name.indexOf('/', lastIndex)) != -1) {
  1537. outputFile = new File(outputFile, name.substring(lastIndex, index));
  1538. lastIndex = index + 1;
  1539. }
  1540. return new File(outputFile, name.substring(lastIndex));
  1541. }
  1542. final static int BUF_SIZE = 4096;
  1543. public void writeStream(ZipInputStream zis, File outputFile) throws IOException {
  1544. if (outputFile.exists()) {
  1545. if (!context.shouldOverwrite(outputFile)) {
  1546. return;
  1547. }
  1548. }
  1549. installPane.progressMessage("writing " + outputFile.getAbsolutePath());
  1550. outputFile.getParentFile().mkdirs();
  1551. if (context.isTextFile(outputFile)) {
  1552. writeTextStream(zis, outputFile);
  1553. } else {
  1554. writeBinaryStream(zis, outputFile);
  1555. }
  1556. }
  1557. public void writeBinaryStream(ZipInputStream zis, File outputFile) throws IOException {
  1558. byte[] buffer = new byte[BUF_SIZE];
  1559. int nRead = 0;
  1560. OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
  1561. while ((nRead = zis.read(buffer)) != -1) {
  1562. os.write(buffer, 0, nRead);
  1563. installPane.progressBytesWritten(nRead);
  1564. }
  1565. os.close();
  1566. }
  1567. public void writeTextStream(ZipInputStream zis, File outputFile) throws IOException {
  1568. BufferedWriter os = new BufferedWriter(new FileWriter(outputFile));
  1569. BufferedReader r = new BufferedReader(new InputStreamReader(zis, "US-ASCII"));
  1570. String l;
  1571. while ((l = r.readLine()) != null) {
  1572. os.write(l);
  1573. os.newLine();
  1574. installPane.progressBytesWritten(l.length() + 1);
  1575. }
  1576. os.close();
  1577. }
  1578. public void writeEntry(ZipInputStream zis, ZipEntry entry, File outputDir) throws IOException {
  1579. if (entry.isDirectory()) {
  1580. return;
  1581. }
  1582. String name = entry.getName();
  1583. File outputFile = makeOutputFile(name, outputDir);
  1584. writeStream(zis, outputFile);
  1585. }
  1586. public void unpack(String jarName, File outputDir) throws IOException {
  1587. URL url = getClass().getResource(jarName);
  1588. InputStream stream = url.openStream();
  1589. ZipInputStream zis = new ZipInputStream(stream);
  1590. // int i = 0;
  1591. ZipEntry entry;
  1592. while ((entry = zis.getNextEntry()) != null) {
  1593. // final String name = entry.getName();
  1594. writeEntry(zis, entry, outputDir);
  1595. //
  1596. }
  1597. installPane.progressMessage("done writing");
  1598. }
  1599. }