From f07948d4959cfdb81bb0c540ebcbe879df0109fb Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 9 Nov 2009 22:42:32 +0100 Subject: The installer is now waaay smarter on linuxes, and should support, out of the box and automatically, debian and debianesques like ubuntu. --- src/lombok/installer/EclipseFinder.java | 95 +++++-- src/lombok/installer/EclipseLocation.java | 410 +++++++++++++++++------------- src/lombok/installer/Installer.java | 68 ++++- 3 files changed, 361 insertions(+), 212 deletions(-) (limited to 'src/lombok') diff --git a/src/lombok/installer/EclipseFinder.java b/src/lombok/installer/EclipseFinder.java index 07e28484..d54dd691 100644 --- a/src/lombok/installer/EclipseFinder.java +++ b/src/lombok/installer/EclipseFinder.java @@ -38,6 +38,7 @@ import java.util.regex.Pattern; import lombok.Lombok; import lombok.core.Version; +import lombok.installer.EclipseLocation.NotAnEclipseException; /** Utility class for doing various OS-specific operations related to finding Eclipse installations. */ class EclipseFinder { @@ -141,11 +142,8 @@ class EclipseFinder { * * Where 'X' is tried for all local disk drives, unless there's a problem calling fsutil, in which case only * C: is tried. - * - * @return A List of directories that contain 'eclipse.exe'. */ - static List findEclipseOnWindows() { - List eclipses = new ArrayList(); + private static void findEclipseOnWindows(List locations, List problems) { List driveLetters = asList("C"); try { driveLetters = getDrivesOnWindows(); @@ -164,7 +162,13 @@ class EclipseFinder { try { if (dir.getName().toLowerCase().contains("eclipse")) { String eclipseLocation = findEclipseOnWindows1(dir); - if (eclipseLocation != null) eclipses.add(eclipseLocation); + if (eclipseLocation != null) { + try { + locations.add(EclipseLocation.create(eclipseLocation)); + } catch (NotAnEclipseException e) { + problems.add(e); + } + } } } catch (Exception ignore) {} @@ -174,7 +178,13 @@ class EclipseFinder { if (!dir2.isDirectory()) continue; if (dir.getName().toLowerCase().contains("eclipse")) { String eclipseLocation = findEclipseOnWindows1(dir); - if (eclipseLocation != null) eclipses.add(eclipseLocation); + if (eclipseLocation != null) { + try { + locations.add(EclipseLocation.create(eclipseLocation)); + } catch (NotAnEclipseException e) { + problems.add(e); + } + } } } } @@ -182,8 +192,6 @@ class EclipseFinder { } } catch (Exception ignore) {} } - - return eclipses; } /** Checks if the provided directory contains 'eclipse.exe', and if so, returns the directory, otherwise null. */ @@ -196,17 +204,22 @@ class EclipseFinder { * Calls the OS-dependent 'find Eclipse' routine. If the local OS doesn't have a routine written for it, * null is returned. * - * @return List of directories that contain the Eclipse executable. + * @param locations List of valid eclipse locations - provide an empty list; this method will fill it. + * @param problems List of eclipse locations that seem to contain half-baked eclipses that can't be installed. + * Provide an empty list; this method will fill it. */ - static List findEclipses() { + static void findEclipses(List locations, List problems) { switch (getOS()) { case WINDOWS: - return findEclipseOnWindows(); + findEclipseOnWindows(locations, problems); + break; case MAC_OS_X: - return findEclipseOnMac(); + findEclipseOnMac(locations, problems); + break; default: case UNIX: - return null; + findEclipseOnUnix(locations, problems); + break; } } @@ -240,22 +253,68 @@ class EclipseFinder { } } + /** Scans a couple of likely locations on linux. */ + private static void findEclipseOnUnix(List locations, List problems) { + List guesses = new ArrayList(); + + File d; + + d = new File("/usr/bin/eclipse"); + if (d.exists()) guesses.add(d.getPath()); + d = new File("/usr/local/bin/eclipse"); + if (d.exists()) guesses.add(d.getPath()); + d = new File(System.getProperty("user.home", "."), "bin/eclipse"); + if (d.exists()) guesses.add(d.getPath()); + + findEclipseInSubDir("/usr/local/share", guesses); + findEclipseInSubDir("/usr/local", guesses); + findEclipseInSubDir("/usr/share", guesses); + findEclipseInSubDir(System.getProperty("user.home", "."), guesses); + + for (String guess : guesses) { + try { + locations.add(EclipseLocation.create(guess)); + } catch (NotAnEclipseException e) { + problems.add(e); + } + } + } + + private static void findEclipseInSubDir(String dir, List guesses) { + File d = new File(dir); + if (!d.isDirectory()) return; + for (File f : d.listFiles()) { + if (f.isDirectory() && f.getName().toLowerCase().contains("eclipse")) { + File possible = new File(f, "eclipse"); + if (possible.exists()) guesses.add(possible.getAbsolutePath()); + } + } + } + /** * Scans /Applications for any folder named 'Eclipse' */ - static List findEclipseOnMac() { - List eclipses = new ArrayList(); + private static void findEclipseOnMac(List locations, List problems) { for (File dir : new File("/Applications").listFiles()) { if (!dir.isDirectory()) continue; if (dir.getName().toLowerCase().equals("eclipse.app")) { //This would be kind of an unorthodox Eclipse installation, but if Eclipse ever //moves to this more maclike installation concept, our installer can still handle it. - eclipses.add("/Applications"); + try { + locations.add(EclipseLocation.create("/Applications")); + } catch (NotAnEclipseException e) { + problems.add(e); + } } if (dir.getName().toLowerCase().contains("eclipse")) { - if (new File(dir, "Eclipse.app").exists()) eclipses.add(dir.toString()); + if (new File(dir, "Eclipse.app").exists()) { + try { + locations.add(EclipseLocation.create(dir.toString())); + } catch (NotAnEclipseException e) { + problems.add(e); + } + } } } - return eclipses; } } diff --git a/src/lombok/installer/EclipseLocation.java b/src/lombok/installer/EclipseLocation.java index e925f158..b1de37d5 100644 --- a/src/lombok/installer/EclipseLocation.java +++ b/src/lombok/installer/EclipseLocation.java @@ -30,6 +30,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -53,7 +54,8 @@ final class EclipseLocation { else OS_NEWLINE = "\n"; } - private final File path; + private final String name; + private final File eclipseIniPath; private volatile boolean hasLombok; /** Toggling the 'selected' checkbox in the GUI is tracked via this boolean */ @@ -78,56 +80,128 @@ final class EclipseLocation { } } + private EclipseLocation(String nameOfLocation, File pathToEclipseIni) throws NotAnEclipseException { + this.name = nameOfLocation; + this.eclipseIniPath = pathToEclipseIni; + try { + this.hasLombok = checkForLombok(eclipseIniPath); + } catch (IOException e) { + throw new NotAnEclipseException( + "I can't read the configuration file of the Eclipse installed at " + name + "\n" + + "You may need to run this installer with root privileges if you want to modify that Eclipse.", e); + } + } + + private static final List eclipseExecutableNames = Collections.unmodifiableList(Arrays.asList( + "eclipse.app", "eclipse.exe", "eclipse")); + /** - * Create a new EclipseLocation by pointing at either the directory contain the Eclipse executable, or the executable itself. + * Create a new EclipseLocation by pointing at either the directory contain the Eclipse executable, or the executable itself, + * or an eclipse.ini file. * * @throws NotAnEclipseException If this isn't an Eclipse executable or a directory with an Eclipse executable. */ - EclipseLocation(String path) throws NotAnEclipseException { + public static EclipseLocation create(String path) throws NotAnEclipseException { if (path == null) throw new NullPointerException("path"); File p = new File(path); - if (!p.exists()) throw new NotAnEclipseException("File does not exist: " + path, null); - final String execName = EclipseFinder.getEclipseExecutableName(); + if (!p.exists()) throw new NotAnEclipseException("File does not exist: " + path, null); if (p.isDirectory()) { - for (File f : p.listFiles()) { - if (f.getName().equalsIgnoreCase(execName)) { - p = f; - break; - } + for (String possibleExeName : eclipseExecutableNames) { + File f = new File(p, possibleExeName); + if (f.exists()) return findEclipseIniFromExe(f, 0); } + + File f = new File(p, "eclipse.ini"); + if (f.exists()) return new EclipseLocation(getFilePath(p), f); } - if (!p.exists() || !p.getName().equalsIgnoreCase(execName)) { - throw new NotAnEclipseException("This path does not appear to contain an Eclipse installation: " + p, null); + if (p.isFile()) { + if (p.getName().equalsIgnoreCase("eclipse.ini")) { + return new EclipseLocation(getFilePath(p.getParentFile()), p); + } + + if (eclipseExecutableNames.contains(p.getName().toLowerCase())) { + return findEclipseIniFromExe(p, 0); + } } - this.path = p; + throw new NotAnEclipseException("This path does not appear to contain an Eclipse installation: " + p, null); + } + + private static EclipseLocation findEclipseIniFromExe(File exePath, int loopCounter) throws NotAnEclipseException { + System.out.println(exePath); + /* Try looking for eclipse.ini as sibling to the executable */ { + File ini = new File(exePath.getParentFile(), "eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(getFilePath(exePath), ini); + } + + /* Try looking for Eclipse/app/Contents/MacOS/eclipse.ini as sibling to executable; this works on Mac OS X. */ { + File ini = new File(exePath.getParentFile(), "Eclipse.app/Contents/MacOS/eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(getFilePath(exePath), ini); + } + + /* If executable is a soft link, follow it and retry. */ { + if (loopCounter < 50) { + try { + String oPath = exePath.getAbsolutePath(); + String nPath = exePath.getCanonicalPath(); + if (!oPath.equals(nPath)) try { + return findEclipseIniFromExe(new File(nPath), loopCounter +1); + } catch (NotAnEclipseException ignore) { + // Unlinking didn't help find an eclipse, so continue. + } + } catch (IOException ignore) { /* okay, that didn't work, assume it isn't a soft link then. */ } + } + } + + /* If executable is a linux LSB-style path, then look in the usual places that package managers like apt-get use.*/ { + String path = exePath.getAbsolutePath(); + try { + path = exePath.getCanonicalPath(); + } catch (IOException ignore) { /* We'll stick with getAbsolutePath()'s result then. */ } + + if (path.equals("/usr/bin/eclipse") || path.equals("/bin/eclipse") || path.equals("/usr/local/bin/eclipse")) { + File ini = new File("/usr/lib/eclipse/eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(path, ini); + ini = new File("/usr/local/lib/eclipse/eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(path, ini); + ini = new File("/usr/local/etc/eclipse/eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(path, ini); + ini = new File("/etc/eclipse.ini"); + if (ini.isFile()) return new EclipseLocation(path, ini); + } + } + + /* If we get this far, we lose. */ + throw new NotAnEclipseException("This path does not appear to contain an eclipse installation: " + exePath, null); + } + + public static String getFilePath(File p) { try { - this.hasLombok = checkForLombok(); + return p.getCanonicalPath(); } catch (IOException e) { - throw new NotAnEclipseException( - "I can't read the configuration file of the Eclipse installed at " + this.path.getAbsolutePath() + "\n" + - "You may need to run this installer with root privileges if you want to modify that Eclipse.", e); + String x = p.getAbsolutePath(); + return x == null ? p.getPath() : x; } } @Override public int hashCode() { - return path.hashCode(); + return eclipseIniPath.hashCode(); } @Override public boolean equals(Object o) { if (!(o instanceof EclipseLocation)) return false; - return ((EclipseLocation)o).path.equals(path); + return ((EclipseLocation)o).eclipseIniPath.equals(eclipseIniPath); } /** - * Returns the absolute path to the Eclipse executable. + * Returns the name of this location; generally the path to the eclipse executable. * * Executables: "eclipse.exe" (Windows), "Eclipse.app" (Mac OS X), "eclipse" (Linux and other unixes). */ - String getPath() { - return path.getAbsolutePath(); + String getName() { + return name; } /** @@ -137,30 +211,13 @@ final class EclipseLocation { return hasLombok; } - /** - * Returns the various directories that can contain the 'eclipse.ini' file. - * Returns multiple directories because there are a few different ways Eclipse is packaged. - */ - private List getTargetDirs() { - return Arrays.asList(path.getParentFile(), new File(new File(path, "Contents"), "MacOS")); - } - - private boolean checkForLombok() throws IOException { - for (File targetDir : getTargetDirs()) { - if (checkForLombok0(targetDir)) return true; - } - - return false; - } - private final Pattern JAVA_AGENT_LINE_MATCHER = Pattern.compile( "^\\-javaagent\\:.*lombok.*\\.jar$", Pattern.CASE_INSENSITIVE); private final Pattern BOOTCLASSPATH_LINE_MATCHER = Pattern.compile( "^\\-Xbootclasspath\\/a\\:(.*lombok.*\\.jar.*)$", Pattern.CASE_INSENSITIVE); - private boolean checkForLombok0(File dir) throws IOException { - File iniFile = new File(dir, "eclipse.ini"); + private boolean checkForLombok(File iniFile) throws IOException { if (!iniFile.exists()) return false; FileInputStream fis = new FileInputStream(iniFile); try { @@ -185,6 +242,16 @@ final class EclipseLocation { } } + /** Returns directories that may contain lombok.jar files that need to be deleted. */ + private List getUninstallDirs() { + List result = new ArrayList(); + File x = new File(name); + if (!x.isDirectory()) x = x.getParentFile(); + if (x.isDirectory()) result.add(x); + result.add(eclipseIniPath.getParentFile()); + return result; + } + /** * Uninstalls lombok from this location. * It's a no-op if lombok wasn't there in the first place, @@ -194,7 +261,7 @@ final class EclipseLocation { * bugs in the uninstall code will probably throw other exceptions; this is intentional. */ void uninstall() throws UninstallException { - for (File dir : getTargetDirs()) { + for (File dir : getUninstallDirs()) { File lombokJar = new File(dir, "lombok.jar"); if (lombokJar.exists()) { if (!lombokJar.delete()) throw new UninstallException( @@ -209,52 +276,51 @@ final class EclipseLocation { "Can't delete " + agentJar.getAbsolutePath() + generateWriteErrorMessage(), null); } } - - File iniFile = new File(dir, "eclipse.ini"); - StringBuilder newContents = new StringBuilder(); - if (iniFile.exists()) { + } + + StringBuilder newContents = new StringBuilder(); + if (eclipseIniPath.exists()) { + try { + FileInputStream fis = new FileInputStream(eclipseIniPath); try { - FileInputStream fis = new FileInputStream(iniFile); - try { - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - String line; - while ((line = br.readLine()) != null) { - if (JAVA_AGENT_LINE_MATCHER.matcher(line).matches()) continue; - Matcher m = BOOTCLASSPATH_LINE_MATCHER.matcher(line); - if (m.matches()) { - StringBuilder elemBuilder = new StringBuilder(); - elemBuilder.append("-Xbootclasspath/a:"); - boolean first = true; - for (String elem : m.group(1).split(Pattern.quote(File.pathSeparator))) { - if (elem.toLowerCase().endsWith("lombok.jar")) continue; - /* legacy code -see previous comment that starts with 'legacy' */ { - if (elem.toLowerCase().endsWith("lombok.eclipse.agent.jar")) continue; - } - if (first) first = false; - else elemBuilder.append(File.pathSeparator); - elemBuilder.append(elem); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + String line; + while ((line = br.readLine()) != null) { + if (JAVA_AGENT_LINE_MATCHER.matcher(line).matches()) continue; + Matcher m = BOOTCLASSPATH_LINE_MATCHER.matcher(line); + if (m.matches()) { + StringBuilder elemBuilder = new StringBuilder(); + elemBuilder.append("-Xbootclasspath/a:"); + boolean first = true; + for (String elem : m.group(1).split(Pattern.quote(File.pathSeparator))) { + if (elem.toLowerCase().endsWith("lombok.jar")) continue; + /* legacy code -see previous comment that starts with 'legacy' */ { + if (elem.toLowerCase().endsWith("lombok.eclipse.agent.jar")) continue; } - if (!first) newContents.append(elemBuilder.toString()).append(OS_NEWLINE); - continue; + if (first) first = false; + else elemBuilder.append(File.pathSeparator); + elemBuilder.append(elem); } - - newContents.append(line).append(OS_NEWLINE); + if (!first) newContents.append(elemBuilder.toString()).append(OS_NEWLINE); + continue; } - } finally { - fis.close(); + newContents.append(line).append(OS_NEWLINE); } - FileOutputStream fos = new FileOutputStream(iniFile); - try { - fos.write(newContents.toString().getBytes()); - } finally { - fos.close(); - } - } catch (IOException e) { - throw new UninstallException("Cannot uninstall lombok from " + path.getAbsolutePath() + - generateWriteErrorMessage(), e); + } finally { + fis.close(); + } + + FileOutputStream fos = new FileOutputStream(eclipseIniPath); + try { + fos.write(newContents.toString().getBytes()); + } finally { + fos.close(); } + } catch (IOException e) { + throw new UninstallException("Cannot uninstall lombok from " + name + + generateWriteErrorMessage(), e); } } } @@ -294,8 +360,6 @@ final class EclipseLocation { * bugs in the install code will probably throw other exceptions; this is intentional. */ void install() throws InstallException { - List failedDirs = new ArrayList(); - // For whatever reason, relative paths in your eclipse.ini file don't work on linux, but only for -javaagent. // If someone knows how to fix this, please do so, as this current hack solution (putting the absolute path // to the jar files in your eclipse.ini) means you can't move your eclipse around on linux without lombok @@ -303,118 +367,104 @@ final class EclipseLocation { boolean fullPathRequired = EclipseFinder.getOS() == EclipseFinder.OS.UNIX; boolean installSucceeded = false; - for (File dir : getTargetDirs()) { - File iniFile = new File(dir, "eclipse.ini"); - StringBuilder newContents = new StringBuilder(); - if (!iniFile.exists()) failedDirs.add(dir); - else { - //If 'installSucceeded' is true here, something very weird is going on, but instrumenting all of them - //is no less bad than aborting, and this situation should be rare to the point of non-existence. - - File lombokJar = new File(iniFile.getParentFile(), "lombok.jar"); - - File ourJar = EclipseFinder.findOurJar(); - byte[] b = new byte[524288]; - boolean readSucceeded = false; + StringBuilder newContents = new StringBuilder(); + //If 'installSucceeded' is true here, something very weird is going on, but instrumenting all of them + //is no less bad than aborting, and this situation should be rare to the point of non-existence. + + File lombokJar = new File(eclipseIniPath.getParentFile(), "lombok.jar"); + + File ourJar = EclipseFinder.findOurJar(); + byte[] b = new byte[524288]; + boolean readSucceeded = true; + try { + FileOutputStream out = new FileOutputStream(lombokJar); + try { + readSucceeded = false; + InputStream in = new FileInputStream(ourJar); try { - FileOutputStream out = new FileOutputStream(lombokJar); - try { - InputStream in = new FileInputStream(ourJar); - try { - while (true) { - int r = in.read(b); - if (r == -1) break; - if (r > 0) readSucceeded = true; - out.write(b, 0, r); - } - } finally { - in.close(); - } - } finally { - out.close(); + while (true) { + int r = in.read(b); + if (r == -1) break; + if (r > 0) readSucceeded = true; + out.write(b, 0, r); } - } catch (IOException e) { - try { - lombokJar.delete(); - } catch (Throwable ignore) {} - if (!readSucceeded) throw new InstallException("I can't read my own jar file. I think you've found a bug in this installer! I suggest you restart it " + - "and use the 'what do I do' link, to manually install lombok. And tell us about this. Thanks!", e); - throw new InstallException("I can't write to your Eclipse directory at " + - iniFile.getParentFile().getAbsolutePath() + - generateWriteErrorMessage(), e); - } - - /* legacy - delete lombok.eclipse.agent.jar if its there, which lombok no longer uses. */ { - new File(lombokJar.getParentFile(), "lombok.eclipse.agent.jar").delete(); + } finally { + in.close(); } - - try { - FileInputStream fis = new FileInputStream(iniFile); - try { - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - String line; - while ((line = br.readLine()) != null) { - if (JAVA_AGENT_LINE_MATCHER.matcher(line).matches()) continue; - Matcher m = BOOTCLASSPATH_LINE_MATCHER.matcher(line); - if (m.matches()) { - StringBuilder elemBuilder = new StringBuilder(); - elemBuilder.append("-Xbootclasspath/a:"); - boolean first = true; - for (String elem : m.group(1).split(Pattern.quote(File.pathSeparator))) { - if (elem.toLowerCase().endsWith("lombok.jar")) continue; - /* legacy code -see previous comment that starts with 'legacy' */ { - if (elem.toLowerCase().endsWith("lombok.eclipse.agent.jar")) continue; - } - if (first) first = false; - else elemBuilder.append(File.pathSeparator); - elemBuilder.append(elem); - } - if (!first) newContents.append(elemBuilder.toString()).append(OS_NEWLINE); - continue; + } finally { + out.close(); + } + } catch (IOException e) { + try { + lombokJar.delete(); + } catch (Throwable ignore) { /* Nothing we can do about that. */ } + if (!readSucceeded) throw new InstallException( + "I can't read my own jar file. I think you've found a bug in this installer!\nI suggest you restart it " + + "and use the 'what do I do' link, to manually install lombok. Also, tell us about this at:\n" + + "http://groups.google.com/group/project-lombok - Thanks!", e); + throw new InstallException("I can't write to your Eclipse directory at " + name + generateWriteErrorMessage(), e); + } + + /* legacy - delete lombok.eclipse.agent.jar if its there, which lombok no longer uses. */ { + new File(lombokJar.getParentFile(), "lombok.eclipse.agent.jar").delete(); + } + + try { + FileInputStream fis = new FileInputStream(eclipseIniPath); + try { + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + String line; + while ((line = br.readLine()) != null) { + if (JAVA_AGENT_LINE_MATCHER.matcher(line).matches()) continue; + Matcher m = BOOTCLASSPATH_LINE_MATCHER.matcher(line); + if (m.matches()) { + StringBuilder elemBuilder = new StringBuilder(); + elemBuilder.append("-Xbootclasspath/a:"); + boolean first = true; + for (String elem : m.group(1).split(Pattern.quote(File.pathSeparator))) { + if (elem.toLowerCase().endsWith("lombok.jar")) continue; + /* legacy code -see previous comment that starts with 'legacy' */ { + if (elem.toLowerCase().endsWith("lombok.eclipse.agent.jar")) continue; } - - newContents.append(line).append(OS_NEWLINE); + if (first) first = false; + else elemBuilder.append(File.pathSeparator); + elemBuilder.append(elem); } - - } finally { - fis.close(); + if (!first) newContents.append(elemBuilder.toString()).append(OS_NEWLINE); + continue; } - String fullPathToLombok = fullPathRequired ? (lombokJar.getParentFile().getCanonicalPath() + File.separator) : ""; - - newContents.append(String.format( - "-javaagent:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE); - newContents.append(String.format( - "-Xbootclasspath/a:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE); - - FileOutputStream fos = new FileOutputStream(iniFile); - try { - fos.write(newContents.toString().getBytes()); - } finally { - fos.close(); - } - installSucceeded = true; - } catch (IOException e) { - throw new InstallException("Cannot install lombok at " + path.getAbsolutePath() + generateWriteErrorMessage(), e); - } finally { - if (!installSucceeded) try { - lombokJar.delete(); - } catch (Throwable ignore) {} + newContents.append(line).append(OS_NEWLINE); } + + } finally { + fis.close(); + } + + String fullPathToLombok = fullPathRequired ? (lombokJar.getParentFile().getCanonicalPath() + File.separator) : ""; + + newContents.append(String.format( + "-javaagent:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE); + newContents.append(String.format( + "-Xbootclasspath/a:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE); + + FileOutputStream fos = new FileOutputStream(eclipseIniPath); + try { + fos.write(newContents.toString().getBytes()); + } finally { + fos.close(); } + installSucceeded = true; + } catch (IOException e) { + throw new InstallException("Cannot install lombok at " + name + generateWriteErrorMessage(), e); + } finally { + if (!installSucceeded) try { + lombokJar.delete(); + } catch (Throwable ignore) {} } if (!installSucceeded) { throw new InstallException("I can't find the eclipse.ini file. Is this a real Eclipse installation?", null); } - - for (File dir : failedDirs) { - /* Legacy code - lombok's installer used to install in other places. To keep the user's eclipse dir clean, we'll delete these. */ { - try { - new File(dir, "lombok.jar").delete(); - new File(dir, "lombok.eclipse.agent.jar").delete(); - } catch (Throwable ignore) {} - } - } } } diff --git a/src/lombok/installer/Installer.java b/src/lombok/installer/Installer.java index 4b0f7699..fd90c6a0 100644 --- a/src/lombok/installer/Installer.java +++ b/src/lombok/installer/Installer.java @@ -95,6 +95,50 @@ public class Installer { private JButton installButton; public static void main(String[] args) { + if (args.length > 0 && args[0].equals("install")) { + if (args.length < 3 || !args[1].equals("eclipse")) { + System.err.println("Run java -jar lombok.jar install eclipse path/to/eclipse/executable"); + System.exit(1); + } + String path = args[2]; + try { + EclipseLocation loc = EclipseLocation.create(path); + loc.install(); + System.out.println("Installed to: " + loc.getName()); + System.exit(0); + } catch (NotAnEclipseException e) { + System.err.println("Not a valid eclipse location:"); + System.err.println(e.getMessage()); + System.exit(2); + } catch (InstallException e) { + System.err.println("Installation failed:"); + System.err.println(e.getMessage()); + System.exit(1); + } + } + + if (args.length > 0 && args[0].equals("uninstall")) { + if (args.length < 3 || !args[1].equals("eclipse")) { + System.err.println("Run java -jar lombok.jar uninstall eclipse path/to/eclipse/executable"); + System.exit(1); + } + String path = args[2]; + try { + EclipseLocation loc = EclipseLocation.create(path); + loc.uninstall(); + System.out.println("Uninstalled from: " + loc.getName()); + System.exit(0); + } catch (NotAnEclipseException e) { + System.err.println("Not a valid eclipse location:"); + System.err.println(e.getMessage()); + System.exit(2); + } catch (UninstallException e) { + System.err.println("Uninstall failed:"); + System.err.println(e.getMessage()); + System.exit(1); + } + } + if (EclipseFinder.getOS() == OS.MAC_OS_X) { System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Lombok Installer"); System.setProperty("com.apple.macos.use-file-dialog-packages", "true"); @@ -132,7 +176,10 @@ public class Installer { "graphical computer system - this message is being shown because your terminal is not graphics capable." + "If you are just using 'javac' or a tool that calls on javac, no installation is neccessary; just " + "make sure lombok.jar is in the classpath when you compile. Example:\n\n" + - " java -cp lombok.jar MyCode.java", Version.getVersion(), ABOUT_LOMBOK_URL); + " java -cp lombok.jar MyCode.java\n\n\n" + + "If for whatever reason you can't run the graphical installer but you do want to install lombok into eclipse," + + "start this jar with the following syntax:\n\n" + + " java -jar lombok.jar install eclipse path/to/your/eclipse/executable", Version.getVersion(), ABOUT_LOMBOK_URL); } /** @@ -307,17 +354,9 @@ public class Installer { Thread findEclipsesThread = new Thread() { @Override public void run() { try { - final List eclipses = EclipseFinder.findEclipses(); final List locations = new ArrayList(); final List problems = new ArrayList(); - - if (eclipses != null) { - for (String eclipse : eclipses) try { - locations.add(new EclipseLocation(eclipse)); - } catch (NotAnEclipseException e) { - problems.add(e); - } - } + EclipseFinder.findEclipses(locations, problems); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -335,7 +374,7 @@ public class Installer { loadingExpl.setVisible(false); - if (eclipses == null) { + if (locations.size() + problems.size() == 0) { JOptionPane.showMessageDialog(appWindow, "I don't know how to automatically find Eclipse installations on this platform.\n" + "Please use the 'Specify Eclipse Location...' button to manually point out the\n" + @@ -380,6 +419,7 @@ public class Installer { chooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { if (f.getName().equalsIgnoreCase(exeName)) return true; + if (f.getName().equalsIgnoreCase("eclipse.ini")) return true; if (f.isDirectory()) return true; return false; @@ -398,7 +438,7 @@ public class Installer { if (file != null) { try { - eclipsesList.addEclipse(new EclipseLocation(file)); + eclipsesList.addEclipse(EclipseLocation.create(file)); } catch (NotAnEclipseException e) { e.showDialog(appWindow); } catch (Throwable t) { @@ -479,7 +519,7 @@ public class Installer { uninstallBox.removeAll(); uninstallBox.add(Box.createRigidArea(new Dimension(1, 16))); for (EclipseLocation location : locations) { - JLabel label = new JLabel(location.getPath()); + JLabel label = new JLabel(location.getName()); label.setFont(label.getFont().deriveFont(Font.BOLD)); uninstallBox.add(label); } @@ -638,7 +678,7 @@ public class Installer { if (locations.contains(location)) return; Box box = Box.createHorizontalBox(); box.setBackground(Color.WHITE); - final JCheckBox checkbox = new JCheckBox(location.getPath()); + final JCheckBox checkbox = new JCheckBox(location.getName()); checkbox.setBackground(Color.WHITE); box.add(checkbox); checkbox.setSelected(true); -- cgit