diff options
Diffstat (limited to 'src/lombok/installer/EclipseFinder.java')
-rw-r--r-- | src/lombok/installer/EclipseFinder.java | 103 |
1 files changed, 47 insertions, 56 deletions
diff --git a/src/lombok/installer/EclipseFinder.java b/src/lombok/installer/EclipseFinder.java index ba3c7e14..5356d6fc 100644 --- a/src/lombok/installer/EclipseFinder.java +++ b/src/lombok/installer/EclipseFinder.java @@ -23,17 +23,17 @@ package lombok.installer; import static java.util.Arrays.asList; -import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URI; import java.net.URLDecoder; import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,70 +62,59 @@ class EclipseFinder { } } + private static final AtomicBoolean windowsDriveInfoLibLoaded = new AtomicBoolean(false); + private static void loadWindowsDriveInfoLib() throws IOException, FileNotFoundException { + if ( !windowsDriveInfoLibLoaded.compareAndSet(false, true) ) return; + + InputStream in = EclipseFinder.class.getResourceAsStream("WindowsDriveInfo.dll"); + File dllFile; + try { + File temp = File.createTempFile("lombok", ".mark"); + dllFile = new File(temp.getParentFile(), "lombok-WindowsDriveInfo.dll"); + temp.delete(); + dllFile.deleteOnExit(); + try { + FileOutputStream out = new FileOutputStream(dllFile); + 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 ) { + if ( dllFile.exists() && dllFile.canRead() ) { + //Fall through - if there is a file named lombok-WindowsDriveInfo.dll, we'll try it. + } else throw e; + } + } finally { + in.close(); + } + + System.load(dllFile.getAbsolutePath()); + } + /** * Returns all drive letters on windows, regardless of what kind of drive is represented. * - * Relies on the 'fsutil.exe' program. I have no idea if you can call it without triggering a gazillion - * security warnings on Vista. I did a cursory test on an out-of-the-box Windows XP and that seems to work. - * * @return A List of drive letters, such as ["A", "C", "D", "X"]. */ - static List<String> getDrivesOnWindows() throws IOException { - ProcessBuilder builder = new ProcessBuilder("fsutil.exe", "fsinfo", "drives"); - builder.redirectErrorStream(true); - Process process = builder.start(); - InputStream in = process.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1")); + static List<String> getDrivesOnWindows() throws Throwable { + loadWindowsDriveInfoLib(); List<String> drives = new ArrayList<String>(); - String line; - while ( (line = br.readLine()) != null ) { - if (line.startsWith("Drives:")) { - line = line.substring(7); - } - line = line.trim(); - if (line.isEmpty()) { - continue; - } - for ( String driveLetter : line.split("\\:\\\\\\s*") ) { - drives.add(driveLetter.trim()); - } - } - - Iterator<String> it = drives.iterator(); - while ( it.hasNext() ) { - if ( !isLocalDriveOnWindows(it.next()) ) it.remove(); + WindowsDriveInfo info = new WindowsDriveInfo(); + for ( String drive : info.getLogicalDrives() ) { + if ( info.isFixedDisk(drive) ) drives.add(drive); } return drives; } - - /** - * @return true if the letter represents a local fixed disk, false if its a disk drive, optical drive, - * USB stick, network drive, or any other kind of drive. Substed (virtual) drives that are an alias to - * a directory on a local disk cause a 'return true', but this is intentional. - */ - static boolean isLocalDriveOnWindows(String driveLetter) { - if ( driveLetter == null || driveLetter.length() == 0 ) return false; - try { - ProcessBuilder builder = new ProcessBuilder("c:\\windows\\system32\\fsutil.exe", "fsinfo", "drivetype", driveLetter + ":"); - builder.redirectErrorStream(true); - Process process = builder.start(); - InputStream in = process.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1")); - - String line; - while ( (line = br.readLine()) != null ) { - if ( line.substring(5).equalsIgnoreCase("Fixed Drive") ) return true; - } - - return false; - } catch ( Exception e ) { - return false; - } - } - + /** * Returns a list of paths of Eclipse installations. * Eclipse installations are found by checking for the existence of 'eclipse.exe' in the following locations: @@ -143,7 +132,9 @@ class EclipseFinder { List<String> driveLetters = asList("C"); try { driveLetters = getDrivesOnWindows(); - } catch ( IOException ignore ) {} + } catch ( Throwable ignore ) { + ignore.printStackTrace(); + } for ( String letter : driveLetters ) { File f = new File(letter + ":\\"); |