diff options
| -rw-r--r-- | build.xml | 23 | ||||
| -rw-r--r-- | src/lombok/core/ShowUserHelp.java | 32 | ||||
| -rw-r--r-- | src/lombok/core/Version.java | 2 | ||||
| -rw-r--r-- | src/lombok/installer/EclipseFinder.java | 146 | ||||
| -rw-r--r-- | src/lombok/installer/EclipseLocation.java | 313 | ||||
| -rw-r--r-- | src/lombok/installer/InstallerWindow.java | 732 | ||||
| -rw-r--r-- | src/lombok/installer/loading.gif | bin | 0 -> 2248 bytes | |||
| -rw-r--r-- | src/lombok/installer/lombokIcon.png | bin | 0 -> 863 bytes | |||
| -rw-r--r-- | src/lombok/installer/lombokText.png | bin | 0 -> 3055 bytes | |||
| -rw-r--r-- | src/lombok/installer/lombokText.svg | 58 |
10 files changed, 1242 insertions, 64 deletions
@@ -40,6 +40,14 @@ <classpath refid="lombok.deps.path" /> <classpath refid="lombok.libs.path" /> </javac> + <copy todir="build/lombok"> + <fileset dir="src"> + <exclude name="**/*.java" /> + <exclude name="**/*.class" /> + <exclude name="**/*.svg" /> + </fileset> + </copy> + <mkdir dir="build/lombok/META-INF" /> <mkdir dir="build/lombok/META-INF/services" /> <echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.javac.apt.Processor</echo> @@ -78,18 +86,21 @@ <target name="dist" depends="clean, compile, getVersion, unpackLibs"> <mkdir dir="dist" /> - <jar basedir="build/lombok" destfile="dist/lombok-${lombok.version}.jar"> - <manifest> - <attribute name="Main-Class" value="lombok.core.ShowUserHelp" /> - </manifest> - </jar> <jar basedir="build/eclipse.agent" destfile="dist/lombok.eclipse.agent-${lombok.version}.jar"> <manifest> <attribute name="Premain-Class" value="lombok.eclipse.agent.EclipsePatcher" /> <attribute name="Can-Redefine-Classes" value="true" /> </manifest> </jar> - <copy file="dist/lombok-${lombok.version}.jar" tofile="dist/lombok.jar" /> <copy file="dist/lombok.eclipse.agent-${lombok.version}.jar" tofile="dist/lombok.eclipse.agent.jar" /> + <jar destfile="dist/lombok-${lombok.version}.jar"> + <fileset dir="build/lombok" /> + <fileset dir="dist" includes="lombok.eclipse.agent.jar" /> + + <manifest> + <attribute name="Main-Class" value="lombok.installer.InstallerWindow" /> + </manifest> + </jar> + <copy file="dist/lombok-${lombok.version}.jar" tofile="dist/lombok.jar" /> </target> </project> diff --git a/src/lombok/core/ShowUserHelp.java b/src/lombok/core/ShowUserHelp.java deleted file mode 100644 index 443de833..00000000 --- a/src/lombok/core/ShowUserHelp.java +++ /dev/null @@ -1,32 +0,0 @@ -package lombok.core; - -import java.net.URI; - -/** - * This class is used as main class for the lombok jar; this way, if the jar is run as java app, the user is pointed - * at documentation about lombok. - */ -public class ShowUserHelp { - private static final URI ABOUT_LOMBOK_URL = URI.create("http://wiki.github.com/rzwitserloot/lombok"); - - public static void main(String[] args) { - boolean browserOpened = false; - try { - //java.awt.Desktop doesn't exist in 1.5, and for IDE's sakes, we may want to work in java1.5 someday, so... - Object desktop = Class.forName("java.awt.Desktop").getMethod("getDesktop").invoke(null); - Class.forName("java.awt.Desktop").getMethod("browse", URI.class).invoke(desktop, ABOUT_LOMBOK_URL); - browserOpened = true; - } catch ( Exception ignore ) {} - - String version = Version.getVersion(); - final String nextStep = browserOpened ? "See your browser window" : - String.format("Browse to %s", ABOUT_LOMBOK_URL); - - System.out.printf("About lombok v%s\n" + - "Lombok makes java better by providing very spicy additions to the Java programming language," + - "such as using @Getter to automatically generate a getter method for any field.\n\n%s" + - " for more information about the lombok project, and how to" + - "install it into your programming environment. If you are just using javac (the java compiler)," + - "just use this jar, no further steps needed.", version, nextStep); - } -} diff --git a/src/lombok/core/Version.java b/src/lombok/core/Version.java index eff6b151..cb349aaf 100644 --- a/src/lombok/core/Version.java +++ b/src/lombok/core/Version.java @@ -1,7 +1,7 @@ package lombok.core; public class Version { - private static final String VERSION = "0.3.5"; + private static final String VERSION = "0.4"; private Version() { //Prevent instantiation diff --git a/src/lombok/installer/EclipseFinder.java b/src/lombok/installer/EclipseFinder.java new file mode 100644 index 00000000..1ca82440 --- /dev/null +++ b/src/lombok/installer/EclipseFinder.java @@ -0,0 +1,146 @@ +package lombok.installer; + +import static java.util.Arrays.asList; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import lombok.Lombok; + +public class EclipseFinder { + public static File findOurJar() { + try { + URI uri = EclipseFinder.class.getResource("/" + EclipseFinder.class.getName().replace('.', '/') + ".class").toURI(); + Pattern p = Pattern.compile("^jar:file:([^\\!]+)\\!.*\\.class$"); + System.out.println(uri.toString()); + Matcher m = p.matcher(uri.toString()); + if ( !m.matches() ) return new File("lombok.jar"); + String rawUri = m.group(1); + return new File(URLDecoder.decode(rawUri, Charset.defaultCharset().name())); + } catch ( Exception e ) { + throw Lombok.sneakyThrow(e); + } + } + + public static List<String> getDrivesOnWindows() throws IOException { + ProcessBuilder builder = new ProcessBuilder("c:\\windows\\system32\\fsutil.exe", "fsinfo", "drives"); + builder.redirectErrorStream(true); + Process process = builder.start(); + InputStream in = process.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1")); + + List<String> drives = new ArrayList<String>(); + + String line; + while ( (line = br.readLine()) != null ) { + if ( line.startsWith("Drives: ") ) { + line = line.substring(8); + for ( String driveLetter : line.split("\\:\\\\\\s*") ) drives.add(driveLetter.trim()); + } + } + + Iterator<String> it = drives.iterator(); + while ( it.hasNext() ) { + if ( !isLocalDriveOnWindows(it.next()) ) it.remove(); + } + + return drives; + } + + public static boolean isLocalDriveOnWindows(String driveLetter) { + if ( driveLetter == null || driveLetter.length() == 0 ) return false; + try { + ProcessBuilder builder = new ProcessBuilder("c:\\windows\\system32\\fsutil.exe", "fsinfo", "drivetype", driveLetter + ":"); + builder.redirectErrorStream(true); + Process process = builder.start(); + InputStream in = process.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1")); + + String line; + while ( (line = br.readLine()) != null ) { + if ( line.substring(5).equalsIgnoreCase("Fixed Drive") ) return true; + } + + return false; + } catch ( Exception e ) { + return false; + } + } + + public static List<String> findEclipseOnWindows() { + List<String> eclipses = new ArrayList<String>(); + List<String> driveLetters = asList("C"); + + try { + driveLetters = getDrivesOnWindows(); + } catch ( IOException ignore ) {} + + for ( String letter : driveLetters ) { + File f = new File(letter + ":\\"); + for ( File dir : f.listFiles() ) { + if ( !dir.isDirectory() ) continue; + if ( dir.getName().toLowerCase().contains("eclipse") ) { + String eclipseLocation = findEclipseOnWindows1(dir); + if ( eclipseLocation != null ) eclipses.add(eclipseLocation); + } + if ( dir.getName().toLowerCase().contains("program files") ) { + for ( File dir2 : dir.listFiles() ) { + if ( !dir2.isDirectory() ) continue; + if ( dir.getName().toLowerCase().contains("eclipse") ) { + String eclipseLocation = findEclipseOnWindows1(dir); + if ( eclipseLocation != null ) eclipses.add(eclipseLocation); + } + } + } + } + } + + return eclipses; + } + + private static String findEclipseOnWindows1(File dir) { + if ( new File(dir, "eclipse.exe").isFile() ) return dir.toString(); + return null; + } + + public static void main(String[] args) throws Exception { + System.out.println(findEclipses()); + } + + public static List<String> findEclipses() { + String prop = System.getProperty("os.name", ""); + if ( prop.equalsIgnoreCase("Mac OS X") ) return findEclipseOnMac(); + if ( prop.equalsIgnoreCase("Windows XP") ) return findEclipseOnWindows(); + + return null; + } + + public static String getEclipseExecutableName() { + String prop = System.getProperty("os.name", ""); + if ( prop.equalsIgnoreCase("Mac OS X") ) return "Eclipse.app"; + if ( prop.equalsIgnoreCase("Windows XP") ) return "eclipse.exe"; + + return "eclipse"; + } + + public static List<String> findEclipseOnMac() { + List<String> eclipses = new ArrayList<String>(); + for ( File dir : new File("/Applications").listFiles() ) { + if ( dir.getName().toLowerCase().contains("eclipse") ) { + if ( new File(dir, "Eclipse.app").exists() ) eclipses.add(dir.toString()); + } + } + return eclipses; + } +} diff --git a/src/lombok/installer/EclipseLocation.java b/src/lombok/installer/EclipseLocation.java new file mode 100644 index 00000000..400b5606 --- /dev/null +++ b/src/lombok/installer/EclipseLocation.java @@ -0,0 +1,313 @@ +package lombok.installer; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.List; +import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +final class EclipseLocation { + private static final String OS_NEWLINE; + + static { + String os = System.getProperty("os.name", ""); + + if ( "Mac OS".equals(os) ) OS_NEWLINE = "\r"; + else if ( os.toLowerCase().contains("windows") ) OS_NEWLINE = "\r\n"; + else OS_NEWLINE = "\n"; + } + + private final File path; + private volatile boolean hasLombok; + boolean selected = true; + + final class NotAnEclipseException extends Exception { + private static final long serialVersionUID = 1L; + + public NotAnEclipseException(String message, Throwable cause) { + super(message, cause); + } + + public void showDialog(JFrame appWindow) { + JOptionPane.showMessageDialog(appWindow, getMessage(), "Cannot configure eclipse installation", JOptionPane.WARNING_MESSAGE); + } + } + + EclipseLocation(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.isDirectory() ) { + for ( File f : p.listFiles() ) { + if ( f.getName().equalsIgnoreCase(execName) ) { + p = f; + break; + } + } + } + + this.path = p; + try { + this.hasLombok = checkForLombok(); + } 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); + } + } + + public int hashCode() { + return path.hashCode(); + } + + public boolean equals(Object o) { + if ( !(o instanceof EclipseLocation) ) return false; + return ((EclipseLocation)o).path.equals(path); + } + + public String getPath() { + return path.getAbsolutePath(); + } + + public boolean hasLombok() { + return hasLombok; + } + + 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"); + if ( !iniFile.exists() ) return false; + 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.trim()).matches() ) return true; + } + + return false; + } finally { + fis.close(); + } + } + + public class UninstallException extends Exception { + private static final long serialVersionUID = 1L; + + public UninstallException(String message, Throwable cause) { + super(message, cause); + } + } + + public void uninstall() throws UninstallException { + for ( File dir : getTargetDirs() ) { + File lombokJar = new File(dir, "lombok.jar"); + if ( lombokJar.exists() ) { + if ( !lombokJar.delete() ) throw new UninstallException( + "Can't delete " + lombokJar.getAbsolutePath() + + " - perhaps the installer does not have the access rights to do so.", + null); + } + + File agentJar = new File(dir, "lombok.eclipse.agent.jar"); + if ( agentJar.exists() ) { + if ( !agentJar.delete() ) throw new UninstallException( + "Can't delete " + agentJar.getAbsolutePath() + + " - perhaps the installer does not have the access rights to do so.", + null); + } + + File iniFile = new File(dir, "eclipse.ini"); + StringBuilder newContents = new StringBuilder(); + if ( iniFile.exists() ) { + 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; + 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; + } + + newContents.append(line).append(OS_NEWLINE); + } + + } finally { + fis.close(); + } + + 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() + + " probably because this installer does not have the access rights to do so.", e); + } + } + } + } + + public class InstallException extends Exception { + private static final long serialVersionUID = 1L; + + public InstallException(String message, Throwable cause) { + super(message, cause); + } + } + + public void install() throws InstallException { + for ( File dir : getTargetDirs() ) { + File iniFile = new File(dir, "eclipse.ini"); + StringBuilder newContents = new StringBuilder(); + if ( iniFile.exists() ) { + 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); + + try { + ZipEntry entry = jar.getEntry("lombok.eclipse.agent.jar"); + InputStream in = jar.getInputStream(entry); + FileOutputStream out = new FileOutputStream(agentJar); + try { + while ( true ) { + int r = in.read(b); + if ( r == -1 ) break; + readSucceeded = true; + out.write(b, 0, r); + } + } finally { + out.close(); + } + } finally { + jar.close(); + + } + + FileOutputStream out = new FileOutputStream(lombokJar); + InputStream in = new FileInputStream(ourJar); + try { + while ( true ) { + int r = in.read(b); + if ( r == -1 ) break; + out.write(b, 0, r); + } + } finally { + out.close(); + } + } catch ( IOException e ) { + try { + lombokJar.delete(); + agentJar.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, probably because this installer does not have the access rights.", e); + } + + 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; + 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; + } + + newContents.append(line).append(OS_NEWLINE); + } + + } finally { + fis.close(); + } + + newContents.append("-javaagent:lombok.jar").append(OS_NEWLINE); + newContents.append("-Xbootclasspath/a:lombok.jar" + File.pathSeparator + "lombok.eclipse.agent.jar").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() + + " probably because this installer does not have the access rights to do so.", e); + } finally { + if ( !installSucceeded ) try { + lombokJar.delete(); + agentJar.delete(); + } catch ( Throwable ignore ) {} + } + } + } + } +} diff --git a/src/lombok/installer/InstallerWindow.java b/src/lombok/installer/InstallerWindow.java index 7db465be..a0911c26 100644 --- a/src/lombok/installer/InstallerWindow.java +++ b/src/lombok/installer/InstallerWindow.java @@ -1,48 +1,740 @@ package lombok.installer; -import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.HeadlessException; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.font.TextAttribute; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import javax.swing.Box; +import javax.swing.BoxLayout; import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.Scrollable; import javax.swing.SwingUtilities; +import javax.swing.filechooser.FileFilter; import lombok.core.Version; +import lombok.installer.EclipseLocation.InstallException; +import lombok.installer.EclipseLocation.NotAnEclipseException; +import lombok.installer.EclipseLocation.UninstallException; public class InstallerWindow { - private JFrame jFrame; - private JLabel mainText; - private JLabel leftGraphic, topGraphic; + private static final URI ABOUT_LOMBOK_URL = URI.create("http://projectlombok.org"); + + private JFrame appWindow; + + private JComponent loadingExpl; + + private Component javacArea; + private Component eclipseArea; + private Component uninstallArea; + private Component howIWorkArea; + + private Box uninstallBox; + + private List<EclipseLocation> toUninstall; public static void main(String[] args) { + try { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + new InstallerWindow().show(); + } catch ( HeadlessException e ) { + printHeadlessInfo(); + } + } + }); + } catch ( HeadlessException e ) { + printHeadlessInfo(); + } + } + + private static void printHeadlessInfo() { + System.out.printf("About lombok v%s\n" + + "Lombok makes java better by providing very spicy additions to the Java programming language," + + "such as using @Getter to automatically generate a getter method for any field.\n\n" + + "Browse to %s for more information. To install lombok on eclipse, re-run this jar file on a " + + "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); + } + + public InstallerWindow() { + appWindow = new JFrame(String.format("Project Lombok v%s - Installer", Version.getVersion())); + + appWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + appWindow.setResizable(false); + + try { + javacArea = buildJavacArea(); + eclipseArea = buildEclipseArea(); + uninstallArea = buildUninstallArea(); + uninstallArea.setVisible(false); + howIWorkArea = buildHowIWorkArea(); + howIWorkArea.setVisible(false); + buildChrome(appWindow.getContentPane()); + appWindow.pack(); + } catch ( Throwable t ) { + handleException(t); + } + } + + private void handleException(final Throwable t) { SwingUtilities.invokeLater(new Runnable() { - public void run() { - new InstallerWindow().show(); + @Override public void run() { + JOptionPane.showMessageDialog(appWindow, "There was a problem during the installation process:\n" + t, "Uh Oh!", JOptionPane.ERROR_MESSAGE); + System.exit(1); } }); } - public InstallerWindow() { - jFrame = new JFrame(String.format("Project Lombok v%s - Installer", Version.getVersion())); + private Component buildHowIWorkArea() { + JPanel container = new JPanel(); + + container.setLayout(new GridBagLayout()); + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = GridBagConstraints.WEST; + + container.add(new JLabel(HOW_I_WORK_TITLE), constraints); - //We want to offer an undo feature when the user cancels in the middle of an operation. - jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + constraints.gridy = 1; + constraints.insets = new Insets(8, 0, 0, 16); + container.add(new JLabel(HOW_I_WORK_EXPLANATION), constraints); - leftGraphic = new JLabel(new ImageIcon(InstallerWindow.class.getResource("/lombok/installer/lombok.png"))); - topGraphic = new JLabel(new ImageIcon(InstallerWindow.class.getResource("/lombok/installer/lombokText.png"))); - mainText = new JLabel("Explanatory stuff goes here."); + Box buttonBar = Box.createHorizontalBox(); + JButton backButton = new JButton("Okay - Good to know!"); + buttonBar.add(Box.createHorizontalGlue()); + buttonBar.add(backButton); - jFrame.setLayout(new BorderLayout()); - jFrame.add(leftGraphic, BorderLayout.WEST); - jFrame.add(topGraphic, BorderLayout.NORTH); - jFrame.add(mainText, BorderLayout.CENTER); + backButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + howIWorkArea.setVisible(false); + javacArea.setVisible(true); + eclipseArea.setVisible(true); + appWindow.pack(); + } + }); + constraints.gridy = 2; + container.add(buttonBar, constraints); - jFrame.pack(); - System.out.println("WE SHOULD BE UP"); + return container; + } + + private Component buildUninstallArea() { + JPanel container = new JPanel(); + + container.setLayout(new GridBagLayout()); + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = GridBagConstraints.WEST; + + container.add(new JLabel(UNINSTALL_TITLE), constraints); + + constraints.gridy = 1; + constraints.insets = new Insets(8, 0, 0, 16); + container.add(new JLabel(UNINSTALL_EXPLANATION), constraints); + + uninstallBox = Box.createVerticalBox(); + constraints.gridy = 2; + constraints.fill = GridBagConstraints.HORIZONTAL; + container.add(uninstallBox, constraints); + + constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.gridy = 3; + container.add(new JLabel("Are you sure?"), constraints); + + Box buttonBar = Box.createHorizontalBox(); + JButton noButton = new JButton("No - Don't uninstall"); + buttonBar.add(noButton); + buttonBar.add(Box.createHorizontalGlue()); + JButton yesButton = new JButton("Yes - uninstall Lombok"); + buttonBar.add(yesButton); + + noButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + uninstallArea.setVisible(false); + javacArea.setVisible(true); + eclipseArea.setVisible(true); + appWindow.pack(); + } + }); + + yesButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + doUninstall(); + } + }); + + constraints.gridy = 4; + container.add(buttonBar, constraints); + + return container; + } + + private Component buildJavacArea() { + JPanel container = new JPanel(); + + container.setLayout(new GridBagLayout()); + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = GridBagConstraints.WEST; + + container.add(new JLabel(JAVAC_TITLE), constraints); + + constraints.gridy = 1; + constraints.insets = new Insets(8, 0, 0, 16); + container.add(new JLabel(JAVAC_EXPLANATION), constraints); + + JLabel example = new JLabel(JAVAC_EXAMPLE); + + constraints.gridy = 2; + constraints.insets = new Insets(8, 0, 0, 16); + container.add(example, constraints); + return container; + } + + private Component buildEclipseArea() throws IOException { + // "Or:" [I'll tell you where eclipse is] [Tell me how to install lombok manually] + + //Mode 2 (manual): + // Replace the entirety of the content (javac+eclipse) with an explanation about what to do: + // - copy lombok.jar to your eclipse directory. + // - jar xvf lombok.jar lombok.eclipse.agent.jar + // - edit eclipse.ini with: + // -javaagent:../../../lombok.eclipse.agent.jar + // -Xbootclasspath/a:../../../lombok.eclipse.agent.jar:../../../lombok.jar + + //Mode 3 (let me choose): + // pop up a file chooser. Make sure we don't care what you pick - eclipse.ini, eclipse.exe, eclipse.app, or dir. + // empty the list, remove the spinner and the [let me find eclipse on my own] button, and put the chosen + // eclipse in the list. + + JPanel container = new JPanel(); + + container.setLayout(new GridBagLayout()); + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = GridBagConstraints.WEST; + + container.add(new JLabel(ECLIPSE_TITLE), constraints); + + constraints.gridy = 1; + constraints.insets = new Insets(8, 0, 0, 16); + container.add(new JLabel(ECLIPSE_EXPLANATION), constraints); + + constraints.gridy = 2; + loadingExpl = Box.createHorizontalBox(); + loadingExpl.add(new JLabel(new ImageIcon(InstallerWindow.class.getResource("/lombok/installer/loading.gif")))); + loadingExpl.add(new JLabel(ECLIPSE_LOADING_EXPLANATION)); + container.add(loadingExpl, constraints); + + constraints.weightx = 1.0; + constraints.gridy = 3; + constraints.fill = GridBagConstraints.HORIZONTAL; + eclipsesList = new EclipsesList(); + + JScrollPane eclipsesListScroll = new JScrollPane(eclipsesList); + eclipsesListScroll.setBackground(Color.WHITE); + container.add(eclipsesListScroll, constraints); + + Thread findEclipsesThread = new Thread() { + @Override public void run() { + try { + final List<String> eclipses = EclipseFinder.findEclipses(); + final List<EclipseLocation> locations = new ArrayList<EclipseLocation>(); + final List<NotAnEclipseException> problems = new ArrayList<NotAnEclipseException>(); + + for ( String eclipse : eclipses ) try { + locations.add(new EclipseLocation(eclipse)); + } catch ( NotAnEclipseException e ) { + problems.add(e); + } + + SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { + for ( EclipseLocation location : locations ) { + try { + eclipsesList.addEclipse(location); + } catch ( Throwable t ) { + handleException(t); + } + } + + for ( NotAnEclipseException problem : problems ) { + problem.showDialog(appWindow); + } + + loadingExpl.setVisible(false); + } + }); + } catch ( Throwable t ) { + handleException(t); + } + } + }; + + findEclipsesThread.start(); + + Box buttonBar = Box.createHorizontalBox(); + JButton specifyEclipseLocationButton = new JButton("Specify eclipse location..."); + buttonBar.add(specifyEclipseLocationButton); + specifyEclipseLocationButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent event) { + JFileChooser chooser = new JFileChooser(); + + chooser.setAcceptAllFileFilterUsed(false); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + chooser.setFileFilter(new FileFilter() { + private final String name = EclipseFinder.getEclipseExecutableName(); + @Override public boolean accept(File f) { + if ( f.getName().equalsIgnoreCase(name) ) return true; + if ( f.isDirectory() ) return true; + + return false; + } + + @Override public String getDescription() { + return "Eclipse Installation"; + } + }); + + switch ( chooser.showDialog(appWindow, "Select") ) { + case JFileChooser.APPROVE_OPTION: + try { + try { + eclipsesList.addEclipse(new EclipseLocation(chooser.getSelectedFile().getAbsolutePath())); + } catch ( NotAnEclipseException e ) { + e.showDialog(appWindow); + } + } catch ( Throwable t ) { + handleException(t); + } + } + } + }); + buttonBar.add(Box.createHorizontalGlue()); + installButton = new JButton("Install / Update"); + buttonBar.add(installButton); + + installButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + List<EclipseLocation> locationsToInstall = new ArrayList<EclipseLocation>(eclipsesList.getSelectedEclipses()); + if ( locationsToInstall.isEmpty() ) { + JOptionPane.showMessageDialog(appWindow, "You haven't selected any eclipse installations!.", "No Selection", JOptionPane.WARNING_MESSAGE); + return; + } + + install(locationsToInstall); + } + }); + + constraints.gridy = 4; + constraints.weightx = 0; + container.add(buttonBar, constraints); + + constraints.gridy = 5; + constraints.fill = GridBagConstraints.NONE; + uninstallButton = new JHyperLink("Uninstall lombok from selected eclipse installations."); + uninstallButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + List<EclipseLocation> locationsToUninstall = new ArrayList<EclipseLocation>(); + for ( EclipseLocation location : eclipsesList.getSelectedEclipses() ) { + if ( location.hasLombok() ) locationsToUninstall.add(location); + } + + if ( locationsToUninstall.isEmpty() ) { + JOptionPane.showMessageDialog(appWindow, "You haven't selected any eclipse installations that have been lombok-enabled.", "No Selection", JOptionPane.WARNING_MESSAGE); + return; + } + + + uninstall(locationsToUninstall); + } + }); + container.add(uninstallButton, constraints); + + constraints.gridy = 6; + JHyperLink showMe = new JHyperLink("Show me what this installer will do to my eclipse installation."); + container.add(showMe, constraints); + showMe.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + showWhatIDo(); + } + }); + + return container; + } + + private void showWhatIDo() { + javacArea.setVisible(false); + eclipseArea.setVisible(false); + howIWorkArea.setVisible(true); + appWindow.pack(); + } + + private void uninstall(List<EclipseLocation> |
