mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 10:18:46 +00:00
Massive update to how the installer works, and added netbeans to the installer.
This commit is contained in:
1 parent
db212a2fa0
commit
df84dffa62
16 files changed
+1981
-1081
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
private JHyperLink uninstallButton;
|
||||
private JLabel uninstallPlaceholder;
|
||||
private JButton installButton;
|
||||
static IdeLocation tryAllProviders(String location) throws CorruptedIdeLocationException {
|
||||
for (IdeLocationProvider provider : locationProviders) {
|
||||
IdeLocation loc = provider.create(location);
|
||||
if (loc != null) return loc;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
for (String rawPath : args.eclipse) {
|
||||
if (rawPath.equals("auto")) {
|
||||
EclipseFinder.findEclipses(locations, problems);
|
||||
} else {
|
||||
if (args.path.contains("auto")) autoDiscover(locations, problems);
|
||||
|
||||
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(location.getName());
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
||||
uninstallBox.add(label);
|
||||
}
|
||||
uninstallBox.add(Box.createRigidArea(new Dimension(1, 16)));
|
||||
|
||||
toUninstall = locations;
|
||||
uninstallArea.setVisible(true);
|
||||
appWindow.pack();
|
||||
}
|
||||
|
||||
private void install(final List<EclipseLocation> toInstall) {
|
||||
JPanel spinner = new JPanel();
|
||||
spinner.setOpaque(true);
|
||||
spinner.setLayout(new FlowLayout());
|
||||
spinner.add(new JLabel(new ImageIcon(Installer.class.getResource("/lombok/installer/loading.gif"))));
|
||||
appWindow.setContentPane(spinner);
|
||||
|
||||
final AtomicReference<Boolean> success = new AtomicReference<Boolean>(true);
|
||||
|
||||
new Thread() {
|
||||
@Override public void run() {
|
||||
for (EclipseLocation loc : toInstall) {
|
||||
try {
|
||||
loc.install();
|
||||
} catch (final InstallException e) {
|
||||
success.set(false);
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
e.getMessage(), "Install Problem", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e2) {
|
||||
//Shouldn't happen.
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
"<html>Lombok has been installed on the selected Eclipse installations.<br>" +
|
||||
"Don't forget to add <code>lombok.jar</code> to your projects, and restart your eclipse!<br>" +
|
||||
"If you start eclipse with a custom -vm parameter, you'll need to add:<br>" +
|
||||
"<code>-vmargs -Xbootclasspath/a:lombok.jar -javaagent:lombok.jar</code><br>" +
|
||||
"as parameter as well.</html>", "Install successful",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
appWindow.setVisible(false);
|
||||
synchronized (exitMarker) {
|
||||
exitMarker.set(0);
|
||||
exitMarker.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (exitMarker) {
|
||||
exitMarker.set(1);
|
||||
exitMarker.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void doUninstall() {
|
||||
JPanel spinner = new JPanel();
|
||||
spinner.setOpaque(true);
|
||||
spinner.setLayout(new FlowLayout());
|
||||
spinner.add(new JLabel(new ImageIcon(Installer.class.getResource("/lombok/installer/loading.gif"))));
|
||||
|
||||
appWindow.setContentPane(spinner);
|
||||
|
||||
final AtomicReference<Boolean> success = new AtomicReference<Boolean>(true);
|
||||
new Thread() {
|
||||
@Override public void run() {
|
||||
for (EclipseLocation loc : toUninstall) {
|
||||
try {
|
||||
loc.uninstall();
|
||||
} catch (final UninstallException e) {
|
||||
success.set(false);
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
e.getMessage(), "Uninstall Problem", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e2) {
|
||||
//Shouldn't happen.
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow, "Lombok has been removed from the selected Eclipse installations.", "Uninstall successful", JOptionPane.INFORMATION_MESSAGE);
|
||||
appWindow.setVisible(false);
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private EclipsesList eclipsesList = new EclipsesList();
|
||||
|
||||
private static class JHyperLink extends JButton {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JHyperLink(String text) {
|
||||
super();
|
||||
setFont(getFont().deriveFont(Collections.singletonMap(TextAttribute.UNDERLINE, 1)));
|
||||
setText(text);
|
||||
setBorder(null);
|
||||
setContentAreaFilled(false);
|
||||
setForeground(Color.BLUE);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
setMargin(new Insets(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void selectedLomboksChanged(List<EclipseLocation> selectedEclipses) {
|
||||
boolean uninstallAvailable = false;
|
||||
boolean installAvailable = false;
|
||||
for (EclipseLocation loc : selectedEclipses) {
|
||||
if (loc.hasLombok()) uninstallAvailable = true;
|
||||
installAvailable = true;
|
||||
}
|
||||
|
||||
uninstallButton.setVisible(uninstallAvailable);
|
||||
uninstallPlaceholder.setVisible(!uninstallAvailable);
|
||||
installButton.setEnabled(installAvailable);
|
||||
}
|
||||
|
||||
private class EclipsesList extends JPanel implements Scrollable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
List<EclipseLocation> locations = new ArrayList<EclipseLocation>();
|
||||
|
||||
EclipsesList() {
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
setBackground(Color.WHITE);
|
||||
}
|
||||
|
||||
List<EclipseLocation> getSelectedEclipses() {
|
||||
List<EclipseLocation> list = new ArrayList<EclipseLocation>();
|
||||
for (EclipseLocation loc : locations) if (loc.selected) list.add(loc);
|
||||
return list;
|
||||
}
|
||||
|
||||
void fireSelectionChange() {
|
||||
selectedLomboksChanged(getSelectedEclipses());
|
||||
}
|
||||
|
||||
void addEclipse(final EclipseLocation location) {
|
||||
if (locations.contains(location)) return;
|
||||
Box box = Box.createHorizontalBox();
|
||||
box.setBackground(Color.WHITE);
|
||||
final JCheckBox checkbox = new JCheckBox(location.getName());
|
||||
checkbox.setBackground(Color.WHITE);
|
||||
box.add(checkbox);
|
||||
checkbox.setSelected(true);
|
||||
checkbox.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) {
|
||||
location.selected = checkbox.isSelected();
|
||||
fireSelectionChange();
|
||||
}
|
||||
});
|
||||
|
||||
if (location.hasLombok()) {
|
||||
box.add(new JLabel(new ImageIcon(Installer.class.getResource("/lombok/installer/lombokIcon.png"))));
|
||||
}
|
||||
box.add(Box.createHorizontalGlue());
|
||||
locations.add(location);
|
||||
add(box);
|
||||
getParent().doLayout();
|
||||
fireSelectionChange();
|
||||
}
|
||||
|
||||
@Override public Dimension getPreferredScrollableViewportSize() {
|
||||
return new Dimension(1, 100);
|
||||
}
|
||||
|
||||
@Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
@Override public boolean getScrollableTracksViewportHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildChrome(Container appWindowContainer) {
|
||||
JLabel leftGraphic = new JLabel(new ImageIcon(Installer.class.getResource("/lombok/installer/lombok.png")));
|
||||
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
|
||||
appWindowContainer.setLayout(new GridBagLayout());
|
||||
|
||||
constraints.gridheight = 3;
|
||||
constraints.gridwidth = 1;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.insets = new Insets(8, 8, 8, 8);
|
||||
appWindowContainer.add(leftGraphic, constraints);
|
||||
constraints.insets = new Insets(0, 0, 0, 0);
|
||||
|
||||
constraints.gridx++;
|
||||
constraints.gridy++;
|
||||
constraints.gridheight = 1;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.ipadx = 16;
|
||||
constraints.ipady = 14;
|
||||
appWindowContainer.add(javacArea, constraints);
|
||||
|
||||
constraints.gridy++;
|
||||
appWindowContainer.add(eclipseArea, constraints);
|
||||
|
||||
appWindowContainer.add(uninstallArea, constraints);
|
||||
|
||||
appWindowContainer.add(howIWorkArea, constraints);
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridwidth = 2;
|
||||
constraints.gridx = 0;
|
||||
constraints.weightx = 0;
|
||||
constraints.weighty = 0;
|
||||
constraints.ipadx = 0;
|
||||
constraints.ipady = 0;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.anchor = GridBagConstraints.SOUTHEAST;
|
||||
constraints.insets = new Insets(0, 16, 8, 8);
|
||||
Box buttonBar = Box.createHorizontalBox();
|
||||
JButton quitButton = new JButton("Quit Installer");
|
||||
quitButton.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) {
|
||||
appWindow.setVisible(false);
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
final JHyperLink hyperlink = new JHyperLink(ABOUT_LOMBOK_URL.toString());
|
||||
hyperlink.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent event) {
|
||||
hyperlink.setForeground(new Color(85, 145, 90));
|
||||
try {
|
||||
//java.awt.Desktop doesn't exist in 1.5.
|
||||
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);
|
||||
} catch (Exception e) {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
try {
|
||||
switch (EclipseFinder.getOS()) {
|
||||
case WINDOWS:
|
||||
String[] cmd = new String[4];
|
||||
cmd[0] = "cmd.exe";
|
||||
cmd[1] = "/C";
|
||||
cmd[2] = "start";
|
||||
cmd[3] = ABOUT_LOMBOK_URL.toString();
|
||||
rt.exec(cmd);
|
||||
break;
|
||||
case MAC_OS_X:
|
||||
rt.exec("open " + ABOUT_LOMBOK_URL.toString());
|
||||
break;
|
||||
default:
|
||||
case UNIX:
|
||||
rt.exec("firefox " + ABOUT_LOMBOK_URL.toString());
|
||||
break;
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
"Well, this is embarrassing. I don't know how to open a webbrowser.\n" +
|
||||
"I guess you'll have to open it. Browse to:\n" +
|
||||
"http://projectlombok.org for more information about Lombok.",
|
||||
"I'm embarrassed", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
buttonBar.add(hyperlink);
|
||||
buttonBar.add(Box.createRigidArea(new Dimension(16, 1)));
|
||||
buttonBar.add(new JLabel("<html><font size=\"-1\">v" + Version.getVersion() + "</font></html>"));
|
||||
|
||||
buttonBar.add(Box.createHorizontalGlue());
|
||||
buttonBar.add(quitButton);
|
||||
appWindow.add(buttonBar, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the installer window visible.
|
||||
*/
|
||||
public void show() {
|
||||
appWindow.setVisible(true);
|
||||
if (EclipseFinder.getOS() == OS.MAC_OS_X) {
|
||||
try {
|
||||
AppleNativeLook.go();
|
||||
} catch (Throwable ignore) {
|
||||
//We're just prettying up the app. If it fails, meh.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String ECLIPSE_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>Eclipse</i></b></font></html>";
|
||||
|
||||
private static final String ECLIPSE_EXPLANATION =
|
||||
"<html>Lombok can update your Eclipse to fully support all Lombok features.<br>" +
|
||||
"Select Eclipse installations below and hit 'Install/Update'.</html>";
|
||||
|
||||
private static final String ECLIPSE_LOADING_EXPLANATION =
|
||||
"Scanning your drives for Eclipse installations...";
|
||||
|
||||
private static final String JAVAC_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>Javac</i></b></font> (and tools that invoke javac such as <i>ant</i> and <i>maven</i>)</html>";
|
||||
|
||||
private static final String JAVAC_EXPLANATION =
|
||||
"<html>Lombok works 'out of the box' with javac.<br>Just make sure the lombok.jar is in your classpath when you compile.";
|
||||
|
||||
private static final String JAVAC_EXAMPLE =
|
||||
"<html>Example: <code>javac -cp lombok.jar MyCode.java</code></html>";
|
||||
|
||||
private static final String UNINSTALL_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>Uninstall</i></b></font></html>";
|
||||
|
||||
private static final String UNINSTALL_EXPLANATION =
|
||||
"<html>Uninstall Lombok from the following Eclipse Installations?</html>";
|
||||
|
||||
private static final String HOW_I_WORK_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>What this installer does</i></b></font></html>";
|
||||
|
||||
private static final String HOW_I_WORK_EXPLANATION =
|
||||
"<html><ol>" +
|
||||
"<li>First, I copy myself (lombok.jar) to your Eclipse install directory.</li>" +
|
||||
"<li>Then, I edit the eclipse.ini file to add the following two entries:<br>" +
|
||||
"<pre>-Xbootclasspath/a:lombok.jar<br>" +
|
||||
"-javaagent:lombok.jar</pre></li></ol>" +
|
||||
"<br>" +
|
||||
"That's all there is to it. Note that on Mac OS X, eclipse.ini is hidden in<br>" +
|
||||
"<code>Eclipse.app%1$sContents%1$sMacOS</code> so that's where I place the jar files.</html>";
|
||||
}
|
||||
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
* 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.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.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.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.filechooser.FileFilter;
|
||||
|
||||
import lombok.core.Version;
|
||||
import lombok.installer.IdeFinder.OS;
|
||||
|
||||
/**
|
||||
* The lombok GUI installer.
|
||||
* Uses swing to show a simple GUI that can add and remove the java agent to IDE installations.
|
||||
* Also offers info on what this installer does in case people want to instrument their IDE manually.
|
||||
*/
|
||||
public class InstallerGUI {
|
||||
static final AtomicReference<Integer> exitMarker = new AtomicReference<Integer>();
|
||||
|
||||
private JFrame appWindow;
|
||||
|
||||
private JComponent loadingExpl;
|
||||
|
||||
private Component javacArea;
|
||||
private Component ideArea;
|
||||
private Component uninstallArea;
|
||||
private Component howIWorkArea;
|
||||
|
||||
private Box uninstallBox;
|
||||
private JHyperLink uninstallButton;
|
||||
private JLabel uninstallPlaceholder;
|
||||
private JButton installButton;
|
||||
|
||||
private List<IdeLocation> toUninstall;
|
||||
private final Set<String> installSpecificMessages = new LinkedHashSet<String>();
|
||||
|
||||
/**
|
||||
* Creates a new installer that starts out invisible.
|
||||
* Call the {@link #show()} method on a freshly created installer to render it.
|
||||
*/
|
||||
public InstallerGUI() {
|
||||
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();
|
||||
ideArea = buildIdeArea();
|
||||
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.separator)), 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);
|
||||
ideArea.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);
|
||||
ideArea.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 buildIdeArea() {
|
||||
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(IDE_TITLE), constraints);
|
||||
|
||||
constraints.gridy = 1;
|
||||
container.add(new JLabel(IDE_EXPLANATION), constraints);
|
||||
|
||||
constraints.gridy = 2;
|
||||
loadingExpl = Box.createHorizontalBox();
|
||||
loadingExpl.add(new JLabel(new ImageIcon(Installer.class.getResource("loading.gif"))));
|
||||
loadingExpl.add(new JLabel(IDE_LOADING_EXPLANATION));
|
||||
container.add(loadingExpl, constraints);
|
||||
|
||||
constraints.weightx = 1.0;
|
||||
constraints.gridy = 3;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
idesList = new IdesList();
|
||||
|
||||
JScrollPane idesListScroll = new JScrollPane(idesList);
|
||||
idesListScroll.setBackground(Color.WHITE);
|
||||
idesListScroll.getViewport().setBackground(Color.WHITE);
|
||||
container.add(idesListScroll, constraints);
|
||||
|
||||
Thread findIdesThread = new Thread() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
final List<IdeLocation> locations = new ArrayList<IdeLocation>();
|
||||
final List<CorruptedIdeLocationException> problems = new ArrayList<CorruptedIdeLocationException>();
|
||||
Installer.autoDiscover(locations, problems);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
for (IdeLocation location : locations) {
|
||||
try {
|
||||
idesList.addLocation(location);
|
||||
} catch (Throwable t) {
|
||||
handleException(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (CorruptedIdeLocationException problem : problems) {
|
||||
problem.showDialog(appWindow);
|
||||
}
|
||||
|
||||
loadingExpl.setVisible(false);
|
||||
|
||||
if (locations.size() + problems.size() == 0) {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
"I can't find any IDEs on your computer.\n" +
|
||||
"If you have IDEs installed on this computer, please use the " +
|
||||
"'Specify Location...' button to manually point out the \n" +
|
||||
"location of your IDE installation to me. Thanks!",
|
||||
"Can't find IDE", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
handleException(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
findIdesThread.start();
|
||||
|
||||
Box buttonBar = Box.createHorizontalBox();
|
||||
JButton specifyIdeLocationButton = new JButton("Specify location...");
|
||||
buttonBar.add(specifyIdeLocationButton);
|
||||
specifyIdeLocationButton.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent event) {
|
||||
final List<Pattern> exeNames = Installer.getIdeExecutableNames();
|
||||
String file = null;
|
||||
|
||||
if (IdeFinder.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) {
|
||||
for (Pattern exeName : exeNames) if (exeName.matcher(fileName).matches()) 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) {
|
||||
for (Pattern exeName : exeNames) if (exeName.matcher(f.getName()).matches()) return true;
|
||||
if (f.isDirectory()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public String getDescription() {
|
||||
return "IDE Installation";
|
||||
}
|
||||
});
|
||||
|
||||
switch (chooser.showDialog(appWindow, "Select")) {
|
||||
case JFileChooser.APPROVE_OPTION:
|
||||
file = chooser.getSelectedFile().getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
try {
|
||||
IdeLocation loc = Installer.tryAllProviders(file);
|
||||
if (loc != null) idesList.addLocation(loc);
|
||||
else JOptionPane.showMessageDialog(appWindow, "I can't find any IDE that lombok supports at location: " + file, "No IDE found", JOptionPane.WARNING_MESSAGE);
|
||||
} catch (CorruptedIdeLocationException 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<IdeLocation> locationsToInstall = new ArrayList<IdeLocation>(idesList.getSelectedIdes());
|
||||
if (locationsToInstall.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(appWindow, "You haven't selected any IDE 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 IDE 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 IDE installations.");
|
||||
uninstallPlaceholder = new JLabel("<html> </html>");
|
||||
uninstallButton.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) {
|
||||
List<IdeLocation> locationsToUninstall = new ArrayList<IdeLocation>();
|
||||
for (IdeLocation location : idesList.getSelectedIdes()) {
|
||||
if (location.hasLombok()) locationsToUninstall.add(location);
|
||||
}
|
||||
|
||||
if (locationsToUninstall.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(appWindow, "You haven't selected any IDE 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);
|
||||
ideArea.setVisible(false);
|
||||
howIWorkArea.setVisible(true);
|
||||
appWindow.pack();
|
||||
}
|
||||
|
||||
private void uninstall(List<IdeLocation> locations) {
|
||||
javacArea.setVisible(false);
|
||||
ideArea.setVisible(false);
|
||||
|
||||
uninstallBox.removeAll();
|
||||
uninstallBox.add(Box.createRigidArea(new Dimension(1, 16)));
|
||||
for (IdeLocation location : locations) {
|
||||
JLabel label = new JLabel(location.getName());
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD));
|
||||
uninstallBox.add(label);
|
||||
}
|
||||
uninstallBox.add(Box.createRigidArea(new Dimension(1, 16)));
|
||||
|
||||
toUninstall = locations;
|
||||
uninstallArea.setVisible(true);
|
||||
appWindow.pack();
|
||||
}
|
||||
|
||||
private void install(final List<IdeLocation> toInstall) {
|
||||
JPanel spinner = new JPanel();
|
||||
spinner.setOpaque(true);
|
||||
spinner.setLayout(new FlowLayout());
|
||||
spinner.add(new JLabel(new ImageIcon(Installer.class.getResource("loading.gif"))));
|
||||
appWindow.setContentPane(spinner);
|
||||
|
||||
final AtomicReference<Boolean> success = new AtomicReference<Boolean>(true);
|
||||
|
||||
new Thread() {
|
||||
@Override public void run() {
|
||||
for (IdeLocation loc : toInstall) {
|
||||
try {
|
||||
installSpecificMessages.add(loc.install());
|
||||
} catch (final InstallException e) {
|
||||
success.set(false);
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
e.getMessage(), "Install Problem", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e2) {
|
||||
//Shouldn't happen.
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
StringBuilder installSpecific = new StringBuilder();
|
||||
for (String installSpecificMessage : installSpecificMessages) {
|
||||
installSpecific.append("<br>").append(installSpecificMessage);
|
||||
}
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
"<html>Lombok has been installed on the selected IDE installations.<br>" +
|
||||
"Don't forget to add <code>lombok.jar</code> to your projects, and restart your IDE!" + installSpecific.toString() + "</html>",
|
||||
"Install successful",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
appWindow.setVisible(false);
|
||||
synchronized (exitMarker) {
|
||||
exitMarker.set(0);
|
||||
exitMarker.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (exitMarker) {
|
||||
exitMarker.set(1);
|
||||
exitMarker.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void doUninstall() {
|
||||
JPanel spinner = new JPanel();
|
||||
spinner.setOpaque(true);
|
||||
spinner.setLayout(new FlowLayout());
|
||||
spinner.add(new JLabel(new ImageIcon(Installer.class.getResource("/lombok/installer/loading.gif"))));
|
||||
|
||||
appWindow.setContentPane(spinner);
|
||||
|
||||
final AtomicReference<Boolean> success = new AtomicReference<Boolean>(true);
|
||||
new Thread() {
|
||||
@Override public void run() {
|
||||
for (IdeLocation loc : toUninstall) {
|
||||
try {
|
||||
loc.uninstall();
|
||||
} catch (final UninstallException e) {
|
||||
success.set(false);
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
e.getMessage(), "Uninstall Problem", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e2) {
|
||||
//Shouldn't happen.
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success.get()) SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
JOptionPane.showMessageDialog(appWindow, "Lombok has been removed from the selected IDE installations.", "Uninstall successful", JOptionPane.INFORMATION_MESSAGE);
|
||||
appWindow.setVisible(false);
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private IdesList idesList = new IdesList();
|
||||
|
||||
void selectedLomboksChanged(List<IdeLocation> selectedIdes) {
|
||||
boolean uninstallAvailable = false;
|
||||
boolean installAvailable = false;
|
||||
for (IdeLocation loc : selectedIdes) {
|
||||
if (loc.hasLombok()) uninstallAvailable = true;
|
||||
installAvailable = true;
|
||||
}
|
||||
|
||||
uninstallButton.setVisible(uninstallAvailable);
|
||||
uninstallPlaceholder.setVisible(!uninstallAvailable);
|
||||
installButton.setEnabled(installAvailable);
|
||||
}
|
||||
|
||||
private class IdesList extends JPanel implements Scrollable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
List<IdeLocation> locations = new ArrayList<IdeLocation>();
|
||||
|
||||
IdesList() {
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
setBackground(Color.WHITE);
|
||||
}
|
||||
|
||||
List<IdeLocation> getSelectedIdes() {
|
||||
List<IdeLocation> list = new ArrayList<IdeLocation>();
|
||||
for (IdeLocation loc : locations) if (loc.selected) list.add(loc);
|
||||
return list;
|
||||
}
|
||||
|
||||
void fireSelectionChange() {
|
||||
selectedLomboksChanged(getSelectedIdes());
|
||||
}
|
||||
|
||||
void addLocation(final IdeLocation location) {
|
||||
if (locations.contains(location)) return;
|
||||
Box box = Box.createHorizontalBox();
|
||||
box.setBackground(Color.WHITE);
|
||||
final JCheckBox checkbox = new JCheckBox(location.getName());
|
||||
checkbox.setBackground(Color.WHITE);
|
||||
box.add(new JLabel(new ImageIcon(location.getIdeIcon())));
|
||||
box.add(checkbox);
|
||||
checkbox.setSelected(true);
|
||||
checkbox.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) {
|
||||
location.selected = checkbox.isSelected();
|
||||
fireSelectionChange();
|
||||
}
|
||||
});
|
||||
|
||||
if (location.hasLombok()) {
|
||||
box.add(new JLabel(new ImageIcon(Installer.class.getResource("lombokIcon.png"))));
|
||||
}
|
||||
box.add(Box.createHorizontalGlue());
|
||||
locations.add(location);
|
||||
add(box);
|
||||
getParent().doLayout();
|
||||
fireSelectionChange();
|
||||
}
|
||||
|
||||
@Override public Dimension getPreferredScrollableViewportSize() {
|
||||
return new Dimension(1, 100);
|
||||
}
|
||||
|
||||
@Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
@Override public boolean getScrollableTracksViewportHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildChrome(Container appWindowContainer) {
|
||||
JLabel leftGraphic = new JLabel(new ImageIcon(Installer.class.getResource("lombok.png")));
|
||||
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
|
||||
appWindowContainer.setLayout(new GridBagLayout());
|
||||
|
||||
constraints.gridheight = 3;
|
||||
constraints.gridwidth = 1;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.insets = new Insets(8, 8, 8, 8);
|
||||
appWindowContainer.add(leftGraphic, constraints);
|
||||
constraints.insets = new Insets(0, 0, 0, 0);
|
||||
|
||||
constraints.gridx++;
|
||||
constraints.gridy++;
|
||||
constraints.gridheight = 1;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.ipadx = 16;
|
||||
constraints.ipady = 14;
|
||||
appWindowContainer.add(javacArea, constraints);
|
||||
|
||||
constraints.gridy++;
|
||||
appWindowContainer.add(ideArea, constraints);
|
||||
|
||||
appWindowContainer.add(uninstallArea, constraints);
|
||||
|
||||
appWindowContainer.add(howIWorkArea, constraints);
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridwidth = 2;
|
||||
constraints.gridx = 0;
|
||||
constraints.weightx = 0;
|
||||
constraints.weighty = 0;
|
||||
constraints.ipadx = 0;
|
||||
constraints.ipady = 0;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.anchor = GridBagConstraints.SOUTHEAST;
|
||||
constraints.insets = new Insets(0, 16, 8, 8);
|
||||
Box buttonBar = Box.createHorizontalBox();
|
||||
JButton quitButton = new JButton("Quit Installer");
|
||||
quitButton.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent e) {
|
||||
appWindow.setVisible(false);
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
final JHyperLink hyperlink = new JHyperLink(Installer.ABOUT_LOMBOK_URL.toString());
|
||||
hyperlink.addActionListener(new ActionListener() {
|
||||
@Override public void actionPerformed(ActionEvent event) {
|
||||
hyperlink.setForeground(new Color(85, 145, 90));
|
||||
try {
|
||||
//java.awt.Desktop doesn't exist in 1.5.
|
||||
Object desktop = Class.forName("java.awt.Desktop").getMethod("getDesktop").invoke(null);
|
||||
Class.forName("java.awt.Desktop").getMethod("browse", URI.class).invoke(desktop, Installer.ABOUT_LOMBOK_URL);
|
||||
} catch (Exception e) {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
try {
|
||||
switch (IdeFinder.getOS()) {
|
||||
case WINDOWS:
|
||||
String[] cmd = new String[4];
|
||||
cmd[0] = "cmd.exe";
|
||||
cmd[1] = "/C";
|
||||
cmd[2] = "start";
|
||||
cmd[3] = Installer.ABOUT_LOMBOK_URL.toString();
|
||||
rt.exec(cmd);
|
||||
break;
|
||||
case MAC_OS_X:
|
||||
rt.exec("open " + Installer.ABOUT_LOMBOK_URL.toString());
|
||||
break;
|
||||
default:
|
||||
case UNIX:
|
||||
rt.exec("firefox " + Installer.ABOUT_LOMBOK_URL.toString());
|
||||
break;
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
JOptionPane.showMessageDialog(appWindow,
|
||||
"Well, this is embarrassing. I don't know how to open a webbrowser.\n" +
|
||||
"I guess you'll have to open it. Browse to:\n" + Installer.ABOUT_LOMBOK_URL +
|
||||
" for more information about Lombok.",
|
||||
"I'm embarrassed", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
buttonBar.add(hyperlink);
|
||||
buttonBar.add(Box.createRigidArea(new Dimension(16, 1)));
|
||||
buttonBar.add(new JLabel("<html><font size=\"-1\">v" + Version.getVersion() + "</font></html>"));
|
||||
|
||||
buttonBar.add(Box.createHorizontalGlue());
|
||||
buttonBar.add(quitButton);
|
||||
appWindow.add(buttonBar, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the installer window visible.
|
||||
*/
|
||||
public void show() {
|
||||
appWindow.setVisible(true);
|
||||
if (IdeFinder.getOS() == OS.MAC_OS_X) {
|
||||
try {
|
||||
AppleNativeLook.go();
|
||||
} catch (Throwable ignore) {
|
||||
//We're just prettying up the app. If it fails, meh.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String IDE_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>IDEs</i></b></font></html>";
|
||||
|
||||
private static final String IDE_EXPLANATION =
|
||||
"<html>Lombok can update your Eclipse and Netbeans to fully support all Lombok features.<br>" +
|
||||
"Select IDE installations below and hit 'Install/Update'.</html>";
|
||||
|
||||
private static final String IDE_LOADING_EXPLANATION =
|
||||
"Scanning your drives for IDE installations...";
|
||||
|
||||
private static final String JAVAC_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>Javac</i></b></font> (and tools that invoke javac such as <i>ant</i> and <i>maven</i>)</html>";
|
||||
|
||||
private static final String JAVAC_EXPLANATION =
|
||||
"<html>Lombok works 'out of the box' with javac.<br>Just make sure the lombok.jar is in your classpath when you compile.";
|
||||
|
||||
private static final String JAVAC_EXAMPLE =
|
||||
"<html>Example: <code>javac -cp lombok.jar MyCode.java</code></html>";
|
||||
|
||||
private static final String UNINSTALL_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>Uninstall</i></b></font></html>";
|
||||
|
||||
private static final String UNINSTALL_EXPLANATION =
|
||||
"<html>Uninstall Lombok from the following IDE Installations?</html>";
|
||||
|
||||
private static final String HOW_I_WORK_TITLE =
|
||||
"<html><font size=\"+1\"><b><i>What this installer does</i></b></font></html>";
|
||||
|
||||
private static final String HOW_I_WORK_EXPLANATION =
|
||||
"<html><h2>Eclipse</h2><ol>" +
|
||||
"<li>First, I copy myself (lombok.jar) to your Eclipse install directory.</li>" +
|
||||
"<li>Then, I edit the <i>eclipse.ini</i> file to add the following two entries:<br>" +
|
||||
"<pre>-Xbootclasspath/a:lombok.jar<br>" +
|
||||
"-javaagent:lombok.jar</pre></li></ol>" +
|
||||
"On Mac OS X, eclipse.ini is hidden in<br>" +
|
||||
"<code>Eclipse.app/Contents/MacOS</code> so that's where I place the jar files.<p>" +
|
||||
"<h2>Netbeans</h2><ol>" +
|
||||
"<li>First, I copy myself (lombok.jar) to your Netbeans install directory.</li>" +
|
||||
"<lI>Then, I edit <i>etc%1$snetbeans.conf</i> to add the following argument to<br><b>netbeans_default_options</b>:<br>" +
|
||||
"<pre>-J-javaagent:lombok.jar</pre></li></ol>" +
|
||||
"On Mac OS X, your netbeans directory is hidden in<br>" +
|
||||
"<code>NetBeans.app/Contents/Resources/NetBeans</code></html>";
|
||||
|
||||
private static class JHyperLink extends JButton {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JHyperLink(String text) {
|
||||
super();
|
||||
setFont(getFont().deriveFont(Collections.singletonMap(TextAttribute.UNDERLINE, 1)));
|
||||
setText(text);
|
||||
setBorder(null);
|
||||
setContentAreaFilled(false);
|
||||
setForeground(Color.BLUE);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
setMargin(new Insets(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package lombok.installer;
|
||||
|
||||
/**
|
||||
* Thrown when uninstallation of lombok into an IDE fails.
|
||||
*/
|
||||
public class UninstallException extends Exception {
|
||||
public UninstallException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
+26
-153
@@ -19,120 +19,22 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.installer;
|
||||
package lombok.installer.eclipse;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.Lombok;
|
||||
import lombok.core.Version;
|
||||
import lombok.installer.EclipseLocation.NotAnEclipseException;
|
||||
import lombok.installer.IdeFinder;
|
||||
import lombok.installer.IdeLocation;
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
|
||||
/** Utility class for doing various OS-specific operations related to finding Eclipse installations. */
|
||||
class EclipseFinder {
|
||||
private EclipseFinder() {
|
||||
//Prevent instantiation.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static File findOurJar() {
|
||||
try {
|
||||
URI uri = EclipseFinder.class.getResource("/" + EclipseFinder.class.getName().replace('.', '/') + ".class").toURI();
|
||||
Pattern p = Pattern.compile("^jar:file:([^\\!]+)\\!.*\\.class$");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 = EclipseFinder.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, regardless of what kind of drive is represented.
|
||||
*
|
||||
* @return A List of drive letters, such as ["A", "C", "D", "X"].
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
@ProviderFor(IdeFinder.class)
|
||||
public class EclipseFinder extends IdeFinder {
|
||||
/**
|
||||
* Returns a list of paths of Eclipse installations.
|
||||
* Eclipse installations are found by checking for the existence of 'eclipse.exe' in the following locations:
|
||||
@@ -144,7 +46,7 @@ class EclipseFinder {
|
||||
* Where 'X' is tried for all local disk drives, unless there's a problem calling fsutil, in which case only
|
||||
* C: is tried.
|
||||
*/
|
||||
private static void findEclipseOnWindows(List<EclipseLocation> locations, List<NotAnEclipseException> problems) {
|
||||
private static void findEclipseOnWindows(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
List<String> driveLetters = asList("C");
|
||||
try {
|
||||
driveLetters = getDrivesOnWindows();
|
||||
@@ -165,8 +67,8 @@ class EclipseFinder {
|
||||
String eclipseLocation = findEclipseOnWindows1(dir);
|
||||
if (eclipseLocation != null) {
|
||||
try {
|
||||
locations.add(EclipseLocation.create(eclipseLocation));
|
||||
} catch (NotAnEclipseException e) {
|
||||
locations.add(EclipseLocationProvider.create0(eclipseLocation));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
@@ -177,12 +79,12 @@ class EclipseFinder {
|
||||
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 (dir2.getName().toLowerCase().contains("eclipse")) {
|
||||
String eclipseLocation = findEclipseOnWindows1(dir2);
|
||||
if (eclipseLocation != null) {
|
||||
try {
|
||||
locations.add(EclipseLocation.create(eclipseLocation));
|
||||
} catch (NotAnEclipseException e) {
|
||||
locations.add(EclipseLocationProvider.create0(eclipseLocation));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
@@ -213,7 +115,8 @@ class EclipseFinder {
|
||||
* eclipses that can't be installed. Provide an empty list; this
|
||||
* method will fill it.
|
||||
*/
|
||||
static void findEclipses(List<EclipseLocation> locations, List<NotAnEclipseException> problems) {
|
||||
@Override
|
||||
public void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
switch (getOS()) {
|
||||
case WINDOWS:
|
||||
findEclipseOnWindows(locations, problems);
|
||||
@@ -228,38 +131,8 @@ class EclipseFinder {
|
||||
}
|
||||
}
|
||||
|
||||
static enum OS {
|
||||
MAC_OS_X, WINDOWS, UNIX;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the proper name of the executable for the local OS.
|
||||
*
|
||||
* @return 'Eclipse.app' on OS X, 'eclipse.exe' on Windows, and 'eclipse' on other OSes.
|
||||
*/
|
||||
static String getEclipseExecutableName() {
|
||||
switch (getOS()) {
|
||||
case WINDOWS:
|
||||
return "eclipse.exe";
|
||||
case MAC_OS_X:
|
||||
return "Eclipse.app";
|
||||
default:
|
||||
case UNIX:
|
||||
return "eclipse";
|
||||
}
|
||||
}
|
||||
|
||||
/** Scans a couple of likely locations on linux. */
|
||||
private static void findEclipseOnUnix(List<EclipseLocation> locations, List<NotAnEclipseException> problems) {
|
||||
private void findEclipseOnUnix(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
List<String> guesses = new ArrayList<String>();
|
||||
|
||||
File d;
|
||||
@@ -278,14 +151,14 @@ class EclipseFinder {
|
||||
|
||||
for (String guess : guesses) {
|
||||
try {
|
||||
locations.add(EclipseLocation.create(guess));
|
||||
} catch (NotAnEclipseException e) {
|
||||
locations.add(EclipseLocationProvider.create0(guess));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void findEclipseInSubDir(String dir, List<String> guesses) {
|
||||
private void findEclipseInSubDir(String dir, List<String> guesses) {
|
||||
File d = new File(dir);
|
||||
if (!d.isDirectory()) return;
|
||||
for (File f : d.listFiles()) {
|
||||
@@ -299,23 +172,23 @@ class EclipseFinder {
|
||||
/**
|
||||
* Scans /Applications for any folder named 'Eclipse'
|
||||
*/
|
||||
private static void findEclipseOnMac(List<EclipseLocation> locations, List<NotAnEclipseException> problems) {
|
||||
private void findEclipseOnMac(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
for (File dir : new File("/Applications").listFiles()) {
|
||||
if (!dir.isDirectory()) continue;
|
||||
if (dir.getName().toLowerCase().equals("eclipse.app")) {
|
||||
//This would be kind of an unorthodox Eclipse installation, but if Eclipse ever
|
||||
//moves to this more maclike installation concept, our installer can still handle it.
|
||||
try {
|
||||
locations.add(EclipseLocation.create("/Applications"));
|
||||
} catch (NotAnEclipseException e) {
|
||||
locations.add(EclipseLocationProvider.create0("/Applications"));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
if (dir.getName().toLowerCase().contains("eclipse")) {
|
||||
if (new File(dir, "Eclipse.app").exists()) {
|
||||
try {
|
||||
locations.add(EclipseLocation.create(dir.toString()));
|
||||
} catch (NotAnEclipseException e) {
|
||||
locations.add(EclipseLocationProvider.create0(dir.toString()));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
+33
-164
@@ -19,7 +19,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.installer;
|
||||
package lombok.installer.eclipse;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -28,162 +28,39 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
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;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
import lombok.installer.IdeFinder;
|
||||
import lombok.installer.IdeLocation;
|
||||
import lombok.installer.InstallException;
|
||||
import lombok.installer.UninstallException;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
public final class EclipseLocation extends IdeLocation {
|
||||
private final String name;
|
||||
private final File eclipseIniPath;
|
||||
private volatile boolean hasLombok;
|
||||
|
||||
/** Toggling the 'selected' checkbox in the GUI is tracked via this boolean */
|
||||
boolean selected = true;
|
||||
private static final String OS_NEWLINE = IdeFinder.getOS().getLineEnding();
|
||||
|
||||
/**
|
||||
* Thrown when creating a new EclipseLocation with a path object that doesn't, in fact,
|
||||
* point at an Eclipse installation.
|
||||
*/
|
||||
static final class NotAnEclipseException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public NotAnEclipseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
private EclipseLocation(String nameOfLocation, File pathToEclipseIni) throws NotAnEclipseException {
|
||||
EclipseLocation(String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException {
|
||||
this.name = nameOfLocation;
|
||||
this.eclipseIniPath = pathToEclipseIni;
|
||||
try {
|
||||
this.hasLombok = checkForLombok(eclipseIniPath);
|
||||
} catch (IOException e) {
|
||||
throw new NotAnEclipseException(
|
||||
throw new CorruptedIdeLocationException(
|
||||
"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,
|
||||
* or an eclipse.ini file.
|
||||
*
|
||||
* @throws NotAnEclipseException
|
||||
* If this isn't an Eclipse executable or a directory with an
|
||||
* Eclipse executable.
|
||||
*/
|
||||
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);
|
||||
if (p.isDirectory()) {
|
||||
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.isFile()) {
|
||||
if (p.getName().equalsIgnoreCase("eclipse.ini")) {
|
||||
return new EclipseLocation(getFilePath(p.getParentFile()), p);
|
||||
}
|
||||
|
||||
if (eclipseExecutableNames.contains(p.getName().toLowerCase())) {
|
||||
return findEclipseIniFromExe(p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
/* 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 {
|
||||
return p.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
String x = p.getAbsolutePath();
|
||||
return x == null ? p.getPath() : x;
|
||||
"You may need to run this installer with root privileges if you want to modify that Eclipse.", "eclipse", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,14 +78,16 @@ final class EclipseLocation {
|
||||
*
|
||||
* Executables: "eclipse.exe" (Windows), "Eclipse.app" (Mac OS X), "eclipse" (Linux and other unixes).
|
||||
*/
|
||||
String getName() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the Eclipse installation has been instrumented with lombok.
|
||||
*/
|
||||
boolean hasLombok() {
|
||||
@Override
|
||||
public boolean hasLombok() {
|
||||
return hasLombok;
|
||||
}
|
||||
|
||||
@@ -234,15 +113,6 @@ final class EclipseLocation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Thrown when uninstalling lombok fails. */
|
||||
static class UninstallException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UninstallException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns directories that may contain lombok.jar files that need to be deleted. */
|
||||
private List<File> getUninstallDirs() {
|
||||
List<File> result = new ArrayList<File>();
|
||||
@@ -263,7 +133,8 @@ final class EclipseLocation {
|
||||
* installation. bugs in the uninstall code will probably throw
|
||||
* other exceptions; this is intentional.
|
||||
*/
|
||||
void uninstall() throws UninstallException {
|
||||
@Override
|
||||
public void uninstall() throws UninstallException {
|
||||
for (File dir : getUninstallDirs()) {
|
||||
File lombokJar = new File(dir, "lombok.jar");
|
||||
if (lombokJar.exists()) {
|
||||
@@ -327,19 +198,10 @@ final class EclipseLocation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Thrown when installing lombok fails. */
|
||||
static class InstallException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InstallException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateWriteErrorMessage() {
|
||||
String osSpecificError;
|
||||
|
||||
switch (EclipseFinder.getOS()) {
|
||||
switch (IdeFinder.getOS()) {
|
||||
default:
|
||||
case MAC_OS_X:
|
||||
case UNIX:
|
||||
@@ -363,21 +225,20 @@ final class EclipseLocation {
|
||||
* installation. bugs in the install code will probably throw
|
||||
* other exceptions; this is intentional.
|
||||
*/
|
||||
void install() throws InstallException {
|
||||
@Override
|
||||
public String install() throws InstallException {
|
||||
// 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
|
||||
// breaking it. NB: rerunning lombok.jar installer and hitting 'update' will fix it if you do that.
|
||||
boolean fullPathRequired = EclipseFinder.getOS() == EclipseFinder.OS.UNIX;
|
||||
boolean fullPathRequired = IdeFinder.getOS() == EclipseFinder.OS.UNIX;
|
||||
|
||||
boolean installSucceeded = 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();
|
||||
File ourJar = findOurJar();
|
||||
byte[] b = new byte[524288];
|
||||
boolean readSucceeded = true;
|
||||
try {
|
||||
@@ -448,9 +309,9 @@ final class EclipseLocation {
|
||||
String fullPathToLombok = fullPathRequired ? (lombokJar.getParentFile().getCanonicalPath() + File.separator) : "";
|
||||
|
||||
newContents.append(String.format(
|
||||
"-javaagent:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE);
|
||||
"-javaagent:%s", escapePath(fullPathToLombok + "lombok.jar"))).append(OS_NEWLINE);
|
||||
newContents.append(String.format(
|
||||
"-Xbootclasspath/a:%slombok.jar", fullPathToLombok)).append(OS_NEWLINE);
|
||||
"-Xbootclasspath/a:%s", escapePath(fullPathToLombok + "lombok.jar"))).append(OS_NEWLINE);
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(eclipseIniPath);
|
||||
try {
|
||||
@@ -470,5 +331,13 @@ final class EclipseLocation {
|
||||
if (!installSucceeded) {
|
||||
throw new InstallException("I can't find the eclipse.ini file. Is this a real Eclipse installation?", null);
|
||||
}
|
||||
|
||||
return "If you start eclipse with a custom -vm parameter, you'll need to add:<br>" +
|
||||
"<code>-vmargs -Xbootclasspath/a:lombok.jar -javaagent:lombok.jar</code><br>" +
|
||||
"as parameter as well.";
|
||||
}
|
||||
|
||||
@Override public URL getIdeIcon() {
|
||||
return EclipseLocation.class.getResource("eclipse.png");
|
||||
}
|
||||
}
|
||||
@@ -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.eclipse;
|
||||
|
||||
import static lombok.installer.IdeLocation.canonical;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.installer.IdeLocation;
|
||||
import lombok.installer.IdeLocationProvider;
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
import lombok.installer.IdeFinder.OS;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
@ProviderFor(IdeLocationProvider.class)
|
||||
public class EclipseLocationProvider implements IdeLocationProvider {
|
||||
@Override public IdeLocation create(String path) throws CorruptedIdeLocationException {
|
||||
return create0(path);
|
||||
}
|
||||
|
||||
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 contains the Eclipse executable, or the executable itself,
|
||||
* or an eclipse.ini file.
|
||||
*
|
||||
* @throws NotAnIdeLocationException
|
||||
* If this isn't an Eclipse executable or a directory with an
|
||||
* Eclipse executable.
|
||||
*/
|
||||
static EclipseLocation create0(String path) throws CorruptedIdeLocationException {
|
||||
if (path == null) throw new NullPointerException("path");
|
||||
File p = new File(path);
|
||||
|
||||
if (!p.exists()) return null;
|
||||
if (p.isDirectory()) {
|
||||
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(canonical(p), f);
|
||||
}
|
||||
|
||||
if (p.isFile()) {
|
||||
if (p.getName().equalsIgnoreCase("eclipse.ini")) {
|
||||
return new EclipseLocation(canonical(p.getParentFile()), p);
|
||||
}
|
||||
|
||||
if (eclipseExecutableNames.contains(p.getName().toLowerCase())) {
|
||||
return findEclipseIniFromExe(p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static EclipseLocation findEclipseIniFromExe(File exePath, int loopCounter) throws CorruptedIdeLocationException {
|
||||
/* Try looking for eclipse.ini as sibling to the executable */ {
|
||||
File ini = new File(exePath.getParentFile(), "eclipse.ini");
|
||||
if (ini.isFile()) return new EclipseLocation(canonical(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(canonical(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 {
|
||||
EclipseLocation loc = findEclipseIniFromExe(new File(nPath), loopCounter + 1);
|
||||
if (loc != null) return loc;
|
||||
} catch (CorruptedIdeLocationException 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. */
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public Pattern getLocationSelectors(OS os) {
|
||||
switch (os) {
|
||||
case MAC_OS_X:
|
||||
return Pattern.compile("^(eclipse|eclipse\\.ini|eclipse\\.app)$", Pattern.CASE_INSENSITIVE);
|
||||
case WINDOWS:
|
||||
return Pattern.compile("^(eclipse\\.exe|eclipse\\.ini)$", Pattern.CASE_INSENSITIVE);
|
||||
default:
|
||||
case UNIX:
|
||||
return Pattern.compile("^(eclipse|eclipse\\.ini)$", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.netbeans;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
import lombok.installer.IdeFinder;
|
||||
import lombok.installer.IdeLocation;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/** Utility class for doing various OS-specific operations related to finding Netbeans installations. */
|
||||
@ProviderFor(IdeFinder.class)
|
||||
public class NetbeansFinder extends IdeFinder {
|
||||
/**
|
||||
* Returns a list of paths of Netbeans installations.
|
||||
*
|
||||
* Netbeans installations are found by checking for the existence of 'netbeans.exe' in the following locations:
|
||||
* <ul>
|
||||
* <li>X:\*Program Files*\*NetBeans*</li>
|
||||
* <li>X:\*NetBeans*</li>
|
||||
* </ul>
|
||||
*
|
||||
* Where 'X' is tried for all local disk drives, unless there's a problem calling fsutil, in which case only
|
||||
* C: is tried.
|
||||
*/
|
||||
private void findNetbeansOnWindows(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
List<String> driveLetters = asList("C");
|
||||
try {
|
||||
driveLetters = getDrivesOnWindows();
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
|
||||
//Various try/catch/ignore statements are in this for loop. Weird conditions on the disk can cause exceptions,
|
||||
//such as an unformatted drive causing a NullPointerException on listFiles. Best action is almost invariably to just
|
||||
//continue onwards.
|
||||
for (String letter : driveLetters) {
|
||||
try {
|
||||
File f = new File(letter + ":\\");
|
||||
for (File dir : f.listFiles()) {
|
||||
if (!dir.isDirectory()) continue;
|
||||
try {
|
||||
if (dir.getName().toLowerCase().contains("netbeans")) {
|
||||
String netbeansLocation = findNetbeansOnWindows1(dir);
|
||||
if (netbeansLocation != null) {
|
||||
try {
|
||||
locations.add(NetbeansLocationProvider.create0(netbeansLocation));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
try {
|
||||
if (dir.getName().toLowerCase().contains("program files")) {
|
||||
for (File dir2 : dir.listFiles()) {
|
||||
if (!dir2.isDirectory()) continue;
|
||||
if (dir2.getName().toLowerCase().contains("netbeans")) {
|
||||
String netbeansLocation = findNetbeansOnWindows1(dir2);
|
||||
if (netbeansLocation != null) {
|
||||
try {
|
||||
locations.add(NetbeansLocationProvider.create0(netbeansLocation));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if the provided directory contains 'netbeans.exe', and if so, returns the directory, otherwise null. */
|
||||
private String findNetbeansOnWindows1(File dir) {
|
||||
if (new File(dir, "netbeans.exe").isFile()) return dir.getAbsolutePath();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the OS-dependent 'find Netbeans' routine. If the local OS doesn't have a routine written for it,
|
||||
* null is returned.
|
||||
*
|
||||
* @param locations
|
||||
* List of valid netbeans locations - provide an empty list; this
|
||||
* method will fill it.
|
||||
* @param problems
|
||||
* List of netbeans locations that seem to contain half-baked
|
||||
* netbeanses that can't be installed. Provide an empty list; this
|
||||
* method will fill it.
|
||||
*/
|
||||
@Override
|
||||
public void findIdes(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
switch (getOS()) {
|
||||
case WINDOWS:
|
||||
findNetbeansOnWindows(locations, problems);
|
||||
break;
|
||||
case MAC_OS_X:
|
||||
findNetbeansOnMac(locations, problems);
|
||||
break;
|
||||
default:
|
||||
case UNIX:
|
||||
findNetbeansOnUnix(locations, problems);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Scans a couple of likely locations on linux. */
|
||||
private void findNetbeansOnUnix(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
List<String> guesses = new ArrayList<String>();
|
||||
|
||||
File d;
|
||||
|
||||
d = new File("/usr/bin/netbeans");
|
||||
if (d.exists()) guesses.add(d.getPath());
|
||||
d = new File("/usr/local/bin/netbeans");
|
||||
if (d.exists()) guesses.add(d.getPath());
|
||||
d = new File(System.getProperty("user.home", "."), "bin/netbeans");
|
||||
if (d.exists()) guesses.add(d.getPath());
|
||||
|
||||
findNetbeansInSubDir("/usr/local/share", guesses);
|
||||
findNetbeansInSubDir("/usr/local", guesses);
|
||||
findNetbeansInSubDir("/usr/share", guesses);
|
||||
findNetbeansInSubDir(System.getProperty("user.home", "."), guesses);
|
||||
|
||||
for (String guess : guesses) {
|
||||
try {
|
||||
locations.add(NetbeansLocationProvider.create0(guess));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void findNetbeansInSubDir(String dir, List<String> guesses) {
|
||||
File d = new File(dir);
|
||||
if (!d.isDirectory()) return;
|
||||
for (File f : d.listFiles()) {
|
||||
if (f.isDirectory() && f.getName().toLowerCase().contains("netbeans")) {
|
||||
File possible = new File(f, "bin/netbeans.exe");
|
||||
if (possible.exists()) guesses.add(possible.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans /Applications for any folder named 'Eclipse'
|
||||
*/
|
||||
private static void findNetbeansOnMac(List<IdeLocation> locations, List<CorruptedIdeLocationException> problems) {
|
||||
for (File dir : new File("/Applications").listFiles()) {
|
||||
if (!dir.isDirectory()) continue;
|
||||
if (dir.getName().toLowerCase().startsWith("netbeans") && dir.getName().toLowerCase().endsWith(".app")) {
|
||||
try {
|
||||
locations.add(NetbeansLocationProvider.create0(dir.getAbsolutePath()));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
if (dir.getName().toLowerCase().contains("netbeans")) {
|
||||
for (File dir2 : dir.listFiles()) {
|
||||
if (!dir2.isDirectory()) continue;
|
||||
if (dir2.getName().toLowerCase().startsWith("netbeans") && dir2.getName().toLowerCase().endsWith(".app")) {
|
||||
try {
|
||||
locations.add(NetbeansLocationProvider.create0(dir2.getAbsolutePath()));
|
||||
} catch (CorruptedIdeLocationException e) {
|
||||
problems.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* 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.netbeans;
|
||||
|
||||
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.net.URL;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
import lombok.installer.IdeFinder;
|
||||
import lombok.installer.IdeLocation;
|
||||
import lombok.installer.InstallException;
|
||||
import lombok.installer.UninstallException;
|
||||
|
||||
public class NetbeansLocation extends IdeLocation {
|
||||
private final String name;
|
||||
private final File netbeansConfPath;
|
||||
private volatile boolean hasLombok;
|
||||
|
||||
private static final String OS_NEWLINE = IdeFinder.getOS().getLineEnding();
|
||||
|
||||
NetbeansLocation(String nameOfLocation, File pathToNetbeansConf) throws CorruptedIdeLocationException {
|
||||
this.name = nameOfLocation;
|
||||
this.netbeansConfPath = pathToNetbeansConf;
|
||||
try {
|
||||
this.hasLombok = checkForLombok(netbeansConfPath);
|
||||
} catch (IOException e) {
|
||||
throw new CorruptedIdeLocationException(
|
||||
"I can't read the configuration file of the Netbeans installed at " + name + "\n" +
|
||||
"You may need to run this installer with root privileges if you want to modify that Netbeans.", "netbeans", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return netbeansConfPath.hashCode();
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (!(o instanceof NetbeansLocation)) return false;
|
||||
return ((NetbeansLocation)o).netbeansConfPath.equals(netbeansConfPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this location; generally the path to the netbeans executable.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the Netbeans installation has been instrumented with lombok.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasLombok() {
|
||||
return hasLombok;
|
||||
}
|
||||
|
||||
private final String ID_CHARS = "(?:\\\\.|[^\"\\\\])*";
|
||||
private final String ID_CHARS_NS = "(?:\\\\.|[^\"\\\\ ])*";
|
||||
private final Pattern JAVA_AGENT_LINE_MATCHER = Pattern.compile(
|
||||
"^\\s*netbeans_default_options\\s*=\\s*\"\\s*" + ID_CHARS + "(?<=[ \"])(-J-javaagent:" + ID_CHARS_NS + "lombok" + ID_CHARS_NS + "\\.jar)(?=[ \"])" + ID_CHARS +"\\s*\"\\s*(?:#.*)?$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private final Pattern OPTIONS_LINE_MATCHER = Pattern.compile(
|
||||
"^\\s*netbeans_default_options\\s*=\\s*\"\\s*" + ID_CHARS + "\\s*(\")\\s*(?:#.*)?$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private boolean checkForLombok(File iniFile) throws IOException {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Override
|
||||
public void uninstall() throws UninstallException {
|
||||
File dir = netbeansConfPath.getParentFile();
|
||||
File lombokJar = new File(dir, "lombok.jar");
|
||||
if (lombokJar.exists()) {
|
||||
if (!lombokJar.delete()) throw new UninstallException(
|
||||
"Can't delete " + lombokJar.getAbsolutePath() + generateWriteErrorMessage(), null);
|
||||
}
|
||||
|
||||
StringBuilder newContents = new StringBuilder();
|
||||
if (netbeansConfPath.exists()) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(netbeansConfPath);
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
Matcher m = JAVA_AGENT_LINE_MATCHER.matcher(line);
|
||||
if (m.matches()) {
|
||||
newContents.append(line.substring(0, m.start(1)) + line.substring(m.end(1)));
|
||||
} else {
|
||||
newContents.append(line);
|
||||
}
|
||||
newContents.append(OS_NEWLINE);
|
||||
}
|
||||
} finally {
|
||||
fis.close();
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(netbeansConfPath);
|
||||
try {
|
||||
fos.write(newContents.toString().getBytes());
|
||||
} finally {
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UninstallException("Cannot uninstall lombok from " + name + generateWriteErrorMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateWriteErrorMessage() {
|
||||
String osSpecificError;
|
||||
|
||||
switch (IdeFinder.getOS()) {
|
||||
default:
|
||||
case MAC_OS_X:
|
||||
case UNIX:
|
||||
osSpecificError = ":\nStart terminal, go to the directory with lombok.jar, and run: sudo java -jar lombok.jar";
|
||||
break;
|
||||
case WINDOWS:
|
||||
osSpecificError = ":\nStart a new cmd (dos box) with admin privileges, go to the directory with lombok.jar, and run: java -jar lombok.jar";
|
||||
break;
|
||||
}
|
||||
|
||||
return ", probably because this installer does not have the access rights.\n" +
|
||||
"Try re-running the installer with administrative privileges" + osSpecificError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install lombok into the Netbeans 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.
|
||||
*/
|
||||
@Override
|
||||
public String install() throws InstallException {
|
||||
boolean installSucceeded = false;
|
||||
StringBuilder newContents = new StringBuilder();
|
||||
|
||||
File lombokJar = new File(netbeansConfPath.getParentFile(), "lombok.jar");
|
||||
|
||||
File ourJar = findOurJar();
|
||||
byte[] b = new byte[524288];
|
||||
boolean readSucceeded = true;
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(lombokJar);
|
||||
try {
|
||||
readSucceeded = false;
|
||||
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();
|
||||
}
|
||||
} 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 Netbeans directory at " + name + generateWriteErrorMessage(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(netbeansConfPath);
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
Matcher m = JAVA_AGENT_LINE_MATCHER.matcher(line);
|
||||
if (m.matches()) {
|
||||
newContents.append(line.substring(0, m.start(1)));
|
||||
newContents.append("-J-javaagent:" + escapePath(canonical(lombokJar)));
|
||||
newContents.append(line.substring(m.end(1)));
|
||||
newContents.append(OS_NEWLINE);
|
||||
continue;
|
||||
}
|
||||
|
||||
m = OPTIONS_LINE_MATCHER.matcher(line);
|
||||
if (m.matches()) {
|
||||
newContents.append(line.substring(0, m.start(1)));
|
||||
newContents.append(" ").append("-J-javaagent:" + escapePath(canonical(lombokJar)) +"\"");
|
||||
newContents.append(line.substring(m.end(1))).append(OS_NEWLINE);
|
||||
continue;
|
||||
}
|
||||
|
||||
newContents.append(line).append(OS_NEWLINE);
|
||||
}
|
||||
} finally {
|
||||
fis.close();
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(netbeansConfPath);
|
||||
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 netbeans.conf file. Is this a real Netbeans installation?", null);
|
||||
}
|
||||
|
||||
return "If you start netbeans with custom parameters, you'll need to add:<br>" +
|
||||
"<code>-J-javaagent:" + escapePath(canonical(lombokJar)) + "</code><br>" +
|
||||
"as parameter as well.";
|
||||
}
|
||||
|
||||
@Override public URL getIdeIcon() {
|
||||
return NetbeansLocation.class.getResource("netbeans.png");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.netbeans;
|
||||
|
||||
import static lombok.installer.IdeLocation.canonical;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.installer.CorruptedIdeLocationException;
|
||||
import lombok.installer.IdeLocation;
|
||||
import lombok.installer.IdeLocationProvider;
|
||||
import lombok.installer.IdeFinder.OS;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
@ProviderFor(IdeLocationProvider.class)
|
||||
public class NetbeansLocationProvider implements IdeLocationProvider {
|
||||
|
||||
@Override public IdeLocation create(String path) throws CorruptedIdeLocationException {
|
||||
return create0(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new NetbeansLocation by pointing at either the directory containing the executable, or the executable itself,
|
||||
* or a netbeans.conf file.
|
||||
*
|
||||
* @throws NotAnIdeLocationException
|
||||
* If this isn't an Eclipse executable or a directory with an
|
||||
* Eclipse executable.
|
||||
*/
|
||||
static NetbeansLocation create0(String path) throws CorruptedIdeLocationException {
|
||||
if (path == null) throw new NullPointerException("path");
|
||||
File p = new File(path);
|
||||
|
||||
if (!p.exists()) return null;
|
||||
if (p.isDirectory()) {
|
||||
String name = p.getName().toLowerCase();
|
||||
if (name.endsWith(".app") && name.startsWith("netbeans")) {
|
||||
File conf = new File(p, "Contents/Resources/NetBeans/etc/netbeans.conf");
|
||||
if (conf.exists()) return new NetbeansLocation(path, conf);
|
||||
}
|
||||
|
||||
File f = new File(p, "netbeans");
|
||||
if (f.isFile()) return findNetbeansConfFromExe(f, 0);
|
||||
f = new File(p, "netbeans.exe");
|
||||
if (f.isFile()) return findNetbeansConfFromExe(f, 0);
|
||||
f = new File(p, "netbeans.conf");
|
||||
if (f.isFile()) return new NetbeansLocation(canonical(f.getParentFile().getParentFile()), f);
|
||||
}
|
||||
|
||||
if (p.isFile()) {
|
||||
if (p.getName().equalsIgnoreCase("netbeans.conf")) {
|
||||
return new NetbeansLocation(canonical(p.getParentFile().getParentFile()), p);
|
||||
}
|
||||
|
||||
if (p.getName().equalsIgnoreCase("netbeans") || p.getName().equalsIgnoreCase("netbeans.exe")) {
|
||||
return findNetbeansConfFromExe(p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static NetbeansLocation findNetbeansConfFromExe(File exePath, int loopCounter) throws CorruptedIdeLocationException {
|
||||
/* Try looking for netbeans.conf as etc/netbeans.conf */ {
|
||||
File conf = new File(exePath.getParentFile(), "etc/netbeans.conf");
|
||||
if (conf.isFile()) return new NetbeansLocation(canonical(exePath), conf);
|
||||
}
|
||||
|
||||
/* Try looking for netbeans.conf as ../etc/netbeans.conf */ {
|
||||
File conf = new File(exePath.getParentFile().getParentFile(), "etc/netbeans.conf");
|
||||
if (conf.isFile()) return new NetbeansLocation(canonical(exePath), conf);
|
||||
}
|
||||
|
||||
/* 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 findNetbeansConfFromExe(new File(nPath), loopCounter + 1);
|
||||
} catch (CorruptedIdeLocationException ignore) {
|
||||
// Unlinking didn't help find a netbeans, so continue.
|
||||
}
|
||||
} catch (IOException ignore) { /* okay, that didn't work, assume it isn't a soft link then. */ }
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get this far, we lose. */
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public Pattern getLocationSelectors(OS os) {
|
||||
switch (os) {
|
||||
case MAC_OS_X:
|
||||
return Pattern.compile("^(netbeans|netbeans\\.conf|NetBeans.*\\.app)$", Pattern.CASE_INSENSITIVE);
|
||||
case WINDOWS:
|
||||
return Pattern.compile("^(netbeans\\.exe|netbeans\\.ini)$", Pattern.CASE_INSENSITIVE);
|
||||
default:
|
||||
case UNIX:
|
||||
return Pattern.compile("^(netbeans|netbeans\\.conf)$", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Reference in new issue
Block a user