diff options
16 files changed, 1981 insertions, 1081 deletions
diff --git a/src/installer/lombok/installer/CorruptedIdeLocationException.java b/src/installer/lombok/installer/CorruptedIdeLocationException.java new file mode 100644 index 00000000..9b185d1e --- /dev/null +++ b/src/installer/lombok/installer/CorruptedIdeLocationException.java @@ -0,0 +1,26 @@ +package lombok.installer; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +/** + * Represents an installation location problem. + * You should throw it upon creation of a {@code IdeLocation} class + * if the provided location looks like your kind of IDE but there's something wrong with it. + */ +public class CorruptedIdeLocationException extends Exception { + private final String ideType; + + public CorruptedIdeLocationException(String message, String ideType, Throwable cause) { + super(message, cause); + this.ideType = ideType; + } + + public String getIdeType() { + return ideType; + } + + void showDialog(JFrame appWindow) { + JOptionPane.showMessageDialog(appWindow, getMessage(), "Cannot configure " + ideType + " installation", JOptionPane.WARNING_MESSAGE); + } +} diff --git a/src/installer/lombok/installer/IdeFinder.java b/src/installer/lombok/installer/IdeFinder.java new file mode 100644 index 00000000..165d0768 --- /dev/null +++ b/src/installer/lombok/installer/IdeFinder.java @@ -0,0 +1,144 @@ +/* + * 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.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.core.Version; + +/** + * Implement and provide this class to add auto-finding a certain brand of IDEs to the lombok installer. + */ +public abstract class IdeFinder { + private static final AtomicBoolean windowsDriveInfoLibLoaded = new AtomicBoolean(false); + + private static void loadWindowsDriveInfoLib() throws IOException { + if (!windowsDriveInfoLibLoaded.compareAndSet(false, true)) return; + + final String prefix = "lombok-" + Version.getVersion() + "-"; + + File temp = File.createTempFile("lombok", ".mark"); + File dll1 = new File(temp.getParentFile(), prefix + "WindowsDriveInfo-i386.dll"); + File dll2 = new File(temp.getParentFile(), prefix + "WindowsDriveInfo-x86_64.dll"); + temp.delete(); + dll1.deleteOnExit(); + dll2.deleteOnExit(); + try { + if (unpackDLL("WindowsDriveInfo-i386.dll", dll1)) { + System.load(dll1.getAbsolutePath()); + return; + } + } catch (Throwable ignore) {} + + try { + if (unpackDLL("WindowsDriveInfo-x86_64.dll", dll2)) { + System.load(dll2.getAbsolutePath()); + } + } catch (Throwable ignore) {} + } + + private static boolean unpackDLL(String dllName, File target) throws IOException { + InputStream in = IdeFinder.class.getResourceAsStream(dllName); + try { + try { + FileOutputStream out = new FileOutputStream(target); + try { + byte[] b = new byte[32000]; + while (true) { + int r = in.read(b); + if (r == -1) break; + out.write(b, 0, r); + } + } finally { + out.close(); + } + } catch (IOException e) { + //Fall through - if there is a file named lombok-WindowsDriveInfo-arch.dll, we'll try it. + return target.exists() && target.canRead(); + } + } finally { + in.close(); + } + + return true; + } + + /** + * Returns all drive letters on windows that represent fixed disks. + * + * Floppy drives, optical drives, USB sticks, and network drives should all be excluded. + * + * @return A List of drive letters, such as ["C", "D", "X"]. + */ + public static List<String> getDrivesOnWindows() throws Throwable { + loadWindowsDriveInfoLib(); + + List<String> drives = new ArrayList<String>(); + + WindowsDriveInfo info = new WindowsDriveInfo(); + for (String drive : info.getLogicalDrives()) { + if (info.isFixedDisk(drive)) drives.add(drive); + } + + return drives; + } + + public static enum OS { + MAC_OS_X("\n"), WINDOWS("\r\n"), UNIX("\n"); + + private final String lineEnding; + + OS(String lineEnding) { + this.lineEnding = lineEnding; + } + + public String getLineEnding() { + return lineEnding; + } + } + + public static OS getOS() { + String prop = System.getProperty("os.name", "").toLowerCase(); + if (prop.matches("^.*\\bmac\\b.*$")) return OS.MAC_OS_X; + if (prop.matches("^.*\\bdarwin\\b.*$")) return OS.MAC_OS_X; + if (prop.matches("^.*\\bwin(dows)\\b.*$")) return OS.WINDOWS; + + return OS.UNIX; + } + + /** + * Look for installations of your IDE in the usual places. + * + * @param locations Add to this list any valid locations that you found. + * @param problems + * Add to this list any locations that look like installations, + * but have problems that prevent you from installing/uninstalling from them. DONT add to this list + * any common locations that have no installation at all - only add near misses. + */ + public abstract void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems); +} diff --git a/src/installer/lombok/installer/IdeLocation.java b/src/installer/lombok/installer/IdeLocation.java new file mode 100644 index 00000000..e23a0033 --- /dev/null +++ b/src/installer/lombok/installer/IdeLocation.java @@ -0,0 +1,74 @@ +/* + * 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.File; +import java.io.IOException; +import java.net.URL; + +import lombok.patcher.inject.LiveInjector; + +/** + * Represents a location that contains an IDE. + */ +public abstract class IdeLocation { + /** Toggling the 'selected' checkbox in the GUI is tracked via this boolean */ + boolean selected = true; + + public abstract String install() throws InstallException; + public abstract void uninstall() throws UninstallException; + public abstract String getName(); + public abstract boolean hasLombok(); + public abstract URL getIdeIcon(); + + /** + * Returns a File object pointing to our own jar file. Will obviously fail if the installer was started via + * a jar that wasn't accessed via the file-system, or if its started via e.g. unpacking the jar. + */ + public static File findOurJar() { + return new File(LiveInjector.findPathJar(IdeFinder.class)); + } + + /** + * Returns a full path to the provided file. + * Returns the canonical path, unless that is not available, in which cae it returns the absolute path. + */ + public static String canonical(File p) { + try { + return p.getCanonicalPath(); + } catch (IOException e) { + String x = p.getAbsolutePath(); + return x == null ? p.getPath() : x; + } + } + + private static final String LEGAL_PATH_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"; + public static String escapePath(String path) { + StringBuilder out = new StringBuilder(); + + for (char c : path.toCharArray()) { + if (LEGAL_PATH_CHARS.indexOf(c) == -1) out.append('\\'); + out.append(c); + } + return out.toString(); + } +} diff --git a/src/installer/lombok/installer/IdeLocationProvider.java b/src/installer/lombok/installer/IdeLocationProvider.java new file mode 100644 index 00000000..e98e199d --- /dev/null +++ b/src/installer/lombok/installer/IdeLocationProvider.java @@ -0,0 +1,40 @@ +/* + * 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.util.regex.Pattern; + +import lombok.installer.IdeFinder.OS; + +public interface IdeLocationProvider { + /** + * @throws CorruptedIdeLocationException + * Only throw this exception if the location seems like a proper installation except there's something wrong with it. + * Do not throw it (just return {@code null}) if there's nothing there or it looks absolutely nothing like your IDE. + */ + public abstract IdeLocation create(String path) throws CorruptedIdeLocationException; + + /** + * Return the usual name of the IDE executable or other obvious marker of an IDE installation on the provided platform. + */ + public abstract Pattern getLocationSelectors(OS os); +} diff --git a/src/installer/lombok/installer/InstallException.java b/src/installer/lombok/installer/InstallException.java new file mode 100644 index 00000000..41879604 --- /dev/null +++ b/src/installer/lombok/installer/InstallException.java @@ -0,0 +1,10 @@ +package lombok.installer; + +/** + * Thrown when installation of lombok into an IDE fails. + */ +public class InstallException extends Exception { + public InstallException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/installer/lombok/installer/Installer.java b/src/installer/lombok/installer/Installer.java index d4b31251..9ed9e93a 100644 --- a/src/installer/lombok/installer/Installer.java +++ b/src/installer/lombok/installer/Installer.java @@ -21,55 +21,23 @@ */ package lombok.installer; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.FileDialog; -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.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.font.TextAttribute; -import java.io.File; -import java.io.FilenameFilter; +import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; -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.UIManager; -import javax.swing.filechooser.FileFilter; +import lombok.Lombok; import lombok.core.LombokApp; +import lombok.core.SpiLoadUtil; import lombok.core.Version; -import lombok.installer.EclipseFinder.OS; -import lombok.installer.EclipseLocation.InstallException; -import lombok.installer.EclipseLocation.NotAnEclipseException; -import lombok.installer.EclipseLocation.UninstallException; +import lombok.installer.IdeFinder.OS; import org.mangosdk.spi.ProviderFor; @@ -77,6 +45,7 @@ import com.zwitserloot.cmdreader.CmdReader; import com.zwitserloot.cmdreader.Description; import com.zwitserloot.cmdreader.InvalidCommandLineException; import com.zwitserloot.cmdreader.Parameterized; +import com.zwitserloot.cmdreader.Sequential; import com.zwitserloot.cmdreader.Shorthand; /** @@ -86,24 +55,49 @@ import com.zwitserloot.cmdreader.Shorthand; * and looks in some common places on Mac OS X, Linux and Windows. */ public class Installer { - private static final URI ABOUT_LOMBOK_URL = URI.create("http://projectlombok.org"); - private static final AtomicReference<Integer> exitMarker = new AtomicReference<Integer>(); + static final URI ABOUT_LOMBOK_URL = URI.create("http://projectlombok.org"); + static final List<IdeLocationProvider> locationProviders; - private JFrame appWindow; + static { + List<IdeLocationProvider> list = new ArrayList<IdeLocationProvider>(); + try { + for (IdeLocationProvider provider : SpiLoadUtil.findServices(IdeLocationProvider.class)) { + list.add(provider); + } + } catch (IOException e) { + throw Lombok.sneakyThrow(e); + } + locationProviders = Collections.unmodifiableList(list); + } - private JComponent loadingExpl; - - private Component javacArea; - private Component eclipseArea; - private Component uninstallArea; - private Component howIWorkArea; - - private Box uninstallBox; - private List<EclipseLocation> toUninstall; + static List<Pattern> getIdeExecutableNames() { + OS os = IdeFinder.getOS(); + List<Pattern> list = new ArrayList<Pattern>(); + for (IdeLocationProvider provider : locationProviders) { + Pattern p = provider.getLocationSelectors(os); + if (p != null) list.add(p); + } + return list; + } + + static IdeLocation tryAllProviders(String location) throws CorruptedIdeLocationException { + for (IdeLocationProvider provider : locationProviders) { + IdeLocation loc = provider.create(location); + if (loc != null) return loc; + } + + return null; + } - private JHyperLink uninstallButton; - private JLabel uninstallPlaceholder; - private JButton installButton; + static void autoDiscover(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) { + try { + for (IdeFinder finder : SpiLoadUtil.findServices(IdeFinder.class)) { + finder.findIdes(locations, problems); + } + } catch (IOException e) { + throw Lombok.sneakyThrow(e); + } + } @ProviderFor(LombokApp.class) public static class GraphicalInstallerApp implements LombokApp { @@ -163,7 +157,7 @@ public class Installer { } private static int guiInstaller() { - if (EclipseFinder.getOS() == OS.MAC_OS_X) { + if (IdeFinder.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"); } @@ -176,22 +170,22 @@ public class Installer { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ignore) {} - new Installer().show(); + new InstallerGUI().show(); } catch (HeadlessException e) { printHeadlessInfo(); } } }); - synchronized (exitMarker) { - while (!Thread.interrupted() && exitMarker.get() == null) { + synchronized (InstallerGUI.exitMarker) { + while (!Thread.interrupted() && InstallerGUI.exitMarker.get() == null) { try { - exitMarker.wait(); + InstallerGUI.exitMarker.wait(); } catch (InterruptedException e) { return 1; } } - Integer errCode = exitMarker.get(); + Integer errCode = InstallerGUI.exitMarker.get(); return errCode == null ? 1 : errCode; } } catch (HeadlessException e) { @@ -201,12 +195,12 @@ public class Installer { } private static class CmdArgs { - @Shorthand("e") - @Description("Specify a path to an eclipse location to install/uninstall. Use 'auto' to apply to all automatically discoverable eclipse installations.") + @Description("Specify paths to a location to install/uninstall. Use 'auto' to apply to all automatically discoverable installations.") @Parameterized - List<String> eclipse = new ArrayList<String>(); + @Sequential + List<String> path = new ArrayList<String>(); - @Shorthand({"?", "h"}) + @Shorthand({"h", "?"}) @Description("Shows this help text") boolean help; } @@ -228,30 +222,33 @@ public class Installer { return 0; } - if (args.eclipse.isEmpty()) { + if (args.path.isEmpty()) { System.err.println("ERROR: Nothing to do!"); System.err.println("--------------------------"); System.err.println(generateCliHelp(uninstall, reader)); return 1; } - final List<EclipseLocation> locations = new ArrayList<EclipseLocation>(); - final List<NotAnEclipseException> problems = new ArrayList<NotAnEclipseException>(); + final List<IdeLocation> locations = new ArrayList<IdeLocation>(); + final List<CorruptedIdeLocationException> problems = new ArrayList<CorruptedIdeLocationException>(); + + if (args.path.contains("auto")) autoDiscover(locations, problems); - for (String rawPath : args.eclipse) { - if (rawPath.equals("auto")) { - EclipseFinder.findEclipses(locations, problems); - } else { + for (String rawPath : args.path) { + if (!rawPath.equals("auto")) { try { - locations.add(EclipseLocation.create(rawPath)); - } catch (NotAnEclipseException e) { + IdeLocation loc = tryAllProviders(rawPath); + if (loc != null) locations.add(loc); + else problems.add(new CorruptedIdeLocationException("Can't find any IDE at: " + rawPath, null, null)); + locations.add(tryAllProviders(rawPath)); + } catch (CorruptedIdeLocationException e) { problems.add(e); } } } int validLocations = locations.size(); - for (EclipseLocation loc : locations) { + for (IdeLocation loc : locations) { try { if (uninstall) { loc.uninstall(); @@ -270,7 +267,7 @@ public class Installer { } } - for (NotAnEclipseException problem : problems) { + for (CorruptedIdeLocationException problem : problems) { System.err.println("WARNING: " + problem.getMessage()); } @@ -301,695 +298,4 @@ public class Installer { " java -cp lombok.jar MyCode.java\n", Version.getVersion(), ABOUT_LOMBOK_URL); } - - /** - * Creates a new installer that starts out invisible. - * Call the {@link #show()} method on a freshly created installer to render it. - */ - public Installer() { - appWindow = new JFrame(String.format("Project Lombok v%s - Installer", Version.getVersion())); - - appWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - appWindow.setResizable(false); - appWindow.setIconImage(Toolkit.getDefaultToolkit().getImage(Installer.class.getResource("lombokIcon.png"))); - - 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() { - @Override public void run() { - JOptionPane.showMessageDialog(appWindow, "There was a problem during the installation process:\n" + t, "Uh Oh!", JOptionPane.ERROR_MESSAGE); - t.printStackTrace(); - System.exit(1); - } - }); - } - - 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); - - constraints.gridy = 1; - constraints.insets = new Insets(8, 0, 0, 16); - container.add(new JLabel(String.format(HOW_I_WORK_EXPLANATION, File.pathSeparator)), constraints); - - Box buttonBar = Box.createHorizontalBox(); - JButton backButton = new JButton("Okay - Good to know!"); - buttonBar.add(Box.createHorizontalGlue()); - buttonBar.add(backButton); - - 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); - - 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; - constraints.insets = new Insets(8, 0, 0, 16); - - container.add(new JLabel(JAVAC_TITLE), constraints); - - constraints.gridy = 1; - constraints.weightx = 1.0; - constraints.fill = GridBagConstraints.HORIZONTAL; - container.add(new JLabel(JAVAC_EXPLANATION), constraints); - - JLabel example = new JLabel(JAVAC_EXAMPLE); - - constraints.gridy = 2; - container.add(example, constraints); - return container; - } - - private Component buildEclipseArea() { - JPanel container = new JPanel(); - - container.setLayout(new GridBagLayout()); - GridBagConstraints constraints = new GridBagConstraints(); - constraints.anchor = GridBagConstraints.WEST; - - constraints.insets = new Insets(8, 0, 0, 16); - container.add(new JLabel(ECLIPSE_TITLE), constraints); - - constraints.gridy = 1; - container.add(new JLabel(ECLIPSE_EXPLANATION), constraints); - - constraints.gridy = 2; - loadingExpl = Box.createHorizontalBox(); - loadingExpl.add(new JLabel(new ImageIcon(Installer.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); - eclipsesListScroll.getViewport().setBackground(Color.WHITE); - container.add(eclipsesListScroll, constraints); - - Thread findEclipsesThread = new Thread() { - @Override public void run() { - try { - final List<EclipseLocation> locations = new ArrayList<EclipseLocation>(); - final List<NotAnEclipseException> problems = new ArrayList<NotAnEclipseException>(); - EclipseFinder.findEclipses(locations, problems); - - 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); - - 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" + - "location of your Eclipse installation to me. Thanks!", "Can't find Eclipse", JOptionPane.INFORMATION_MESSAGE); - } - } - }); - } 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) { - final String exeName = EclipseFinder.getEclipseExecutableName(); - String file = null; - - if (EclipseFinder.getOS() == OS.MAC_OS_X) { - FileDialog chooser = new FileDialog(appWindow); - chooser.setMode(FileDialog.LOAD); - chooser.setFilenameFilter(new FilenameFilter() { - @Override public boolean accept(File dir, String fileName) { - if (exeName.equalsIgnoreCase(fileName)) return true; - if (new File(dir, fileName).isDirectory()) return true; - return false; - } - }); - - chooser.setVisible(true); - file = new File(chooser.getDirectory(), chooser.getFile()).getAbsolutePath(); - } else { - JFileChooser chooser = new JFileChooser(); - - chooser.setAcceptAllFileFilterUsed(false); - chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - 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; - } - - @Override public String getDescription() { - return "Eclipse Installation"; - } - }); - - switch (chooser.showDialog(appWindow, "Select")) { - case JFileChooser.APPROVE_OPTION: - file = chooser.getSelectedFile().getAbsolutePath(); - } - } - - if (file != null) { - try { - eclipsesList.addEclipse(EclipseLocation.create(file)); - } 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; - 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(); - } - }); - - constraints.gridy = 6; - uninstallButton = new JHyperLink("Uninstall lombok from selected Eclipse installations."); - uninstallPlaceholder = new JLabel("<html> </html>"); - 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); - uninstallPlaceholder.setVisible(false); - container.add(uninstallPlaceholder, constraints); - - - return container; - } - - private void showWhatIDo() { - javacArea.setVisible(false); - eclipseArea.setVisible(false); - howIWorkArea.setVisible(true); - appWindow.pack(); - } - - private void uninstall(List<EclipseLocation> locations) { - javacArea.setVisible(false); - eclipseArea.setVisible(false); - - uninstallBox.removeAll(); - uninstallBox.add(Box.createRigidArea(new Dimension(1, 16))); - for (EclipseLocation location : locations) { - JLabel label = new JLabel(locati |
