Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Main.java 50KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765
  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 SrcInstaller extends Installer {
  270. public String getTitle() {
  271. return "AspectJ(TM) Compiler and Core Tools Sources Installer";
  272. }
  273. public String getPrefix() {
  274. return "sources";
  275. }
  276. public SrcInstaller() {
  277. InstallPane installPane = new InstallPane(false);
  278. setInstallPane(installPane);
  279. panes = new WizardPane[] { new IntroPane(), new LocationPane(), installPane, new FinishPane() };
  280. }
  281. }
  282. abstract class Installer {
  283. static final String EXIT_MESSAGE = "Are you sure you want to cancel the installation?";
  284. static final String EXIT_TITLE = "Exiting installer";
  285. /**
  286. * relative directory in jar from package $installer$.org.aspectj for loading resources - todo must be tracked during build
  287. */
  288. public static final String RESOURCE_DIR = "resources";
  289. JFrame frame;
  290. InstallContext context;
  291. /** special pane that actually does the installation */
  292. InstallPane installPane;
  293. public Installer() {
  294. }
  295. protected void setInstallPane(InstallPane installPane) {
  296. this.installPane = installPane;
  297. }
  298. public InstallPane getInstallPane() {
  299. return installPane;
  300. }
  301. /** directly run the install pane, if any */
  302. public void run() {
  303. if (null != installPane) {
  304. installPane.run();
  305. }
  306. }
  307. public abstract String getPrefix();
  308. public String getReadmeFilename() {
  309. return "README-" + getPrefix().toUpperCase() + ".html";
  310. }
  311. public void setContext(InstallContext context) {
  312. this.context = context;
  313. context.installer = this;
  314. }
  315. public InstallContext getContext() {
  316. return context;
  317. }
  318. public String getTitle() {
  319. return "AspectJ(TM) Installer";
  320. }
  321. public int getWidth() {
  322. return 640;
  323. }
  324. public int getHeight() {
  325. return 460;
  326. }
  327. protected WizardPane[] panes = new WizardPane[0];
  328. public WizardPane[] getPanes() {
  329. return panes;
  330. }
  331. public int findPaneIndex(WizardPane pane) {
  332. for (int i = 0; i < panes.length; i++) {
  333. if (panes[i] == pane) {
  334. return i;
  335. }
  336. }
  337. return -1;
  338. }
  339. Component header, footer, body;
  340. public void runGUI() {
  341. frame = new JFrame(getTitle());
  342. WindowListener wl = new WindowAdapter() {
  343. public void windowClosing(WindowEvent arg0) {
  344. Main.exit(-1); // -1 unless exiting through done button
  345. }
  346. };
  347. frame.addWindowListener(wl);
  348. if (Options.forceError1) {
  349. throw new RuntimeException("forced error1 for testing purposes");
  350. }
  351. Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
  352. int x = (int) (size.getWidth() - getWidth()) / 2;
  353. int y = (int) (size.getHeight() - getHeight()) / 2;
  354. //include a few sanity checks on starting position
  355. if (x < 0) {
  356. x = 0;
  357. }
  358. if (x > 600) {
  359. x = 600;
  360. }
  361. if (y < 0) {
  362. y = 0;
  363. }
  364. if (y > 400) {
  365. y = 400;
  366. }
  367. frame.setLocation(x, y);
  368. frame.setSize(getWidth(), getHeight());
  369. moveToPane(getPanes()[0]);
  370. frame.setVisible(true);
  371. }
  372. public void moveToPane(WizardPane pane) {
  373. WizardPane.setContext(this.context);
  374. Dimension size = frame.getContentPane().getSize();
  375. JPanel contents = new JPanel();
  376. contents.setLayout(new BorderLayout());
  377. header = makeHeader();
  378. contents.add(header, BorderLayout.NORTH);
  379. body = pane.getPanel();
  380. contents.add(body, BorderLayout.CENTER);
  381. footer = pane.getButtons();
  382. contents.add(footer, BorderLayout.SOUTH);
  383. contents.revalidate();
  384. contents.setSize(size);
  385. frame.setContentPane(contents);
  386. //XXX deal with threading here?
  387. pane.run();
  388. }
  389. public Icon loadImage(String name) {
  390. return new javax.swing.ImageIcon(this.getClass().getResource(name));
  391. }
  392. public Component makeHeader() {
  393. return new JLabel(loadImage(Installer.RESOURCE_DIR + "/aspectjBanner.gif"));
  394. }
  395. public ActionListener makeNextAction(final WizardPane pane) {
  396. int nextPaneIndex = findPaneIndex(pane) + 1;
  397. if (nextPaneIndex >= getPanes().length) {
  398. return null;
  399. }
  400. final WizardPane nextPane = getPanes()[nextPaneIndex];
  401. return new ActionListener() {
  402. public void actionPerformed(ActionEvent e) {
  403. pane.finish();
  404. moveToPane(nextPane);
  405. }
  406. };
  407. }
  408. public ActionListener makeBackAction(final WizardPane pane) {
  409. int nextPaneIndex = findPaneIndex(pane) - 1;
  410. if (nextPaneIndex < 0) {
  411. return null;
  412. }
  413. final WizardPane nextPane = getPanes()[nextPaneIndex];
  414. return new ActionListener() {
  415. public void actionPerformed(ActionEvent e) {
  416. moveToPane(nextPane);
  417. }
  418. };
  419. }
  420. public ActionListener makeCancelAction(WizardPane pane) {
  421. return new ActionListener() {
  422. public void actionPerformed(ActionEvent e) {
  423. int ret = JOptionPane.showConfirmDialog(frame, EXIT_MESSAGE, EXIT_TITLE, JOptionPane.YES_NO_OPTION,
  424. JOptionPane.QUESTION_MESSAGE);
  425. if (ret == JOptionPane.YES_OPTION) {
  426. Main.exit(-1);
  427. }
  428. }
  429. };
  430. }
  431. public ActionListener makeFinishAction(WizardPane pane) {
  432. return new ActionListener() {
  433. public void actionPerformed(ActionEvent e) {
  434. Main.exit(0);
  435. }
  436. };
  437. }
  438. }
  439. // willing to go up to 3 levels deep to find either jre or jdk
  440. // jre\[*\]lib\ext
  441. // jdk*\lib\tools.jar
  442. /*****
  443. * final static int MAX_DEPTH = 4; public static void findPaths(String prefix, File currentDir, int currentDepth) { if (currentDepth
  444. * > MAX_DEPTH) return; if (!currentDir.exists() || !currentDir.isDirectory()) return; File [] files = currentDir.listFiles(); if
  445. * (files == null) return; for (int i=0; i<files.length; i++) { if (files[i] == null) continue; if (!files[i].isDirectory())
  446. * continue; if (files[i].getName().startsWith(prefix)) { System.out.println("found: " + files[i]); } else { findPaths(prefix,
  447. * files[i], currentDepth + 1); } } }
  448. *
  449. * public static void findPaths(String prefix) { File [] files = File.listRoots(); for (int i=1; i<files.length; i++) { if
  450. * (!files[i].isDirectory()) continue; if (files[i].getName().toLowerCase().startsWith(prefix)) { System.out.println("found: " +
  451. * files[i]); } else { findPaths(prefix, files[i], 1); } } }
  452. *****/
  453. class InstallContext {
  454. public InstallContext(Map properties) {
  455. this.properties = properties;
  456. properties.put("user.home", System.getProperty("user.home"));
  457. //System.out.println("new install context");
  458. }
  459. private File outputDir;
  460. public void setOutputDir(File outputDir) {
  461. this.outputDir = outputDir;
  462. properties.put("installer.output.dir", outputDir.getAbsolutePath());
  463. properties.put("installer.output.dir.bin", new File(outputDir, "bin").getAbsolutePath());
  464. properties.put("installer.output.dir.doc", new File(outputDir, "doc").getAbsolutePath());
  465. properties.put("installer.output.aspectjrt", new File(new File(outputDir, "lib"), "aspectjrt.jar").getAbsolutePath());
  466. properties.put("installer.output.readme", new File(outputDir, installer.getReadmeFilename()).getAbsolutePath());
  467. }
  468. public File getOutputDir() {
  469. return outputDir;
  470. }
  471. private boolean hasGui;
  472. public File javaPath;
  473. public File toolsJarPath;
  474. public Installer installer;
  475. private Map<String,String> properties;
  476. public boolean hasGui() {
  477. return hasGui;
  478. }
  479. public void setHasGui(boolean hasGui) {
  480. if (this.hasGui != hasGui) {
  481. this.hasGui = hasGui;
  482. }
  483. }
  484. public Font getFont() {
  485. return new Font("Serif", Font.PLAIN, 14);
  486. }
  487. public String getOS() {
  488. return System.getProperty("os.name");
  489. }
  490. public boolean onOS2() {
  491. return getOS().equals("OS2") || getOS().equals("OS/2");
  492. }
  493. public boolean onWindows() {
  494. return getOS().startsWith("Windows") || onOS2();
  495. }
  496. public boolean onWindowsPro() {
  497. // TODO: Think about a more future-proof solution also checking 'os.version' system property. See also this table:
  498. // https://github.com/openjdk/jdk/blob/9604ee82690f89320614b37bfef4178abc869777/src/java.base/windows/native/libjava/java_props_md.c#L446
  499. // Alternatively, explicitly exclude unsupported versions because those won't change in the future.
  500. return getOS().matches("^Windows (NT|2000|XP|Vista|Server|7|8|10).*");
  501. }
  502. public boolean onMacintosh() {
  503. return getOS().startsWith("Mac");
  504. }
  505. public boolean onUnix() {
  506. return !onWindows();
  507. }
  508. static final String[] TEXT_EXTENSIONS = { ".txt", ".text", ".htm", ".html", ".java", ".ajava", "README", ".lst" };
  509. public boolean isTextFile(File file) {
  510. String name = file.getName();
  511. for (String textExtension : TEXT_EXTENSIONS) {
  512. if (name.endsWith(textExtension)) {
  513. return true;
  514. }
  515. }
  516. return false;
  517. }
  518. public void handleException(Throwable e) {
  519. System.out.println("internal error: " + e.toString());
  520. e.printStackTrace();
  521. if (hasGui()) {
  522. JOptionPane.showMessageDialog(installer.frame, e.toString(), "Unexpected Exception", JOptionPane.ERROR_MESSAGE);
  523. }
  524. }
  525. final static String OVERWRITE_MESSAGE = "Overwrite file ";
  526. final static String OVERWRITE_TITLE = "Overwrite?";
  527. final static String[] OVERWRITE_OPTIONS = { "Yes", "No", "Yes to all" //, "No to all"
  528. };
  529. final static int OVERWRITE_YES = 0;
  530. final static int OVERWRITE_NO = 1;
  531. final static int OVERWRITE_ALL = 2;
  532. //final static int OVERWRITE_NONE = 3;
  533. int overwriteState = OVERWRITE_NO;
  534. boolean shouldOverwrite(final File file) {
  535. //System.out.println("overwrite: " + file + " state " + overwriteState);
  536. if (overwriteState == OVERWRITE_ALL) {
  537. return true;
  538. //if (overwriteState == OVERWRITE_NONE) return false;
  539. }
  540. try {
  541. SwingUtilities.invokeAndWait(new Runnable() {
  542. public void run() {
  543. int ret = JOptionPane.showOptionDialog(installer.frame, OVERWRITE_MESSAGE + file.getPath(), OVERWRITE_TITLE,
  544. JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, OVERWRITE_OPTIONS,
  545. OVERWRITE_OPTIONS[OVERWRITE_YES]);
  546. overwriteState = ret;
  547. }
  548. });
  549. } catch (InvocationTargetException ite) {
  550. handleException(ite.getTargetException());
  551. } catch (InterruptedException ie) {
  552. }
  553. return overwriteState == OVERWRITE_YES || overwriteState == OVERWRITE_ALL;
  554. }
  555. public Map<String,String> getProperties() {
  556. return properties;
  557. }
  558. }
  559. abstract class WizardPane {
  560. static InstallContext context;
  561. protected JButton backButton = null;
  562. protected JButton nextButton = null;
  563. protected JButton cancelButton = null;
  564. public static void setContext(InstallContext con) {
  565. context = con;
  566. }
  567. public abstract JPanel makePanel();
  568. protected JTextArea makeTextArea(String data) {
  569. JTextArea text = new JTextArea(data);
  570. text.setOpaque(false);
  571. text.setFont(context.getFont());
  572. text.setEditable(false);
  573. return text;
  574. }
  575. /** @return false only if there is an InstallContext saying there is no GUI */
  576. protected boolean hasGui() {
  577. final InstallContext icontext = context;
  578. return ((null == icontext) || icontext.hasGui());
  579. }
  580. public static String stringFromStream(InputStream stream) throws IOException {
  581. BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "US-ASCII"));
  582. StringBuilder ret = new StringBuilder();
  583. int data;
  584. while ((data = reader.read()) != -1) {
  585. ret.append((char) data);
  586. }
  587. return ret.toString();
  588. }
  589. public static String removeHead(String text) {
  590. int startIndex = text.indexOf("<head>");
  591. int stopIndex = text.indexOf("</head>");
  592. if (startIndex == -1 || stopIndex == -1) {
  593. return text;
  594. }
  595. stopIndex += 7;
  596. return text.substring(0, startIndex) + text.substring(stopIndex);
  597. }
  598. static String styleHeader = "<head></head>";/*
  599. * <STYLE TYPE=\"text/css\"><!--\n" + " h2 {\n" + " font-size: x-large;\n" +
  600. * " font-family: Serif;\n" + " font-weight: normal;\n" + " }\n" + " p {\n" +
  601. * " font-family: Serif;\n" + " font-weight: normal;\n" + //" color:black;\n"
  602. * + "}</head>\n";
  603. */
  604. public static String applyProperties(String text, Map<String,String> map) {
  605. // ${name} -> map.get(name).toString()
  606. int lastIndex = 0;
  607. StringBuilder buf = new StringBuilder();
  608. int startIndex;
  609. while ((startIndex = text.indexOf("${", lastIndex)) != -1) {
  610. int endIndex = text.indexOf('}', startIndex);
  611. //XXX internal error here
  612. if (endIndex == -1) {
  613. break;
  614. }
  615. buf.append(text.substring(lastIndex, startIndex));
  616. String key = text.substring(startIndex + 2, endIndex);
  617. lastIndex = endIndex + 1;
  618. String replaceText = (map == null ? null : map.get(key));
  619. //System.out.println("key: " + key + " -> " + replaceText);
  620. if (replaceText == null) {
  621. replaceText = "NOT_FOUND";
  622. }
  623. buf.append(replaceText.toString());
  624. }
  625. buf.append(text.substring(lastIndex));
  626. return buf.toString();
  627. }
  628. public static String applyProperties(String text) {
  629. return applyProperties(text, (context == null ? null : context.getProperties()));
  630. }
  631. protected String loadText(String filename) {
  632. String fullname = Installer.RESOURCE_DIR + "/" + filename;
  633. //context.installer.getPrefix() + "-" + filename;
  634. try {
  635. String text = stringFromStream(getClass().getResourceAsStream(fullname));
  636. text = styleHeader + removeHead(text);
  637. text = applyProperties(text);
  638. //System.out.println(text);
  639. return text;
  640. } catch (IOException e) {
  641. context.handleException(e);
  642. return "";
  643. }
  644. }
  645. protected JEditorPane makeHTMLArea(String filename) {
  646. JEditorPane editorPane = new JEditorPane("text/html", loadText(filename));
  647. /*
  648. * { public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  649. * RenderingHints.VALUE_ANTIALIAS_ON); super.paint(g2); } };
  650. */
  651. editorPane.setEditable(false);
  652. editorPane.setOpaque(false);
  653. return editorPane;
  654. }
  655. protected void setHTMLArea(JEditorPane pane, String filename) {
  656. pane.setText(loadText(filename));
  657. }
  658. protected JPanel makeLocationBox(String label, JTextField textField, JButton browseButton) {
  659. JPanel box = new JPanel();
  660. box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS));
  661. textField.setFont(context.getFont());
  662. textField.selectAll();
  663. box.add(textField);
  664. box.add(browseButton);
  665. Border border = BorderFactory.createTitledBorder(label);
  666. final int INSET = 8;
  667. border = new CompoundBorder(border, new EmptyBorder(1, INSET, INSET, INSET));
  668. box.setBorder(border);
  669. return box;
  670. }
  671. private JPanel panel = null;
  672. public JPanel getPanel() {
  673. if (panel == null) {
  674. panel = makePanel();
  675. panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
  676. }
  677. return panel;
  678. }
  679. protected void setListener(JButton button, ActionListener listener) {
  680. if (listener == null) {
  681. button.setEnabled(false);
  682. } else {
  683. button.addActionListener(listener);
  684. }
  685. }
  686. protected Component makeButtons(Installer installer) {
  687. JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  688. backButton = new JButton("Back");
  689. setListener(backButton, installer.makeBackAction(this));
  690. panel.add(backButton);
  691. nextButton = new JButton("Next");
  692. setListener(nextButton, installer.makeNextAction(this));
  693. panel.add(nextButton); //.setDefaultCapable(true);
  694. JLabel space = new JLabel();
  695. space.setPreferredSize(new Dimension(20, 0));
  696. panel.add(space);
  697. cancelButton = new JButton("Cancel");
  698. setListener(cancelButton, installer.makeCancelAction(this));
  699. panel.add(cancelButton);
  700. return panel;
  701. }
  702. private Component buttons = null;
  703. public Component getButtons() {
  704. if (buttons == null) {
  705. buttons = makeButtons(context.installer);
  706. //buttons.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
  707. }
  708. context.installer.frame.getRootPane().setDefaultButton(nextButton);
  709. return buttons;
  710. }
  711. public void finish() {
  712. if (Options.forceError2) {
  713. throw new RuntimeException("forced error2 for testing purposes");
  714. }
  715. }
  716. public void run() {
  717. }
  718. }
  719. class IntroPane extends WizardPane {
  720. public JPanel makePanel() {
  721. Component text = makeHTMLArea("intro.html");
  722. JPanel panel = new JPanel(new BorderLayout());
  723. panel.add(text);
  724. return panel;
  725. }
  726. }
  727. class FinishPane extends WizardPane {
  728. public JPanel makePanel() {
  729. Component text = makeHTMLArea("finish.html");
  730. JPanel panel = new JPanel(new BorderLayout());
  731. panel.add(text);
  732. finalActions();
  733. return panel;
  734. }
  735. public Component makeButtons(Installer installer) {
  736. Component ret = super.makeButtons(installer);
  737. nextButton.setText("Finish");
  738. nextButton.setEnabled(true);
  739. nextButton.addActionListener(installer.makeFinishAction(this));
  740. backButton.setEnabled(false);
  741. cancelButton.setEnabled(false);
  742. return ret;
  743. }
  744. public void finalActions() {
  745. }
  746. }
  747. class LocationPane extends WizardPane implements ActionListener {
  748. //XXX need more sophisticated default location finding
  749. //XXX would like to find the place they last chose...
  750. public String getDefaultLocation() {
  751. if (context.onWindows()) {
  752. return "c:\\aspectj1.9";
  753. } else {
  754. return new File(System.getProperty("user.home"), "aspectj1.9").getAbsolutePath();
  755. }
  756. }
  757. protected JTextField location;
  758. public JPanel makePanel() {
  759. Component text = makeHTMLArea("location.html");
  760. location = new JTextField(getDefaultLocation());
  761. JButton browse = new JButton("Browse...");
  762. browse.addActionListener(this);
  763. JPanel locationBox = makeLocationBox("installation directory", location, browse);
  764. GridBagLayout bag = new GridBagLayout();
  765. GridBagConstraints c = new GridBagConstraints();
  766. JPanel panel = new JPanel(bag);
  767. c.fill = GridBagConstraints.BOTH;
  768. c.weightx = 1.0;
  769. c.gridwidth = GridBagConstraints.REMAINDER;
  770. bag.setConstraints(text, c);
  771. panel.add(text);
  772. c.weighty = 1.0;
  773. c.fill = GridBagConstraints.HORIZONTAL;
  774. c.gridwidth = GridBagConstraints.REMAINDER;
  775. bag.setConstraints(locationBox, c);
  776. panel.add(locationBox);
  777. //XXX set next button to read install
  778. //context.nextButton.setText("Install");
  779. return panel;
  780. }
  781. public Component makeButtons(Installer installer) {
  782. Component ret = super.makeButtons(installer);
  783. nextButton.setText("Install");
  784. return ret;
  785. }
  786. public void actionPerformed(ActionEvent e) {
  787. JFileChooser chooser = new JFileChooser(); // {
  788. // public void approveSelection() {
  789. // System.out.println("approved selection");
  790. // }
  791. //}; //field.getText());
  792. chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
  793. int returnVal = chooser.showDialog(location, "Select");
  794. if (returnVal == JFileChooser.APPROVE_OPTION) {
  795. File file = chooser.getSelectedFile();
  796. if (!file.isDirectory()) {
  797. file = file.getParentFile();
  798. }
  799. String name = file.getPath();
  800. location.setText(name);
  801. location.selectAll();
  802. }
  803. }
  804. /**
  805. * Override to do any additional checks.
  806. */
  807. protected void verify() {
  808. }
  809. public void finish() {
  810. verify();
  811. context.setOutputDir(new File(location.getText()));
  812. }
  813. }
  814. class ConfigureLauncherPane extends WizardPane {
  815. /*
  816. * //XXX check that the returned file is valid public String getDefaultJavaLocation() { String name = "java"; if
  817. * (context.onWindows()) name += ".exe";
  818. *
  819. * if (Options.verbose) { System.out.println("java.home: " + System.getProperty("java.home")); System.out.println(" java: " +
  820. * new File(new File(System.getProperty("java.home"), "bin"), name)); System.out.println(" java: " + new File(new
  821. * File(System.getProperty("java.home"), "bin"), name).getPath()); }
  822. *
  823. * return new File(new File(System.getProperty("java.home"), "bin"), name).getPath(); }
  824. */
  825. public static String getDefaultJavaHomeLocation() {
  826. if (!Options.forceHandConfigure) {
  827. File javaHome = findJavaHome();
  828. if (javaHome != null) {
  829. return javaHome.getPath();
  830. }
  831. }
  832. return null;
  833. }
  834. public void chooseFile(JTextField field) {
  835. JFileChooser chooser = new JFileChooser(); //field.getText());
  836. chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  837. int returnVal = chooser.showDialog(field, "Select");
  838. if (returnVal == JFileChooser.APPROVE_OPTION) {
  839. String name = chooser.getSelectedFile().getPath();
  840. field.setText(name);
  841. field.selectAll();
  842. }
  843. }
  844. public ActionListener makeJavaLocationBrowseListener() {
  845. return new ActionListener() {
  846. public void actionPerformed(ActionEvent e) {
  847. chooseFile(javaLocation);
  848. }
  849. };
  850. }
  851. // public ActionListener makeToolsJarLocationBrowseListener() {
  852. // return new ActionListener() {
  853. // public void actionPerformed(ActionEvent e) {
  854. // chooseFile(toolsJarLocation);
  855. // }
  856. // };
  857. // }
  858. private JTextField javaLocation;
  859. //private JTextField toolsJarLocation;
  860. public JPanel makePanel() {
  861. String javaPath = getDefaultJavaHomeLocation();
  862. //String toolsJarPath = getDefaultToolsJarLocation();
  863. Component text;
  864. if (javaPath == null) {
  865. javaPath = "<java home not found>";
  866. text = makeHTMLArea("configure-hand.html");
  867. } else {
  868. text = makeHTMLArea("configure-auto.html");
  869. }
  870. javaLocation = new JTextField(javaPath);
  871. JButton javaLocationBrowse = new JButton("Browse...");
  872. javaLocationBrowse.addActionListener(makeJavaLocationBrowseListener());
  873. JPanel javaLocationBox = makeLocationBox("java home directory", javaLocation, javaLocationBrowse);
  874. // toolsJarLocation = new JTextField(toolsJarPath);
  875. // JButton toolsJarLocationBrowse = new JButton("Browse...");
  876. // toolsJarLocationBrowse.addActionListener(makeToolsJarLocationBrowseListener());
  877. // JPanel toolsJarLocationBox = makeLocationBox("full path to tools.jar", toolsJarLocation, toolsJarLocationBrowse);
  878. GridBagLayout bag = new GridBagLayout();
  879. GridBagConstraints c = new GridBagConstraints();
  880. JPanel panel = new JPanel(bag);
  881. c.fill = GridBagConstraints.BOTH;
  882. c.weightx = 1.0;
  883. c.weighty = 1.0;
  884. //c.ipady = 10;
  885. c.gridwidth = GridBagConstraints.REMAINDER;
  886. bag.setConstraints(text, c);
  887. panel.add(text);
  888. c.weighty = 0.0;
  889. //c.fill = GridBagConstraints.VERTICAL;
  890. bag.setConstraints(javaLocationBox, c);
  891. panel.add(javaLocationBox);
  892. // c.weighty = 0.25;
  893. // JLabel space = new JLabel();
  894. // bag.setConstraints(space, c);
  895. // panel.add(space);
  896. // c.weighty = 0.0;
  897. // bag.setConstraints(toolsJarLocationBox, c);
  898. // panel.add(toolsJarLocationBox);
  899. c.weighty = 0.5;
  900. JLabel space = new JLabel();
  901. bag.setConstraints(space, c);
  902. panel.add(space);
  903. return panel;
  904. }
  905. public void finish() {
  906. context.javaPath = new File(javaLocation.getText());
  907. // context.toolsJarPath = new File(toolsJarLocation.getText());
  908. //XXX need much more work on helping the user get these paths right
  909. // if (context.javaPath.isDirectory()) {
  910. // context.javaPath = new File(context.javaPath, "java");
  911. // }
  912. // if (context.toolsJarPath.isDirectory()) {
  913. // context.toolsJarPath = new File(context.toolsJarPath, "tools.jar");
  914. // }
  915. }
  916. //XXX add user.home to prefixes in a rational way
  917. public static final String[] windowsPaths = { "c:\\jdk", "c:\\apps\\jdk", "${user.home}\\jdk" };
  918. public static final String[] unixPaths = { "/usr/local/bin/jdk", "/usr/bin/jdk", "/usr/bin/jdk", "${user.home}/jdk" };
  919. public static final String[] suffixes = { "1.3.1", "1.3", "1.2", "13", "12", "2", "", "1.4" };
  920. public static boolean windows = true;
  921. public static boolean isLegalJavaHome(File home) {
  922. File bin = new File(home, "bin");
  923. return new File(bin, "java").isFile() || new File(bin, "java.exe").isFile();
  924. }
  925. public static boolean isLegalJDKHome(File home) {
  926. File lib = new File(home, "lib");
  927. return new File(lib, "tools.jar").isFile();
  928. }
  929. public static File findJavaHome() {
  930. String s = System.getProperty("java.home");
  931. File javaHome = null;
  932. if (s != null) {
  933. javaHome = new File(s);
  934. if (isLegalJDKHome(javaHome)) {
  935. return javaHome;
  936. }
  937. if (isLegalJavaHome(javaHome)) {
  938. File parent = javaHome.getParentFile();
  939. if (parent != null && isLegalJDKHome(parent)) {
  940. return parent;
  941. }
  942. }
  943. }
  944. String[] paths;
  945. if (windows) {
  946. paths = windowsPaths;
  947. } else {
  948. paths = unixPaths;
  949. }
  950. for (String suffix : suffixes) {
  951. for (String path : paths) {
  952. String prefix = path;
  953. prefix = applyProperties(prefix);
  954. File test = new File(prefix + suffix);
  955. if (isLegalJavaHome(test)) {
  956. if (isLegalJDKHome(test)) {
  957. return test;
  958. } else if (javaHome == null) {
  959. javaHome = test;
  960. }
  961. }
  962. }
  963. }
  964. return javaHome;
  965. }
  966. }
  967. class InstallPane extends WizardPane {
  968. private JProgressBar progressBar;
  969. private JTextField progressItem;
  970. private JEditorPane message;
  971. private boolean makeLaunchScripts = false;
  972. public InstallPane(boolean makeLaunchScripts) {
  973. this.makeLaunchScripts = makeLaunchScripts;
  974. }
  975. public JPanel makePanel() {
  976. message = makeHTMLArea("install-start.html");
  977. progressBar = new JProgressBar();
  978. progressItem = new JTextField();
  979. progressItem.setOpaque(false);
  980. progressItem.setFont(context.getFont());
  981. progressItem.setEditable(false);
  982. GridBagLayout bag = new GridBagLayout();
  983. GridBagConstraints c = new GridBagConstraints();
  984. JPanel panel = new JPanel(bag);
  985. c.fill = GridBagConstraints.BOTH;
  986. c.weightx = 1.0;
  987. c.weighty = 1.0;
  988. //c.ipady = 10;
  989. c.gridwidth = GridBagConstraints.REMAINDER;
  990. bag.setConstraints(message, c);
  991. panel.add(message);
  992. c.weighty = 0.0;
  993. //c.fill = GridBagConstraints.VERTICAL;
  994. bag.setConstraints(progressBar, c);
  995. panel.add(progressBar);
  996. c.weighty = 0.1;
  997. JLabel space = new JLabel();
  998. bag.setConstraints(space, c);
  999. panel.add(space);
  1000. c.weighty = 0.0;
  1001. bag.setConstraints(progressItem, c);
  1002. panel.add(progressItem);
  1003. c.weighty = 0.5;
  1004. space = new JLabel();
  1005. bag.setConstraints(space, c);
  1006. panel.add(space);
  1007. return panel;
  1008. }
  1009. class InstallRunner implements Runnable {
  1010. public InstallRunner() {
  1011. }
  1012. public void run() {
  1013. try {
  1014. new CurrentJarUnpacker(context, InstallPane.this).unpack(Installer.RESOURCE_DIR + "/contents.txt",
  1015. context.getOutputDir());
  1016. if (makeLaunchScripts) {
  1017. LaunchScriptMaker lsm = new LaunchScriptMaker(context);
  1018. lsm.writeScript("ajc");
  1019. lsm.writeScript("ajdoc");
  1020. // Moved to the bin dir in 1.2.1
  1021. // we should now come back and make the generation of this
  1022. // script uniform with those above.
  1023. lsm.writeAJLaunchScript("aj", false);
  1024. lsm.writeAJLaunchScript("aj5", true);
  1025. }
  1026. if (hasGui()) {
  1027. progressBar.setValue(100);
  1028. setHTMLArea(message, "install-finish.html");
  1029. }
  1030. } catch (IOException ioe) {
  1031. context.handleException(ioe);
  1032. }
  1033. if (hasGui()) {
  1034. cancelButton.setEnabled(false);
  1035. nextButton.setEnabled(true);
  1036. }
  1037. }
  1038. }
  1039. public Component makeButtons(Installer installer) {
  1040. Component ret = super.makeButtons(installer);
  1041. //nextButton.setText("Finish");
  1042. nextButton.setEnabled(false);
  1043. //nextButton.addActionListener(installer.makeFinishAction(this));
  1044. backButton.setEnabled(false);
  1045. return ret;
  1046. }
  1047. public void run() {
  1048. Thread thread = new Thread(new InstallRunner());
  1049. thread.start();
  1050. }
  1051. public void progressMessage(final String message) {
  1052. if (!hasGui()) {
  1053. return;
  1054. }
  1055. try {
  1056. //XXX performance tradeoff between invokeAndWait and invokeLater...
  1057. SwingUtilities.invokeAndWait(new Runnable() {
  1058. public void run() {
  1059. progressItem.setText(message);
  1060. }
  1061. });
  1062. } catch (InvocationTargetException ite) {
  1063. context.handleException(ite.getTargetException());
  1064. } catch (InterruptedException ie) {
  1065. }
  1066. }
  1067. int nBytes = 0;
  1068. int bytesWritten = 0;
  1069. public void progressBytesWritten(int bytes) {
  1070. if (!hasGui()) {
  1071. return;
  1072. }
  1073. bytesWritten += bytes;
  1074. final int PCT = (int) (100.0 * bytesWritten / nBytes);
  1075. //System.out.println("bytesWritten: " + bytesWritten);
  1076. try {
  1077. //XXX performance tradeoff between invokeAndWait and invokeLater...
  1078. SwingUtilities.invokeAndWait(new Runnable() {
  1079. public void run() {
  1080. progressBar.setValue(PCT);
  1081. }
  1082. });
  1083. } catch (InvocationTargetException ite) {
  1084. context.handleException(ite.getTargetException());
  1085. } catch (InterruptedException ie) {
  1086. }
  1087. }
  1088. }
  1089. class CurrentJarUnpacker {
  1090. InstallContext context;
  1091. InstallPane installPane;
  1092. public CurrentJarUnpacker(InstallContext context, InstallPane installPane) {
  1093. this.context = context;
  1094. this.installPane = installPane;
  1095. }
  1096. public File makeOutputFile(String name, File outputFile) {
  1097. int index;
  1098. int lastIndex = 0;
  1099. while ((index = name.indexOf('/', lastIndex)) != -1) {
  1100. outputFile = new File(outputFile, name.substring(lastIndex, index));
  1101. lastIndex = index + 1;
  1102. }
  1103. return new File(outputFile, name.substring(lastIndex));
  1104. }
  1105. final static int BUF_SIZE = 4096;
  1106. public void writeStream(InputStream zis, File outputFile) throws IOException {
  1107. if (outputFile.exists()) {
  1108. if (!context.shouldOverwrite(outputFile)) {
  1109. return;
  1110. }
  1111. }
  1112. installPane.progressMessage("writing " + outputFile.getAbsolutePath());
  1113. outputFile.getParentFile().mkdirs();
  1114. if (context.isTextFile(outputFile)) {
  1115. writeTextStream(zis, outputFile);
  1116. } else {
  1117. writeBinaryStream(zis, outputFile);
  1118. }
  1119. }
  1120. public void writeBinaryStream(InputStream zis, File outputFile) throws IOException {
  1121. byte[] buffer = new byte[BUF_SIZE];
  1122. int nRead = 0;
  1123. OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
  1124. while ((nRead = zis.read(buffer)) != -1) {
  1125. os.write(buffer, 0, nRead);
  1126. installPane.progressBytesWritten(nRead);
  1127. }
  1128. os.close();
  1129. }
  1130. public void writeTextStream(InputStream zis, File outputFile) throws IOException {
  1131. BufferedWriter os = new BufferedWriter(new FileWriter(outputFile));
  1132. BufferedReader r = new BufferedReader(new InputStreamReader(zis, "US-ASCII"));
  1133. String l;
  1134. while ((l = r.readLine()) != null) {
  1135. os.write(l);
  1136. os.newLine();
  1137. installPane.progressBytesWritten(l.length() + 1);
  1138. }
  1139. os.close();
  1140. }
  1141. public void writeResource(String name, File outputDir) throws IOException {
  1142. File outputFile = makeOutputFile(name, outputDir);
  1143. //System.out.println("finding name: " + name);
  1144. writeStream(getClass().getResourceAsStream("/" + name), outputFile);
  1145. }
  1146. public void writeResource(JarFile jarFile, JarEntry entry, File outputDir) throws IOException {
  1147. String name = entry.getName().substring(6);
  1148. File outputFile = makeOutputFile(name, outputDir);
  1149. //System.out.println("finding name: " + name);
  1150. // writeStream(getClass().getResourceAsStream("/" + name), outputFile);
  1151. writeStream(jarFile.getInputStream(entry), outputFile);
  1152. }
  1153. public void unpack(String contentsName, File outputDir) throws IOException {
  1154. URL url = getClass().getResource(contentsName);
  1155. // Process everything under 'files/**' copying to the target
  1156. // install directory with 'files/' removed
  1157. JarURLConnection juc = (JarURLConnection) url.openConnection();
  1158. JarFile jf = juc.getJarFile();
  1159. Enumeration<JarEntry> entries = jf.entries();
  1160. while (entries.hasMoreElements()) {
  1161. JarEntry je = entries.nextElement();
  1162. if (je.getName().startsWith("files/") && !je.getName().endsWith("/")) {
  1163. writeResource(jf, je, outputDir);
  1164. }
  1165. }
  1166. // InputStream stream = url.openStream();
  1167. // BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "US-ASCII"));
  1168. // String line = reader.readLine();
  1169. // installPane.nBytes = Integer.parseInt(line);
  1170. //
  1171. // while ((line = reader.readLine()) != null) {
  1172. // writeResource(line, outputDir);
  1173. // }
  1174. installPane.progressMessage("done writing");
  1175. }
  1176. }
  1177. class LaunchScriptMaker {
  1178. static final String toolsPackage = "org.aspectj.tools";
  1179. InstallContext context;
  1180. public LaunchScriptMaker(InstallContext context) {
  1181. this.context = context;
  1182. }
  1183. /**
  1184. *
  1185. */
  1186. public void writeAJLaunchScript(String name, boolean isJava5) throws IOException {
  1187. if (!context.onUnix()) {
  1188. if (context.onOS2()) {
  1189. name += ".cmd";
  1190. } else if (context.onWindows()) {
  1191. name += ".bat";
  1192. }
  1193. }
  1194. File destDir = new File(context.getOutputDir(), "bin");
  1195. destDir.mkdirs();
  1196. File file = new File(destDir, name);
  1197. PrintStream ps = getPrintStream(file);
  1198. writeAJLaunchScriptContent(ps, isJava5);
  1199. ps.close();
  1200. if (context.onUnix()) {
  1201. makeExecutable(file);
  1202. }
  1203. }
  1204. /**
  1205. * @param ps
  1206. */
  1207. private void writeAJLaunchScriptContent(PrintStream ps, boolean isJava5) {
  1208. if (context.onUnix()) {
  1209. writeUnixHeader(ps);
  1210. if (isJava5) {
  1211. writeAJ5UnixLaunchLine(ps);
  1212. } else {
  1213. writeAJUnixLaunchLine(ps);
  1214. }
  1215. } else {
  1216. writeWindowsHeader(ps);
  1217. if (isJava5) {
  1218. writeAJ5WindowsLaunchLine(ps);
  1219. } else {
  1220. writeAJWindowsLaunchLine(ps);
  1221. }
  1222. }
  1223. }
  1224. /**
  1225. * @param ps
  1226. */
  1227. private void writeAJWindowsLaunchLine(PrintStream ps) {
  1228. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " + "\"%ASPECTJ_HOME%\\lib\\aspectjweaver.jar\""
  1229. + " \"-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader\""
  1230. + " \"-Daj.class.path=%ASPECTPATH%;%CLASSPATH%\"" + " \"-Daj.aspect.path=%ASPECTPATH%\"" + " "
  1231. + makeScriptArgs(false));
  1232. }
  1233. /**
  1234. * @param ps
  1235. */
  1236. private void writeAJ5WindowsLaunchLine(PrintStream ps) {
  1237. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " + "\"%ASPECTJ_HOME%\\lib\\aspectjweaver.jar;%CLASSPATH%\""
  1238. + " \"-javaagent:%ASPECTJ_HOME%\\lib\\aspectjweaver.jar\"" + " " + makeScriptArgs(false));
  1239. }
  1240. /**
  1241. * @param ps
  1242. */
  1243. private void writeAJUnixLaunchLine(PrintStream ps) {
  1244. ps.println("\"$JAVA_HOME/bin/java\" -classpath" + " \"$ASPECTJ_HOME/lib/aspectjweaver.jar\""
  1245. + " \"-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader\""
  1246. + " \"-Daj.class.path=$ASPECTPATH:$CLASSPATH\"" + " \"-Daj.aspect.path=$ASPECTPATH\"" + " " + makeScriptArgs(true));
  1247. }
  1248. /**
  1249. * @param ps
  1250. */
  1251. private void writeAJ5UnixLaunchLine(PrintStream ps) {
  1252. ps.println("\"$JAVA_HOME/bin/java\" -classpath" + " \"$ASPECTJ_HOME/lib/aspectjweaver.jar:$CLASSPATH\""
  1253. + " \"-javaagent:$ASPECTJ_HOME/lib/aspectjweaver.jar\"" + " " + makeScriptArgs(true));
  1254. }
  1255. private void writeWindowsHeader(PrintStream ps) {
  1256. ps.println("@echo off");
  1257. ps.println("REM This file generated by AspectJ installer");
  1258. ps.println("REM Created on " + new java.util.Date() + " by " + System.getProperty("user.name"));
  1259. ps.println("");
  1260. ps.println("if \"%JAVA_HOME%\" == \"\" set JAVA_HOME=" + context.javaPath.getAbsolutePath());
  1261. ps.println("if \"%ASPECTJ_HOME%\" == \"\" set ASPECTJ_HOME=" + context.getOutputDir().getAbsolutePath());
  1262. ps.println("");
  1263. ps.println("if exist \"%JAVA_HOME%\\bin\\java.exe\" goto haveJava");
  1264. ps.println("if exist \"%JAVA_HOME%\\bin\\java.bat\" goto haveJava");
  1265. ps.println("if exist \"%JAVA_HOME%\\bin\\java\" goto haveJava");
  1266. ps.println("echo java does not exist as %JAVA_HOME%\\bin\\java");
  1267. ps.println("echo please fix the JAVA_HOME environment variable");
  1268. ps.println(":haveJava");
  1269. }
  1270. private void writeWindowsLaunchLine(String className, PrintStream ps) {
  1271. ps.println("\"%JAVA_HOME%\\bin\\java\" -classpath " +
  1272. // "\"%ASPECTJ_HOME%\\lib\\aspectjtools.jar;%CLASSPATH%\""+
  1273. "\"%ASPECTJ_HOME%\\lib\\aspectjtools.jar;%JAVA_HOME%\\lib\\tools.jar;%CLASSPATH%\"" + " -Xmx64M " + className + //" -defaultClasspath " + "\"%CLASSPATH%\"" +
  1274. " " + makeScriptArgs(false));
  1275. }
  1276. private void writeUnixHeader(PrintStream ps) {
  1277. File binsh = new File(File.separator + "bin", "sh");
  1278. if (binsh.canRead()) {
  1279. ps.println("#!" + binsh.getPath());
  1280. }
  1281. ps.println("# This file generated by AspectJ installer");
  1282. ps.println("# Created on " + new java.util.Date() + " by " + System.getProperty("user.name"));
  1283. ps.println("");
  1284. ps.println("if [ \"$JAVA_HOME\" = \"\" ] ; then JAVA_HOME=" + quote(true, false, context.javaPath.getAbsolutePath()));
  1285. ps.println("fi");
  1286. ps.println("if [ \"$ASPECTJ_HOME\" = \"\" ] ; then ASPECTJ_HOME=" + quote(true, false, context.getOutputDir()));
  1287. ps.println("fi");
  1288. ps.println("");
  1289. }
  1290. private void writeUnixLaunchLine(String className, PrintStream ps) {
  1291. String sep = File.pathSeparator;
  1292. ps.println("\"$JAVA_HOME/bin/java\" -classpath " + "\"$ASPECTJ_HOME/lib/aspectjtools.jar" + sep
  1293. + "$JAVA_HOME/lib/tools.jar" + sep + "$CLASSPATH\"" + " -Xmx64M " + className + " " + makeScriptArgs(true));
  1294. }
  1295. private void makeExecutable(File file) {
  1296. try {
  1297. Runtime curRuntime = Runtime.getRuntime();
  1298. curRuntime.exec("chmod 777 " + quote(true, false, file));
  1299. } catch (Throwable t) {
  1300. // ignore any errors that occur while trying to chmod
  1301. }
  1302. }
  1303. private String makeScriptArgs(boolean unixStyle) {
  1304. if (unixStyle) {
  1305. return "\"$@\"";
  1306. } else if (context.onWindowsPro()) {
  1307. return "%*";
  1308. } else {
  1309. return "%1 %2 %3 %4 %5 %6 %7 %8 %9";
  1310. }
  1311. }
  1312. private String quote(boolean unixStyle, boolean forceQuotes, File file) {
  1313. return quote(unixStyle, forceQuotes, file.getAbsolutePath());
  1314. }
  1315. private String quote(boolean unixStyle, boolean forceQuotes, String s) {
  1316. if (context.onWindows() && unixStyle) {
  1317. s = s.replace('\\', '/');
  1318. }
  1319. if (!forceQuotes && s.indexOf(' ') == -1) {
  1320. return s;
  1321. }
  1322. return "\"" + s + "\"";
  1323. }
  1324. private File makeScriptFile(String name, boolean unixStyle) throws IOException {
  1325. if (!unixStyle) {
  1326. if (context.onOS2()) {
  1327. name += ".cmd";
  1328. } else if (context.onWindows()) {
  1329. name += ".bat";
  1330. }
  1331. }
  1332. //XXX probably want a context.getOutputBinDir()
  1333. File bindir = new File(context.getOutputDir(), "bin");
  1334. bindir.mkdirs();
  1335. File file = new File(bindir, name);
  1336. return file;
  1337. }
  1338. private PrintStream getPrintStream(File file) throws IOException {
  1339. return new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
  1340. }
  1341. String makeClassPathVar(boolean unixStyle) {
  1342. if (unixStyle) {
  1343. return "$CLASSPATH";
  1344. } else {
  1345. return "%CLASSPATH%";
  1346. }
  1347. }
  1348. public String makeClassPath(boolean unixStyle) throws IOException {
  1349. return context.toolsJarPath.getAbsolutePath() + File.pathSeparator
  1350. +
  1351. //XXX want context.getOutputLibDir()
  1352. new File(new File(context.getOutputDir(), "lib"), "aspectjtools.jar").getAbsolutePath() + File.pathSeparator
  1353. + makeClassPathVar(unixStyle);
  1354. }
  1355. public void writeScript(String className, PrintStream ps, boolean unixStyle) throws IOException {
  1356. if (unixStyle) {
  1357. writeUnixHeader(ps);
  1358. writeUnixLaunchLine(className, ps);
  1359. } else {
  1360. writeWindowsHeader(ps);
  1361. writeWindowsLaunchLine(className, ps);
  1362. }
  1363. /*
  1364. * ps.print(quote(unixStyle, false, context.javaPath.getAbsolutePath())); ps.print(" "); ps.print("-classpath ");
  1365. * ps.print(quote(unixStyle, true, makeClassPath(unixStyle))); ps.print(" "); ps.print("-Xmx64M "); ps.print(className);
  1366. * ps.print(" "); ps.print(makeScriptArgs(unixStyle));
  1367. */
  1368. }
  1369. public void writeScript(String className, boolean unixStyle) throws IOException {
  1370. File file = makeScriptFile(className, unixStyle);
  1371. if (!checkExistingFile(file)) {
  1372. return;
  1373. }
  1374. PrintStream ps = getPrintStream(file);
  1375. writeScript(toolsPackage + '.' + className + ".Main", ps, unixStyle);
  1376. ps.close();
  1377. //??? unixStyle vs. onUnix()
  1378. if (context.onUnix()) {
  1379. makeExecutable(file);
  1380. }
  1381. }
  1382. public boolean checkExistingFile(File file) {
  1383. if (!file.exists()) {
  1384. return true;
  1385. }
  1386. return context.shouldOverwrite(file);
  1387. }
  1388. /*
  1389. * final static String OVERWRITE_MESSAGE = "Overwrite launch script "; final static String OVERWRITE_TITLE = "Overwrite?";
  1390. *
  1391. * final static String[] OVERWRITE_OPTIONS = { "Yes", "No", "Yes to all", "No to all" };
  1392. *
  1393. * final static int OVERWRITE_YES = 0; final static int OVERWRITE_NO = 1; final static int OVERWRITE_ALL = 2; final static int
  1394. * OVERWRITE_NONE = 3;
  1395. *
  1396. * int overwriteState = OVERWRITE_NO; boolean shouldOverwrite(final File file) { if (overwriteState == OVERWRITE_ALL) return
  1397. * true; if (overwriteState == OVERWRITE_NONE) return false;
  1398. *
  1399. * try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { int ret =
  1400. * JOptionPane.showOptionDialog(context.installer.frame, OVERWRITE_MESSAGE+file.getPath(), OVERWRITE_TITLE,
  1401. * JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, OVERWRITE_OPTIONS, OVERWRITE_OPTIONS[OVERWRITE_YES]);
  1402. *
  1403. * overwriteState = ret; } }); } catch (InvocationTargetException ite) { context.handleException(ite.getTargetException()); }
  1404. * catch (InterruptedException ie) { }
  1405. *
  1406. * return overwriteState == OVERWRITE_YES || overwriteState == OVERWRITE_ALL; }
  1407. */
  1408. public void writeScript(String className) throws IOException {
  1409. writeScript(className, true);
  1410. if (context.onWindows()) {
  1411. writeScript(className, false);
  1412. }
  1413. }
  1414. }
  1415. class JarUnpacker {
  1416. InstallContext context;
  1417. InstallPane installPane;
  1418. public JarUnpacker(InstallContext context, InstallPane installPane) {
  1419. this.context = context;
  1420. this.installPane = installPane;
  1421. }
  1422. public File makeOutputFile(String name, File outputFile) {
  1423. int index;
  1424. int lastIndex = 0;
  1425. while ((index = name.indexOf('/', lastIndex)) != -1) {
  1426. outputFile = new File(outputFile, name.substring(lastIndex, index));
  1427. lastIndex = index + 1;
  1428. }
  1429. return new File(outputFile, name.substring(lastIndex));
  1430. }
  1431. final static int BUF_SIZE = 4096;
  1432. public void writeStream(ZipInputStream zis, File outputFile) throws IOException {
  1433. if (outputFile.exists()) {
  1434. if (!context.shouldOverwrite(outputFile)) {
  1435. return;
  1436. }
  1437. }
  1438. installPane.progressMessage("writing " + outputFile.getAbsolutePath());
  1439. outputFile.getParentFile().mkdirs();
  1440. if (context.isTextFile(outputFile)) {
  1441. writeTextStream(zis, outputFile);
  1442. } else {
  1443. writeBinaryStream(zis, outputFile);
  1444. }
  1445. }
  1446. public void writeBinaryStream(ZipInputStream zis, File outputFile) throws IOException {
  1447. byte[] buffer = new byte[BUF_SIZE];
  1448. int nRead = 0;
  1449. OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
  1450. while ((nRead = zis.read(buffer)) != -1) {
  1451. os.write(buffer, 0, nRead);
  1452. installPane.progressBytesWritten(nRead);
  1453. }
  1454. os.close();
  1455. }
  1456. public void writeTextStream(ZipInputStream zis, File outputFile) throws IOException {
  1457. BufferedWriter os = new BufferedWriter(new FileWriter(outputFile));
  1458. BufferedReader r = new BufferedReader(new InputStreamReader(zis, "US-ASCII"));
  1459. String l;
  1460. while ((l = r.readLine()) != null) {
  1461. os.write(l);
  1462. os.newLine();
  1463. installPane.progressBytesWritten(l.length() + 1);
  1464. }
  1465. os.close();
  1466. }
  1467. public void writeEntry(ZipInputStream zis, ZipEntry entry, File outputDir) throws IOException {
  1468. if (entry.isDirectory()) {
  1469. return;
  1470. }
  1471. String name = entry.getName();
  1472. File outputFile = makeOutputFile(name, outputDir);
  1473. writeStream(zis, outputFile);
  1474. }
  1475. public void unpack(String jarName, File outputDir) throws IOException {
  1476. URL url = getClass().getResource(jarName);
  1477. InputStream stream = url.openStream();
  1478. ZipInputStream zis = new ZipInputStream(stream);
  1479. // int i = 0;
  1480. ZipEntry entry;
  1481. while ((entry = zis.getNextEntry()) != null) {
  1482. // final String name = entry.getName();
  1483. writeEntry(zis, entry, outputDir);
  1484. //
  1485. }
  1486. installPane.progressMessage("done writing");
  1487. }
  1488. }