// Copyright © 2011-2015, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package fi.jumi.actors.generator;

import com.google.common.io.CharStreams;

import java.io.*;
import java.net.*;
import java.util.zip.*;

public class LibrarySourceLocator {

    public String findSources(String className) {
        String result = null;
        String sourceFilePath = className.replace('.', '/') + ".java";
        try {
            // classpath
            InputStream in = getClass().getClassLoader().getResourceAsStream(sourceFilePath);
            if (in != null) {
                return toString(in);
            }

            // JDK
            File javaHome = new File(System.getProperty("java.home"));
            File jdkSourcesFile = new File(javaHome.getParentFile(), "src.zip");
            if (jdkSourcesFile.isFile()) {
                result = findZipFileEntry(jdkSourcesFile, sourceFilePath);
            }

            // local Maven repository
            if (result == null) {
                File classesJar = findJarContaining(className);
                if (classesJar != null) {
                    File sourcesJar = new File(classesJar.getPath().replaceAll("\\.jar$", "-sources.jar"));
                    if (sourcesJar.isFile()) {
                        result = findZipFileEntry(sourcesJar, sourceFilePath);
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("Error finding sources for " + className);
            e.printStackTrace();
        }
        return result;
    }

    private File findJarContaining(String className) throws MalformedURLException {
        URL resource = getClass().getClassLoader().getResource(className.replace('.', '/') + ".class");
        if (resource != null && resource.getProtocol().equals("jar")) {
            String path = new URL(resource.getPath()).getPath();
            File file = new File(path.substring(0, path.indexOf("!")));
            if (file.isFile()) {
                return file;
            }
        }
        return null;
    }

    private String findZipFileEntry(File zipFile, String entryName) throws IOException {
        ZipFile zip = null;
        try {
            zip = new ZipFile(zipFile);
            ZipEntry entry = zip.getEntry(entryName);
            if (entry == null) {
                return null;
            }
            return toString(zip.getInputStream(entry));
        } finally {
            if (zip != null) {
                zip.close();
            }
        }
    }

    private static String toString(InputStream in) throws IOException {
        try {
            return CharStreams.toString(new InputStreamReader(in, "UTF-8"));
        } finally {
            in.close();
        }
    }
}

@@ -358,16 +358,101 @@
 ator %7B%0A%0A
+    private static final File javaHome = new File(System.getProperty(%22java.home%22));%0A%0A
     publ
@@ -767,36 +767,38 @@
               re
-turn
+sult =
  toString(in);%0A 
@@ -846,67 +846,341 @@
     
-File javaHome = new File(System.getProperty(%22java.home%22));%0A
+if (result == null) %7B%0A                File jdkSourcesFile = new File(javaHome.getParentFile(), %22src.zip%22);%0A                if (jdkSourcesFile.isFile()) %7B%0A                    result = findZipFileEntry(jdkSourcesFile, sourceFilePath);%0A                %7D%0A            %7D%0A%0A            // JDK 6 on OS X%0A            if (result == null) %7B%0A    
     
@@ -1230,34 +1230,18 @@
 Home
-.getParentFile()
 , %22src.
-zip
+jar
 %22);%0A
@@ -1244,32 +1244,36 @@
 %22);%0A            
+    
 if (jdkSourcesFi
@@ -1279,32 +1279,36 @@
 ile.isFile()) %7B%0A
+    
                 
@@ -1340,32 +1340,41 @@
 (jdkSourcesFile,
+ %22src/%22 +
  sourceFilePath)
@@ -1367,32 +1367,50 @@
 ourceFilePath);%0A
+                %7D%0A
             %7D%0A%0A 
@@ -1949,16 +1949,24 @@
 rror
+:
  f
-inding
+ailed to read
  sou
@@ -1970,19 +1970,18 @@
 sources 
+o
 f
-or
  %22 + cla

Fix for finding JDK 6 sources on OS X