deleted netbeans agent. With the new resolution features it'll never work, and netbeans has supported lombok as a plain annotation processor for quite a while now.

This commit is contained in:
Reinier Zwitserloot committed 2010-11-10 00:32:56 +01:00
1 parent 63519f9ae6
commit d02a0f823f
9 files changed
-1163

No files matched your search

-4
View File
@@ -130,10 +130,8 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
<ivy:compile destdir="build/lombok" source="1.6" target="1.6">
<src path="src/core" />
<src path="src/delombok" />
<src path="src/netbeansAgent" />
<include name="lombok/javac/**" />
<include name="lombok/delombok/**" />
<include name="lombok/netbeans/**" />
<classpath location="build/lombok" />
<classpath refid="build.path" />
</ivy:compile>
@@ -165,7 +163,6 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
<ivy:eclipsegen>
<srcdir dir="src/core" />
<srcdir dir="src/eclipseAgent" />
<srcdir dir="src/netbeansAgent" />
<srcdir dir="src/installer" />
<srcdir dir="src/delombok" />
<srcdir dir="experimental/src" />
@@ -250,7 +247,6 @@ the common tasks and can be called on to run the main aspects of all the sub-scr
<sources>
<fileset dir="src/core" />
<fileset dir="src/eclipseAgent" />
<fileset dir="src/netbeansAgent" />
<fileset dir="src/installer" />
<fileset dir="src/delombok" />
<fileset dir="experimental/src" />
@@ -1,206 +0,0 @@
/*
* 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 {
IdeLocation newLocation = NetbeansLocationProvider.create0(netbeansLocation);
if (newLocation != null) locations.add(newLocation);
} 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 {
IdeLocation newLocation = NetbeansLocationProvider.create0(netbeansLocation);
if (newLocation != null) locations.add(newLocation);
} 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, "bin/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 {
IdeLocation newLocation = NetbeansLocationProvider.create0(guess);
if (newLocation != null) locations.add(newLocation);
} 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");
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 {
IdeLocation newLocation = NetbeansLocationProvider.create0(dir.getAbsolutePath());
if (newLocation != null) locations.add(newLocation);
} 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 {
IdeLocation newLocation = NetbeansLocationProvider.create0(dir2.getAbsolutePath());
if (newLocation != null) locations.add(newLocation);
} catch (CorruptedIdeLocationException e) {
problems.add(e);
}
}
}
}
}
}
}
@@ -1,410 +0,0 @@
/*
* Copyright © 2009-2010 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.ArrayList;
import java.util.List;
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.Installer;
import lombok.installer.UninstallException;
public class NetbeansLocation extends IdeLocation {
private final String name;
private final File netbeansConfPath;
private final String version;
private final int versionFirst, versionSecond;
private final 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);
}
this.version = findNetbeansVersion(netbeansConfPath);
int first, second;
String[] vs = version.split("\\.");
try {
first = Integer.parseInt(vs[0]);
} catch (Exception e) {
first = 0;
}
try {
second = Integer.parseInt(vs[1]);
} catch (Exception e) {
second = 0;
}
this.versionFirst = first;
this.versionSecond = second;
}
public boolean versionIsPre68() {
return versionFirst < 6 || (versionFirst == 6 && versionSecond < 8);
}
public boolean versionIs68() {
return versionFirst == 6 && versionSecond == 8;
}
public boolean versionIsPost68() {
return versionFirst > 6 || (versionFirst == 6 && versionSecond > 8);
}
@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 Pattern JAVA_AGENT_LINE_MATCHER = Pattern.compile(
"^\\s*netbeans_default_options\\s*=\\s*\"\\s*" + ID_CHARS + "(?<=[ \"])(-J-javaagent:\\\\\".*lombok.*\\.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 String findNetbeansVersion(File iniFile) {
String forcedVersion = System.getProperty("force.netbeans.version", null);
if (forcedVersion != null) return forcedVersion;
try {
for (File child : iniFile.getParentFile().getParentFile().listFiles()) {
if (!child.isDirectory()) continue;
String name = child.getName();
if (name == null || !name.startsWith("nb")) continue;
String version = name.substring(2);
File versionFile = new File(child, "VERSION.txt");
if (versionFile.exists() && versionFile.canRead() && !versionFile.isDirectory()) {
try {
version = readVersionFile(versionFile);
} catch (IOException e) {
// Intentional Fallthrough
}
}
if (version != null && version.length() > 0) {
return version;
}
}
} catch (NullPointerException e) {
// Intentional Fallthrough
}
return "UNKNOWN";
}
private static String readVersionFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
StringBuilder version = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
for (String line = br.readLine(); line != null; line = br.readLine()) {
if (line.startsWith("#")) continue;
if (version.length() > 0) version.append(" ");
version.append(line);
}
return version.toString();
} finally {
fis.close();
}
}
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 {
final List<File> lombokJarsForWhichCantDeleteSelf = new ArrayList<File>();
File dir = netbeansConfPath.getParentFile();
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);
}
}
File lombokJar = new File(dir, "lombok.jar");
if (lombokJar.exists()) {
if (!lombokJar.delete()) {
if (IdeFinder.getOS() == IdeFinder.OS.WINDOWS && Installer.isSelf(lombokJar.getAbsolutePath())) {
lombokJarsForWhichCantDeleteSelf.add(lombokJar);
} else {
throw new UninstallException(
"Can't delete " + lombokJar.getAbsolutePath() + generateWriteErrorMessage(), null);
}
}
}
if (!lombokJarsForWhichCantDeleteSelf.isEmpty()) {
throw new UninstallException(true,
"lombok.jar cannot delete itself on windows.\nHowever, lombok has been uncoupled from your netbeans.\n" +
"You can safely delete this jar file. You can find it at:\n" +
lombokJarsForWhichCantDeleteSelf.get(0).getAbsolutePath(), null);
}
}
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 {
if ("UNKNOWN".equals(version)) {
throw new InstallException(String.format(
"Can't determine version of Netbeans installed at:\n%s\n\n" +
"Your Netbeans version determines what this installer does:\n" +
"Pre 6.8: Lombok is not compatible with netbeans pre 6.8, and thus won't install.\n" +
"6.8: Lombok will install itself into Netbeans.\n" +
"6.9 and later: NetBeans supports lombok natively. This installer will explain how to enable it.\n\n" +
"If you know your netbeans version, you can force this by starting the installer with:\n" +
"java -Dforce.netbeans.version=6.8 -jar lombok.jar", this.getName()), null);
}
if (versionIsPre68()) {
throw new InstallException(String.format(
"Lombok is not compatible with Netbeans versions prior to 6.8.\n" +
"Therefore, lombok will not be installed at:\n%s\nbecause it is version: %s",
this.getName(), version), null);
}
if (versionIsPost68()) {
try {
uninstall();
} catch (Exception e) {
// Well, we tried. Lombok on 6.9 doesn't do anything, so we'll leave it then.
}
throw new InstallException(true, String.format(
"Starting with NetBeans 6.9, lombok is natively supported and does not need to be installed at:\n%s\n\n" +
"To use lombok.jar in your netbeans project:\n" +
"1. Add lombok.jar to your project (Go to Project Properties, 'Libraries' page, and add lombok.jar in the 'Compile' tab).\n" +
"2. Enable Annotation Processors (Go to Project Properties, 'Build/Compiling' page, and check 'Enable Annotation Processing in Editor').\n" +
"\n" +
"NB: In the first release of NetBeans 6.9, due to a netbeans bug, maven-based projects don't run annotation processors. This \n" +
"issue should be fixed by the great folks at NetBeans soon.", this.getName()), null);
}
boolean installSucceeded = false;
StringBuilder newContents = new StringBuilder();
File lombokJar = new File(netbeansConfPath.getParentFile(), "lombok.jar");
/* No need to copy lombok.jar to itself, obviously. On windows this would generate an error so we check for this. */
if (!Installer.isSelf(lombokJar.getAbsolutePath())) {
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:\\\"" + 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:\\\"" + 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:\\\"" + canonical(lombokJar) + "\\\"</code><br>" +
"as parameter as well.";
}
@Override public URL getIdeIcon() {
return NetbeansLocation.class.getResource("netbeans.png");
}
}
@@ -1,125 +0,0 @@
/*
* 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, "bin/netbeans");
if (f.isFile()) return findNetbeansConfFromExe(f, 0);
f = new File(p, "bin/netbeans.exe");
if (f.isFile()) return findNetbeansConfFromExe(f, 0);
f = new File(p, "etc/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\\.conf)$", Pattern.CASE_INSENSITIVE);
default:
case UNIX:
return Pattern.compile("^(netbeans|netbeans\\.conf)$", Pattern.CASE_INSENSITIVE);
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

@@ -1,75 +0,0 @@
/*
* 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.netbeans.agent;
import java.util.Collections;
import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic.Kind;
import lombok.javac.JavacTransformer;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
public class NetbeansEntryPoint implements TaskListener {
public class DummyMessager implements Messager {
@Override public void printMessage(Kind kind, CharSequence msg) {
System.err.printf("%s: %s\n", kind, msg);
}
@Override public void printMessage(Kind kind, CharSequence msg, Element e) {
printMessage(kind, msg);
}
@Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) {
printMessage(kind, msg);
}
@Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) {
printMessage(kind, msg);
}
}
private final Context context;
public NetbeansEntryPoint(Context context) {
this.context = context;
}
@Override public void started(TaskEvent event) {
//we run at the end, so all the action is in #finished.
}
@Override public void finished(TaskEvent event) {
if (TaskEvent.Kind.PARSE == event.getKind()) {
JavacTransformer transformer = new JavacTransformer(new DummyMessager()); //TODO hook into netbeans error reporting!
JCCompilationUnit compilationUnit = (JCCompilationUnit) event.getCompilationUnit();
transformer.transform(context, Collections.singletonList(compilationUnit));
}
}
}
@@ -1,134 +0,0 @@
/*
* 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.netbeans.agent;
import java.lang.instrument.Instrumentation;
import lombok.core.Agent;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
import lombok.patcher.StackRequest;
import lombok.patcher.scripts.ScriptBuilder;
/**
* This is a java-agent that patches some of netbeans's classes so that lombok is initialized as Javac TaskListener,
* allowing us to change AST nodes anytime netbeans parses source code. It also fixes some of the places in netbeans that
* can't deal with generated code.
*
* The hard work on figuring out where to patch has been done by Jan Lahoda (jlahoda@netbeans.org)
*/
public class NetbeansPatcher extends Agent {
@Override
public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception {
registerPatchScripts(instrumentation, injected);
}
private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses) {
ScriptManager sm = new ScriptManager();
sm.registerTransformer(instrumentation);
patchNetbeansClassLoader(sm);
patchNetbeansJavac(sm);
patchNetbeansMissingPositionAwareness(sm);
if (reloadExistingClasses) sm.reloadClasses(instrumentation);
}
private static void patchNetbeansClassLoader(ScriptManager sm) {
sm.addScript(ScriptBuilder.exitEarly()
.transplant().request(StackRequest.PARAM1, StackRequest.PARAM2)
.target(new MethodTarget("org.netbeans.StandardModule$OneModuleClassLoader", "<init>"))
.decisionMethod(new Hook("lombok.netbeans.agent.PatchFixes", "addSelfToClassLoader", "void", "org.netbeans.Module", "java.util.List"))
.build());
sm.addScript(ScriptBuilder.exitEarly()
.transplant()
.request(StackRequest.THIS, StackRequest.PARAM1)
.target(new MethodTarget("org.netbeans.ProxyClassLoader", "getResource"))
.decisionMethod(new Hook("lombok.netbeans.agent.PatchFixes", "getResource_decision", "boolean", "java.lang.ClassLoader", "java.lang.String"))
.valueMethod(new Hook("lombok.netbeans.agent.PatchFixes", "getResource_value", "java.net.URL", "java.lang.ClassLoader", "java.lang.String"))
.build());
sm.addScript(ScriptBuilder.exitEarly()
.transplant()
.request(StackRequest.THIS, StackRequest.PARAM1)
.target(new MethodTarget("org.netbeans.ProxyClassLoader", "getResources"))
.decisionMethod(new Hook("lombok.netbeans.agent.PatchFixes", "getResources_decision", "boolean", "java.lang.ClassLoader", "java.lang.String"))
.valueMethod(new Hook("lombok.netbeans.agent.PatchFixes", "getResources_value", "java.util.Enumeration", "java.lang.ClassLoader", "java.lang.String"))
.build());
sm.addScript(ScriptBuilder.exitEarly()
.transplant()
.target(new MethodTarget("org.netbeans.ProxyClassLoader", "loadClass"))
.request(StackRequest.THIS, StackRequest.PARAM1)
.decisionMethod(new Hook("lombok.netbeans.agent.PatchFixes", "loadClass_decision", "boolean", "java.lang.ClassLoader", "java.lang.String"))
.valueMethod(new Hook("lombok.netbeans.agent.PatchFixes", "loadClass_value", "java.lang.Class", "java.lang.ClassLoader", "java.lang.String"))
.build());
}
private static void patchNetbeansJavac(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.request(StackRequest.THIS, StackRequest.PARAM1)
.transplant()
.target(new MethodTarget("com.sun.tools.javac.api.JavacTaskImpl", "setTaskListener"))
.wrapMethod(new Hook("lombok.netbeans.agent.PatchFixes", "fixContentOnSetTaskListener", "void",
"com.sun.tools.javac.api.JavacTaskImpl", "com.sun.source.util.TaskListener"))
.build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.request(StackRequest.RETURN_VALUE, StackRequest.PARAM1)
.transplant()
.target(new MethodTarget("org.netbeans.modules.java.source.parsing.JavacParser", "createJavacTask",
"com.sun.tools.javac.api.JavacTaskImpl",
"org.netbeans.api.java.source.ClasspathInfo", "javax.tools.DiagnosticListener", "java.lang.String", "boolean",
"com.sun.tools.javac.api.ClassNamesForFileOraculum", "com.sun.tools.javac.util.CancelService"))
.wrapMethod(new Hook("lombok.netbeans.agent.PatchFixes", "addTaskListenerWhenCallingJavac", "void",
"com.sun.tools.javac.api.JavacTaskImpl", "org.netbeans.api.java.source.ClasspathInfo"))
.build());
}
private static void patchNetbeansMissingPositionAwareness(ScriptManager sm) {
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.netbeans.modules.java.editor.overridden.ComputeAnnotations",
"createAnnotations"))
.methodToReplace(new Hook("com.sun.source.util.Trees", "getTree", "com.sun.source.tree.Tree",
"javax.lang.model.element.Element"))
.replacementMethod(new Hook("lombok.netbeans.agent.PatchFixes", "returnNullForGeneratedNode", "com.sun.source.tree.Tree",
"com.sun.source.util.Trees", "javax.lang.model.element.Element", "java.lang.Object"))
.requestExtra(StackRequest.PARAM1).transplant()
.build());
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.netbeans.modules.java.source.parsing.FindMethodRegionsVisitor",
"visitMethod"))
.methodToReplace(new Hook("com.sun.source.util.SourcePositions", "getEndPosition", "long",
"com.sun.source.tree.CompilationUnitTree", "com.sun.source.tree.Tree"))
.replacementMethod(new Hook("lombok.netbeans.agent.PatchFixes", "returnMinus1ForGeneratedNode", "long",
"com.sun.source.util.SourcePositions", "com.sun.source.tree.CompilationUnitTree", "com.sun.source.tree.Tree"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.netbeans.modules.java.source.save.CasualDiff", "filterHidden"))
.methodToWrap(new Hook("java.lang.Iterable", "iterator", "java.util.Iterator"))
.wrapMethod(new Hook("lombok.netbeans.agent.PatchFixes", "filterGenerated", "java.util.Iterator",
"java.util.Iterator"))
.transplant().build());
}
}
@@ -1,183 +0,0 @@
/*
* 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.netbeans.agent;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import javax.lang.model.element.Element;
import lombok.Lombok;
import lombok.patcher.inject.LiveInjector;
import org.netbeans.Module;
import org.netbeans.ProxyClassLoader;
import org.netbeans.api.java.source.ClasspathInfo;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TaskListener;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Context;
// A lot of the footwork on the netbeans support has been done by Jan Lahoda, who is awesome. (jlahoda@netbeans.org)
// This footwork was converted into a patch script form by me (rzwitserloot). See:
// http://code.google.com/p/projectlombok/issues/detail?id=20#c3
public class PatchFixes {
public static boolean loadClass_decision(ClassLoader loader, String name) throws Exception {
return name.startsWith("lombok.");
}
public static Class<?> loadClass_value(ClassLoader loader, String name) throws Exception {
int last = name.lastIndexOf('.');
String pkg = (last >= 0) ? name.substring(0, last) : "";
Method m = ProxyClassLoader.class.getDeclaredMethod("selfLoadClass", String.class, String.class);
m.setAccessible(true);
return (Class<?>)m.invoke(loader, pkg, name);
}
public static boolean getResource_decision(ClassLoader loader, String name) throws Exception {
return name.startsWith("META-INF/services/lombok.");
}
public static URL getResource_value(ClassLoader loader, String name) throws Exception {
Method m = ProxyClassLoader.class.getDeclaredMethod("findResource", String.class);
m.setAccessible(true);
return (URL) m.invoke(loader, name);
}
public static boolean getResources_decision(ClassLoader loader, String name) throws Exception {
return name.startsWith("META-INF/services/lombok.");
}
public static Enumeration<?> getResources_value(ClassLoader loader, String name) throws Exception {
Method m = ProxyClassLoader.class.getDeclaredMethod("findResources", String.class);
m.setAccessible(true);
return (Enumeration<?>) m.invoke(loader, name);
}
public static void addSelfToClassLoader(Module module, List<File> classPath) {
if (module.getJarFile().getName().equals("org-netbeans-libs-javacimpl.jar")) {
String lombokJarLoc = LiveInjector.findPathJar(Lombok.class);
classPath.add(new File(lombokJarLoc));
}
}
public static void fixContentOnSetTaskListener(JavacTaskImpl that, TaskListener taskListener) throws Throwable {
Context context = that.getContext();
if (context.get(TaskListener.class) != null)
context.put(TaskListener.class, (TaskListener)null);
if (taskListener != null) {
try {
Method m = JavacTaskImpl.class.getDeclaredMethod("wrap", TaskListener.class);
try {
m.setAccessible(true);
} catch (SecurityException ignore) {}
TaskListener w = (TaskListener)m.invoke(that, taskListener);
context.put(TaskListener.class, w);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
public static Tree returnNullForGeneratedNode(Trees trees, Element element, Object o) throws Throwable {
try {
Tree tree = trees.getTree(element);
if (tree == null) return null;
CompilationUnitTree unit = (CompilationUnitTree) o.getClass().getMethod("getCompilationUnit").invoke(o);
int startPos = (int) trees.getSourcePositions().getStartPosition(unit, tree);
if (startPos == -1) return null;
return tree;
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
public static long returnMinus1ForGeneratedNode(SourcePositions that, CompilationUnitTree cu, Tree tree) {
int start = (int) that.getStartPosition(cu, tree);
if (start < 0) return -1;
return that.getEndPosition(cu, tree);
}
public static void addTaskListenerWhenCallingJavac(JavacTaskImpl task,
ClasspathInfo cpInfo) throws Exception {
if (task == null) return;
Class<?> entryPoint = JavacTaskImpl.class.getClassLoader().loadClass("lombok.netbeans.agent.NetbeansEntryPoint");
if (entryPoint == null) {
/* TODO tell the user that lombok is not working. loadClass is not supposed to return null, but netbeans' loader does anyway. */
System.err.println("[LOMBOK] ClassLoader not patched correctly.");
} else {
task.setTaskListener((TaskListener) entryPoint.getConstructor(Context.class).newInstance(task.getContext()));
}
}
public static Iterator<JCTree> filterGenerated(final Iterator<JCTree> it) {
return new Iterator<JCTree>() {
private JCTree next;
private boolean hasNext;
{
calc();
}
private void calc() {
while (it.hasNext()) {
JCTree n = it.next();
if (n.pos != -1) {
hasNext = true;
next = n;
return;
}
}
hasNext = false;
next = null;
}
@Override public boolean hasNext() {
return hasNext;
}
@Override public JCTree next() {
if (!hasNext) throw new NoSuchElementException();
JCTree n = next;
calc();
return n;
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
@@ -1,26 +0,0 @@
/*
* 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.
*/
/**
* Contains the mechanism that instruments netbeans by being loaded as a javaagent.
*/
package lombok.netbeans.agent;