Skip to content

Commit

Permalink
Provide preference mapping for Java Execution Environments -> Runtimes
Browse files Browse the repository at this point in the history
Signed-off-by: Snjezana Peco <snjezana.peco@redhat.com>
  • Loading branch information
snjeza authored and fbricon committed Jan 10, 2020
1 parent 09b7f5f commit e19606f
Show file tree
Hide file tree
Showing 7 changed files with 461 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@
package org.eclipse.jdt.ls.core.internal;

import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
Expand All @@ -31,8 +36,11 @@
import org.eclipse.jdt.launching.IVMInstallChangedListener;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jdt.launching.PropertyChangeEvent;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.jdt.ls.core.internal.preferences.Preferences;

/**
Expand All @@ -48,41 +56,162 @@ public static boolean configureDefaultVM(Preferences preferences) throws CoreExc
return false;
}
String javaHome = preferences.getJavaHome();
boolean changed = false;
if (javaHome != null) {
File jvmHome = new File(javaHome);
if (jvmHome.isDirectory()) {
IVMInstall defaultVM = JavaRuntime.getDefaultVMInstall();
File location = defaultVM.getInstallLocation();
if (!location.equals(jvmHome)) {
IVMInstall vm = findVM(jvmHome);
IVMInstall vm = findVM(jvmHome, null);
if (vm == null) {
IVMInstallType installType = JavaRuntime.getVMInstallType(StandardVMType.ID_STANDARD_VM_TYPE);
long unique = System.currentTimeMillis();
while (installType.findVMInstall(String.valueOf(unique)) != null) {
unique++;
}
String vmId = String.valueOf(unique);
VMStandin vmStandin = new VMStandin(installType, vmId);
String name = StringUtils.defaultIfBlank(jvmHome.getName(), "JRE");
vmStandin.setName(name);
vmStandin.setInstallLocation(jvmHome);
vm = vmStandin.convertToRealVM();
JDTUtils.setCompatibleVMs(vm.getId());
changed = true;
}
boolean hasDefault = false;
for (RuntimeEnvironment runtime : preferences.getRuntimes()) {
if (runtime.isDefault()) {
hasDefault = true;
break;
}
}
if (!hasDefault) {
IVMInstall defaultVM = JavaRuntime.getDefaultVMInstall();
File location = defaultVM.getInstallLocation();
if (!location.equals(jvmHome)) {
JavaRuntime.setDefaultVMInstall(vm, new NullProgressMonitor());
JDTUtils.setCompatibleVMs(vm.getId());
changed = true;
}
}
}
}
boolean jvmChanged = configureJVMs(preferences);
return changed || jvmChanged;
}

public static boolean configureJVMs(Preferences preferences) throws CoreException {
boolean changed = false;
Set<RuntimeEnvironment> runtimes = preferences.getRuntimes();
for (RuntimeEnvironment runtime : runtimes) {
if (runtime.isValid()) {
File file = runtime.getInstallationFile();
if (file != null && file.isDirectory()) {
URL javadocURL = runtime.getJavadocURL();
IPath sourcePath = runtime.getSourcePath();
IVMInstall vm = findVM(file, runtime.getName());
IVMInstallType installType = JavaRuntime.getVMInstallType(StandardVMType.ID_STANDARD_VM_TYPE);
VMStandin vmStandin;
if (vm == null) {
IVMInstallType installType = JavaRuntime.getVMInstallType(StandardVMType.ID_STANDARD_VM_TYPE);
long unique = System.currentTimeMillis();
while (installType.findVMInstall(String.valueOf(unique)) != null) {
unique++;
}
String vmId = String.valueOf(unique);
VMStandin vmStandin = new VMStandin(installType, vmId);
String name = StringUtils.defaultIfBlank(jvmHome.getName(), "JRE");
vmStandin.setName(name);
vmStandin.setInstallLocation(jvmHome);
vm = vmStandin.convertToRealVM();
vmStandin = new VMStandin(installType, vmId);
changed = true;
} else {
vmStandin = new VMStandin(vm);
changed = changed || !runtime.getName().equals(vm.getName()) || !runtime.getInstallationFile().equals(vm.getInstallLocation());
}
JavaRuntime.setDefaultVMInstall(vm, new NullProgressMonitor());
JDTUtils.setCompatibleVMs(vm.getId());
IStatus status = installType.validateInstallLocation(file);
if (!status.isOK()) {
JavaLanguageServerPlugin.log(status);
continue;
}
vmStandin.setName(runtime.getName());
vmStandin.setInstallLocation(file);
if (sourcePath != null || javadocURL != null) {
LibraryLocation[] libs;
if (vm != null && vm.getLibraryLocations() != null) {
libs = vm.getLibraryLocations();
} else {
StandardVMType svt = (StandardVMType) installType;
libs = svt.getDefaultLibraryLocations(file);
}
boolean libChanged = false;
if (libs != null) {
for (int i = 0; i < libs.length; i++) {
LibraryLocation lib = libs[i];
IPath systemSourcePath = sourcePath != null ? sourcePath : lib.getSystemLibrarySourcePath();
URL javadocLocation = javadocURL != null ? javadocURL : lib.getJavadocLocation();
LibraryLocation newLib = new LibraryLocation(lib.getSystemLibraryPath(), systemSourcePath, lib.getPackageRootPath(), javadocLocation, lib.getIndexLocation(), lib.getExternalAnnotationsPath());
libChanged = libChanged || !newLib.equals(lib);
libs[i] = newLib;
}
}
if (libChanged) {
LibraryLocation[] newLibs = Arrays.copyOf(libs, libs.length);
vmStandin.setLibraryLocations(newLibs);
changed = true;
}
}
vm = vmStandin.convertToRealVM();
if (runtime.isDefault()) {
JavaRuntime.setDefaultVMInstall(vm, new NullProgressMonitor());
JavaLanguageServerPlugin.logInfo("Runtime " + runtime.getName() + " set as default");
}
if (!setDefaultEnvironmentVM(vm, runtime.getName())) {
JavaLanguageServerPlugin.logError("Runtime at '" + runtime.getPath() + "' is not compatible with the '" + runtime.getName() + "' environment");
}
} else {
JavaLanguageServerPlugin.logInfo("Invalid runtime: " + runtime);
}
}
}
if (changed) {
JavaLanguageServerPlugin.logInfo("JVM Runtimes changed, saving new configuration");
JavaRuntime.saveVMConfiguration();
}
return changed;
}

private static boolean setDefaultEnvironmentVM(IVMInstall vm, String name) {
IExecutionEnvironment environment = getExecutionEnvironment(name);
if (environment != null) {
IVMInstall[] compatibleVMs = environment.getCompatibleVMs();
for (IVMInstall compatibleVM : compatibleVMs) {
if (compatibleVM.equals(vm)) {
if (!environment.isStrictlyCompatible(vm)) {
JavaLanguageServerPlugin.logInfo("Runtime at '" + vm.getInstallLocation().toString() + "' is not strictly compatible with the '" + name + "' environment");
}
JavaLanguageServerPlugin.logInfo("Setting " + compatibleVM.getInstallLocation() + " as '" + name + "' environment (id:" + compatibleVM.getId() + ")");
environment.setDefaultVM(compatibleVM);
return true;
}
}
}
return false;
}

private static IVMInstall findVM(File jvmHome) {
public static IExecutionEnvironment getExecutionEnvironment(String name) {
IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
IExecutionEnvironment[] environments = manager.getExecutionEnvironments();
for (IExecutionEnvironment environment : environments) {
if (environment.getId().equals(name)) {
return environment;
}
}
return null;
}

public static IVMInstall findVM(File file, String name) {
IVMInstallType[] types = JavaRuntime.getVMInstallTypes();
for (IVMInstallType type : types) {
IVMInstall[] installs = type.getVMInstalls();
for (IVMInstall install : installs) {
if (jvmHome.equals(install.getInstallLocation())) {
if (name != null && name.equals(install.getName())) {
return install;
}
if (file != null && file.equals(install.getInstallLocation())) {
return install;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

import com.google.common.base.Strings;

/**
*
* @author snjeza
*
*/
public class RuntimeEnvironment {

private String name;
private String path;
private String javadoc;
private String sources;
private boolean isDefault;

/**
* @return the isDefault
*/
public boolean isDefault() {
return isDefault;
}

/**
* @param isDefault
* the isDefault to set
*/
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public String getJavadoc() {
return javadoc;
}

public void setJavadoc(String javadoc) {
this.javadoc = javadoc;
}

public String getSources() {
return sources;
}

public void setSources(String sources) {
this.sources = sources;
}

/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
RuntimeEnvironment other = (RuntimeEnvironment) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}

public boolean isValid() {
return !Strings.isNullOrEmpty(name) && !Strings.isNullOrEmpty(path);
}

public File getInstallationFile() {
if (isValid()) {
return new File(path);
}
return null;
}

public URL getJavadocURL() {
if (Strings.isNullOrEmpty(javadoc)) {
return null;
}
URL url;
try {
url = new URL(javadoc);
} catch (MalformedURLException e) {
File file = new File(javadoc);
if (file.exists()) {
try {
return JDTUtils.toURI(javadoc).toURL();
} catch (MalformedURLException e1) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
}
JavaLanguageServerPlugin.logInfo("Invalid javadoc: " + javadoc);
return null;
}
return url;
}

public IPath getSourcePath() {
if (!Strings.isNullOrEmpty(sources)) {
return new Path(sources);
}
return null;
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "JavaEnvironment [name=" + name + ", path=" + path + ", javadoc=" + javadoc + ", sources=" + sources + "]";
}

}
Loading

0 comments on commit e19606f

Please sign in to comment.