aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/installer/EclipseLocation.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-11-09 22:42:32 +0100
committerReinier Zwitserloot <reinier@tipit.to>2009-11-09 22:42:32 +0100
commitf07948d4959cfdb81bb0c540ebcbe879df0109fb (patch)
tree5416e32115bc32b72f0e0df99a199534c32cf647 /src/lombok/installer/EclipseLocation.java
parent9830a2ba02bbed18f773216888bc21c1ceb15995 (diff)
downloadlombok-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.java410
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) {}
- }
- }
}
}