/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.gradle.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.util.FileUtils;
/**
* Models path information for a particular JDK install.
* <p/>
* Copied largely from {@link org.gradle.util.Jvm} and {@link org.apache.tools.ant.util.JavaEnvUtils}. The main
* difference is that those classes are static, based solely on the reported "java.home" sys prop. Also, Ant's
* JavaEnvUtils allows for use of either a JRE or JDK; we do not care about allowing for a JRE-only set up here.
*
*
* @author Steve Ebersole
*/
public class Jdk {
private static final boolean IS_DOS = Os.isFamily( "dos" );
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
private final File jdkHome;
private final JavaVersion version;
public Jdk(){
this(System.getenv( "JAVA_HOME" ));
}
public Jdk(File jdkHome) {
this.jdkHome = jdkHome;
if ( !jdkHome.exists() ) {
throw new IllegalArgumentException( "Invalid path specified for JDK home; " + jdkHome.getAbsolutePath() + " did not exist" );
}
this.version = determineJdkVersion();
}
public Jdk(String jdkHomePath) {
this( new File( jdkHomePath ) );
}
public File getJavaExecutable() {
return new File( getJdkExecutable( "java" ) );
}
public File getJavacExecutable() {
return new File( getJdkExecutable( "javac" ) );
}
public File getJavadocExecutable() {
return new File( getJdkExecutable( "javadoc" ) );
}
public JavaVersion getVersion() {
return version;
}
protected String getJdkExecutable(String command) {
File executable = findInDir( jdkHome + "/bin", command );
if ( executable == null ) {
executable = findInDir( jdkHome + "/../bin", command );
}
if ( executable != null ) {
return executable.getAbsolutePath();
}
else {
// Unfortunately on Windows java.home doesn't always refer
// to the correct location, so we need to fall back to
// assuming java is somewhere on the PATH.
return addExtension( command );
}
}
private static File findInDir(String dirName, String commandName) {
File dir = FILE_UTILS.normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static String addExtension(String command) {
// This is the most common extension case - exe for windows and OS/2,
// nothing for *nix.
return command + (IS_DOS ? ".exe" : "");
}
private JavaVersion determineJdkVersion() {
String javaVersionString = extractFromSunJdk();
if ( javaVersionString == null ) {
throw new RuntimeException( "Could not determine Java version" );
}
return new JavaVersion( javaVersionString );
}
private String extractFromSunJdk() {
String version = null;
final String key = "java version \"";
try {
final File javaCommand = getJavaExecutable();
Process javaProcess = Runtime.getRuntime().exec( javaCommand.getAbsolutePath() + " -version" );
try {
BufferedReader br = new BufferedReader( new InputStreamReader( javaProcess.getErrorStream() ) );
String line;
while ( (line = br.readLine()) != null) {
if ( version == null && line.startsWith( key ) ) {
version = line.substring( key.length(), line.length() - 1 );
}
}
br.close();
br = new BufferedReader( new InputStreamReader( javaProcess.getInputStream() ) );
while ( (line = br.readLine()) != null) {
if ( version == null && line.startsWith( key ) ) {
version = line.substring( key.length(), line.length() - 1 );
}
}
br.close();
}
finally {
javaProcess.destroy();
}
}
catch ( IOException e ) {
throw new RuntimeException( "Unable to determine Java version", e );
}
return version;
}
}