diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-09 22:42:32 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-11-09 22:42:32 +0100 |
commit | f07948d4959cfdb81bb0c540ebcbe879df0109fb (patch) | |
tree | 5416e32115bc32b72f0e0df99a199534c32cf647 /src/lombok/installer/EclipseLocation.java | |
parent | 9830a2ba02bbed18f773216888bc21c1ceb15995 (diff) | |
download | lombok-f07948d4959cfdb81bb0c540ebcbe879df0109fb.tar.gz lombok-f07948d4959cfdb81bb0c540ebcbe879df0109fb.tar.bz2 lombok-f07948d4959cfdb81bb0c540ebcbe879df0109fb.zip |
The installer is now waaay smarter on linuxes, and should support, out of the box and automatically, debian and debianesques like ubuntu.
Diffstat (limited to 'src/lombok/installer/EclipseLocation.java')
-rw-r--r-- | src/lombok/installer/EclipseLocation.java | 410 |
1 files changed, 230 insertions, 180 deletions
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<String> 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<File> 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<File> getUninstallDirs() { + List<File> result = new ArrayList<File>(); + 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<File> failedDirs = new ArrayList<File>(); - // 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) {} - } - } } } |