diff options
Diffstat (limited to 'src/lombok/installer/EclipseLocation.java')
-rw-r--r-- | src/lombok/installer/EclipseLocation.java | 116 |
1 files changed, 104 insertions, 12 deletions
diff --git a/src/lombok/installer/EclipseLocation.java b/src/lombok/installer/EclipseLocation.java index 400b5606..66bba5b8 100644 --- a/src/lombok/installer/EclipseLocation.java +++ b/src/lombok/installer/EclipseLocation.java @@ -1,3 +1,24 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package lombok.installer; import java.io.BufferedReader; @@ -7,6 +28,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.jar.JarFile; @@ -17,6 +39,11 @@ import java.util.zip.ZipEntry; import javax.swing.JFrame; import javax.swing.JOptionPane; +/** + * Represents an eclipse installation. + * An instance can figure out if an eclipse installation has been lombok-ified, and can + * install and uninstall lombok from the eclipse installation. + */ final class EclipseLocation { private static final String OS_NEWLINE; @@ -30,8 +57,14 @@ final class EclipseLocation { private final File path; private volatile boolean hasLombok; + + /** Toggling the 'selected' checkbox in the GUI is tracked via this boolean */ boolean selected = true; + /** + * Thrown when creating a new EclipseLocation with a path object that doesn't, in fact, + * point at an eclipse installation. + */ final class NotAnEclipseException extends Exception { private static final long serialVersionUID = 1L; @@ -39,11 +72,19 @@ final class EclipseLocation { super(message, cause); } - public void showDialog(JFrame appWindow) { + /** + * Renders a message dialog with information about what went wrong. + */ + void showDialog(JFrame appWindow) { JOptionPane.showMessageDialog(appWindow, getMessage(), "Cannot configure eclipse installation", JOptionPane.WARNING_MESSAGE); } } + /** + * Create a new EclipseLocation by pointing at either the directory contain the eclipse executable, or the executable itself. + * + * @throws NotAnEclipseException If this isn't an eclipse executable or a directory with an eclipse executable. + */ EclipseLocation(String path) throws NotAnEclipseException { if ( path == null ) throw new NullPointerException("path"); File p = new File(path); @@ -59,6 +100,10 @@ final class EclipseLocation { } } + if ( !p.exists() || !p.getName().equalsIgnoreCase(execName) ) { + throw new NotAnEclipseException("This path does not appear to contain an eclipse installation: " + p, null); + } + this.path = p; try { this.hasLombok = checkForLombok(); @@ -69,23 +114,35 @@ final class EclipseLocation { } } - public int hashCode() { + @Override public int hashCode() { return path.hashCode(); } - public boolean equals(Object o) { + @Override public boolean equals(Object o) { if ( !(o instanceof EclipseLocation) ) return false; return ((EclipseLocation)o).path.equals(path); } - public String getPath() { + /** + * Returns the absolute path to the eclipse executable. + * + * Executables: "eclipse.exe" (Windows), "Eclipse.app" (Mac OS X), "eclipse" (Linux and other unixes). + */ + String getPath() { return path.getAbsolutePath(); } - public boolean hasLombok() { + /** + * @return true if the eclipse installation has been instrumented with lombok. + */ + boolean hasLombok() { 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")); } @@ -121,7 +178,8 @@ final class EclipseLocation { } } - public class UninstallException extends Exception { + /** Thrown when uninstalling lombok fails. */ + class UninstallException extends Exception { private static final long serialVersionUID = 1L; public UninstallException(String message, Throwable cause) { @@ -129,7 +187,15 @@ final class EclipseLocation { } } - public void uninstall() throws UninstallException { + /** + * Uninstalls lombok from this location. + * It's a no-op if lombok wasn't there in the first place, + * and it will remove a half-succeeded lombok installation as well. + * + * @throws UninstallException If there's an obvious I/O problem that is preventing installation. + * bugs in the uninstall code will probably throw other exceptions; this is intentional. + */ + void uninstall() throws UninstallException { for ( File dir : getTargetDirs() ) { File lombokJar = new File(dir, "lombok.jar"); if ( lombokJar.exists() ) { @@ -194,7 +260,8 @@ final class EclipseLocation { } } - public class InstallException extends Exception { + /** Thrown when installing lombok fails. */ + class InstallException extends Exception { private static final long serialVersionUID = 1L; public InstallException(String message, Throwable cause) { @@ -202,18 +269,31 @@ final class EclipseLocation { } } - public void install() throws InstallException { + /** + * Install lombok into the eclipse at this location. + * If lombok is already there, it is overwritten neatly (upgrade mode). + * + * @throws InstallException If there's an obvious I/O problem that is preventing installation. + * bugs in the install code will probably throw other exceptions; this is intentional. + */ + void install() throws InstallException { + List<File> failedDirs = new ArrayList<File>(); + + boolean installSucceeded = false; for ( File dir : getTargetDirs() ) { File iniFile = new File(dir, "eclipse.ini"); StringBuilder newContents = new StringBuilder(); - if ( iniFile.exists() ) { + 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 agentJar = new File(iniFile.getParentFile(), "lombok.eclipse.agent.jar"); File ourJar = EclipseFinder.findOurJar(); byte[] b = new byte[524288]; boolean readSucceeded = false; - boolean installSucceeded = false; try { JarFile jar = new JarFile(ourJar); @@ -297,7 +377,6 @@ final class EclipseLocation { fos.close(); } installSucceeded = true; - } catch ( IOException e ) { throw new InstallException("Cannot install lombok at " + path.getAbsolutePath() + " probably because this installer does not have the access rights to do so.", e); @@ -309,5 +388,18 @@ final class EclipseLocation { } } } + + if ( !installSucceeded ) { + throw new InstallException("I can't find the eclipse.ini file. Is this a real eclipse installation?", null); + } + + for ( File dir : failedDirs ) { + //If we're updating the old installation might have worked by putting the lombok jars in a different place. + //We'll delete these old files. + try { + new File(dir, "lombok.jar").delete(); + new File(dir, "lombok.eclipse.agent.jar").delete(); + } catch ( Throwable ignore ) {} + } } } |