/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package org.ant4eclipse.lib.jdt.internal.model.jre; import static org.ant4eclipse.lib.core.logging.A4ELogging.trace; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import org.ant4eclipse.lib.core.Assure; import org.ant4eclipse.lib.core.exception.Ant4EclipseException; import org.ant4eclipse.lib.core.logging.A4ELogging; import org.ant4eclipse.lib.jdt.JdtExceptionCode; import org.ant4eclipse.lib.jdt.model.ContainerTypes; import org.ant4eclipse.lib.jdt.model.jre.JavaProfile; import org.ant4eclipse.lib.jdt.model.jre.JavaRuntime; import org.ant4eclipse.lib.jdt.model.jre.JavaRuntimeRegistry; /** * <p> * Implementation of the {@link JavaRuntimeRegistry}. * </p> * * @author Daniel Kasmeroglu (daniel.kasmeroglu@kasisoft.net) * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class JavaRuntimeRegistryImpl implements JavaRuntimeRegistry { /** the default java runtime key * */ private String _defaultJavaRuntimeKey = null; /** the default java runtime (lazy initialized) */ private JavaRuntime _defaultJavaRuntime = null; /** the java runtime cache */ private Map<String, JavaRuntime> _javaRuntimeCache; /** * <p> * Creates a new instance of type {@link JavaRuntimeRegistryImpl}. * </p> */ public JavaRuntimeRegistryImpl() { // create hash maps this._javaRuntimeCache = new HashMap<String, JavaRuntime>(); } /** * {@inheritDoc} */ public JavaRuntime registerJavaRuntime(String id, File location) { return registerJavaRuntime(id, location, null, null, null); } /* * (non-Javadoc) * * @see org.ant4eclipse.lib.jdt.model.jre.JavaRuntimeRegistry#registerJavaRuntime(java.lang.String, java.io.File, * java.util.List) */ public JavaRuntime registerJavaRuntime(String id, File location, String extDirs, String endorsedDirs, List<File> jreFiles) { return registerJavaRuntime(id, location, extDirs, endorsedDirs, jreFiles, false); } private JavaRuntime registerJavaRuntime(String id, File location, String extDirs, String endorsedDirs, List<File> jreFiles, boolean isDefault) { Assure.nonEmpty("id", id); Assure.isDirectory("location", location); A4ELogging.info( "registerJavaRuntime: id = %s, location = %s, extDirs = %s, endorsedDirs = %s, jreFiles = %s, isDefault = %s", id, location, extDirs, endorsedDirs, jreFiles, isDefault); JavaRuntime javaRuntime = JavaRuntimeLoader.loadJavaRuntime(id, location, extDirs, endorsedDirs, jreFiles); return registerJavaRuntime(javaRuntime, isDefault); } /** * {@inheritDoc} */ public void setDefaultJavaRuntime(String id) { Assure.notNull("id", id); Assure.assertTrue(hasJavaRuntime(id), "No JavaRuntime with id '" + id + "' registered!"); this._defaultJavaRuntimeKey = id; } /** * {@inheritDoc} */ public boolean hasJavaRuntime(String path) { Assure.nonEmpty("path", path); // return true if a java runtime exists if (this._javaRuntimeCache.containsKey(path)) { return true; } // return if a java profile exists JavaProfile javaProfile = JavaProfileReader.getInstance().getJavaProfile(path); if (javaProfile != null && getJavaRuntime(javaProfile) != null) { return true; } return false; } /** * {@inheritDoc} */ public boolean hasJavaProfile(String path) { Assure.nonEmpty("path", path); return JavaProfileReader.getInstance().hasJavaProfile(path); } public String getAllJavaProfileNames() { return JavaProfileReader.getInstance().getAllProfileNames(); } /** * {@inheritDoc} */ public JavaRuntime getJavaRuntime(String path) { Assure.nonEmpty("path", path); // return true if a java runtime exists if (this._javaRuntimeCache.containsKey(path)) { return this._javaRuntimeCache.get(path); } // return if a java profile exists JavaProfile javaProfile = JavaProfileReader.getInstance().getJavaProfile(path); if (javaProfile != null) { if (((JavaProfileImpl) javaProfile).getAssociatedJavaRuntimeId() != null) { return getJavaRuntime(((JavaProfileImpl) javaProfile).getAssociatedJavaRuntimeId()); } else { return getJavaRuntime(javaProfile); } } return null; } /* * (non-Javadoc) * * @see org.ant4eclipse.lib.jdt.model.jre.JavaRuntimeRegistry#getJavaRuntimeForPath(java.lang.String) */ public JavaRuntime getJavaRuntimeForPath(String path) { Assure.notNull("path", path); trace("Determining JRE for path '%s'", path); if (ContainerTypes.JRE_CONTAINER.equals(path)) { return getDefaultJavaRuntime(); } JavaRuntime javaRuntime = null; if (path.startsWith(ContainerTypes.VMTYPE_PREFIX)) { javaRuntime = getJavaRuntime(path.substring(ContainerTypes.VMTYPE_PREFIX.length())); } if (javaRuntime != null) { return javaRuntime; } A4ELogging.warn("No java runtime '%s' defined - using default runtime.", path); return getDefaultJavaRuntime(); } /** * {@inheritDoc} */ public JavaProfile getJavaProfile(String path) { Assure.nonEmpty("path", path); return JavaProfileReader.getInstance().getJavaProfile(path); } /** * {@inheritDoc} */ public JavaRuntime getDefaultJavaRuntime() { if (this._defaultJavaRuntime != null) { return this._defaultJavaRuntime; } if (this._defaultJavaRuntimeKey != null) { if (this._javaRuntimeCache.containsKey(this._defaultJavaRuntimeKey)) { this._defaultJavaRuntime = this._javaRuntimeCache.get(this._defaultJavaRuntimeKey); return this._defaultJavaRuntime; } // default jre was specified but does not exists. This shouldn't happen as // we make sure that there is a JRE with the default id in the moment // the default jre is set (setDefaultJavaRuntime). // For backward compatibility we only print a warning here. A4ELogging.error( "No default JRE configured with id '%s'. (missing or wrong <installedJREs> in your build file?). Trying to use JRE from java.home. ", this._defaultJavaRuntimeKey); } // TODO: A4ELogging.warn( "No default JRE has been set (using the 'default' attribute on <installedJREs> data type). Trying to use JRE from java.home"); // try to create java runtime from java.home this._defaultJavaRuntime = getJavaRuntimeFromJavaHome(); return this._defaultJavaRuntime; } /** * <p> * </p> * * @param javaProfile * @return */ private JavaRuntime getJavaRuntime(JavaProfile javaProfile) { // result JavaRuntime result = null; String profileName = javaProfile.getName(); // iterate over java runtime cache for (Object element : this._javaRuntimeCache.values()) { // get the java runtime JavaRuntime javaRuntime = (JavaRuntime) element; if (javaRuntime.getJavaProfile().getExecutionEnvironmentNames().contains(profileName)) { if (result == null) { result = javaRuntime; } else { if (getIndex(javaRuntime, profileName) < getIndex(result, profileName)) { result = javaRuntime; } } } } return result; } /** * <p> * </p> * * @param javaRuntime * @param profileName * @return */ private int getIndex(JavaRuntime javaRuntime, String profileName) { int index = javaRuntime.getJavaProfile().getExecutionEnvironmentNames().indexOf(profileName); index = javaRuntime.getJavaProfile().getExecutionEnvironmentNames().size() - index; return index; } /** * <p> * Registers the specified {@link JavaRuntime}. * </p> * * @param javaRuntime * the java runtime to specify. * @param isDefault * indicates if the java runtime is the default runtime or not. * * @return the path under this java runtime is stored, e.g. * <code>org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk15</code> */ private JavaRuntime registerJavaRuntime(JavaRuntime javaRuntime, boolean isDefault) { Assure.notNull("javaRuntime", javaRuntime); // create path String id = javaRuntime.getId(); if (this._javaRuntimeCache.containsKey(id)) { JavaRuntime runtime = this._javaRuntimeCache.get(id); if (!runtime.equals(javaRuntime)) { // throw an exception // TODO throw new RuntimeException("Duplicate definition of JavaRuntime with key '" + id + "'."); } // return previous instance return this._javaRuntimeCache.get(id); } // store java runtime this._javaRuntimeCache.put(id, javaRuntime); // store default if necessary if (isDefault || (this._defaultJavaRuntimeKey == null)) { setDefaultJavaRuntime(id); } // return java runtime return javaRuntime; } /** * <p> * Tries to create a java runtime for the JRE defined under system property 'java.home'. If the system property is not * properly set, <code>null</code> will be returned instead. * </p> * * @return the {@link JavaRuntime} or <code>null</code> if no such {@link JavaRuntime} exists. */ private JavaRuntime getJavaRuntimeFromJavaHome() { // read system property 'java.home' String javaHome = System.getProperty("java.home"); // if system property 'java.home' is not set, return null if (javaHome == null) { throw new Ant4EclipseException(JdtExceptionCode.NO_DEFAULT_JAVA_RUNTIME_EXCEPTION, "Tried to read JRE from 'java.home' but system property 'java.home' is not set."); } // create file File location = new File(javaHome); // if location is not a directory, return null if (!location.isDirectory()) { throw new Ant4EclipseException(JdtExceptionCode.NO_DEFAULT_JAVA_RUNTIME_EXCEPTION, String.format("Location of 'java.home' (%s) is not a directory", javaHome)); } // create new java runtime A4ELogging.info("Using default JRE defined in system property 'java.home' (%s)", location.getAbsolutePath()); return JavaRuntimeLoader.loadJavaRuntime("java.home", location, null, null, null); } }