package net.ftb.util.winreg;
import java.util.Comparator;
import javax.annotation.Nullable;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
/*
* Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License.
* Needs WinRegistry.java. Get it at: http://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
*
* JavaFinder - Windows-specific classes to search for all installed versions of java on this system
* Author: petrucio@stackoverflow (828681)
*****************************************************************************/
/**
* Helper struct to hold information about one installed java version
****************************************************************************/
public class JavaInfo extends JavaVersion
{
private static Cache<String, JavaInfo> CACHE;
static
{
CACHE = CacheBuilder.newBuilder().initialCapacity(10).build();
}
public String path; // ! Full path to java.exe executable file
public boolean is64bits; // ! true for 64-bit javas, false for 32
/**
* Creates new JavaInfo using string got from java -version
* @param version:
****************************************************************************/
private JavaInfo (String version) throws Exception
{
super(version, true);
}
/**
* Creates new JavaInfo or returns cached JavaInfo object
*
* @param javaPath: path to java binary
* @return
*/
@Nullable
public static JavaInfo getJavaInfo (String javaPath)
{
JavaInfo j = CACHE.getIfPresent(javaPath);
// TODO: notation to mark that there will not be value for given key?
if (j == null)
{
String output = RuntimeStreamer.execute(new String[]
{javaPath, "-version"});
try
{
j = new JavaInfo(output);
}
catch (Exception e)
{
return null;
}
j.path = javaPath;
j.is64bits = output.toUpperCase().contains("64-");
CACHE.put(javaPath, j);
}
return j;
}
public boolean samePath (JavaInfo j)
{
return this.path.equals(j.path);
}
public boolean sameBitness (JavaInfo j)
{
return this.is64bits == j.is64bits;
}
/**
* Tests if JavaInfo are identical: same version, same bitness but not always same path
*
* Used to manually remove duplicate JavaInfos from Collections
* @param j other JavaInfo objct to test
* @return
*/
public boolean isIdentical (JavaInfo j)
{
return (this.isSameVersion(j) && sameBitness(j));
}
/**
* @return Human-readable contents of this JavaInfo instance
****************************************************************************/
public String toString ()
{
return "Java Version: " + origVersion + " sorted as: " + this.verToString() + " " + (this.is64bits ? "64" : "32") + " Bit Java at : " + this.path;
}
public String verToString ()
{
return major + "." + minor + "." + revision + "_" + update;
}
// PREFERRED sorting compares first bitness then java version
public static final Comparator<JavaInfo> PREFERRED_SORTING = new Comparator<JavaInfo>()
{
public int compare (JavaInfo j1, JavaInfo j2)
{
if (!j1.is64bits && j2.is64bits)
{
return -1;
}
else if (j1.is64bits && !j2.is64bits)
{
return 1;
}
else
{
return j1.comparableVersion.compareTo(j2.comparableVersion);
}
}
};
}