package org.eclipse.jdt.internal.launching;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CompilationParticipant;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.osgi.util.NLS;
public class EECompilationParticipant extends CompilationParticipant {
private Set<IJavaProject> fCleaned = new HashSet<>();
@Override
public boolean isActive(IJavaProject project) {
return true;
}
@Override
public void cleanStarting(IJavaProject project) {
super.cleanStarting(project);
fCleaned.add(project);
}
@Override
public void buildFinished(IJavaProject project) {
super.buildFinished(project);
if (fCleaned.remove(project)) {
String eeId = null;
IPath container = null;
try {
IClasspathEntry[] rawClasspath = project.getRawClasspath();
for (int j = 0; j < rawClasspath.length; j++) {
IClasspathEntry entry = rawClasspath[j];
if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
IPath path = entry.getPath();
if (JavaRuntime.JRE_CONTAINER.equals(path.segment(0))) {
container = path;
eeId = JREContainerInitializer.getExecutionEnvironmentId(path);
}
}
}
} catch (CoreException e) {
LaunchingPlugin.log(e);
}
if (container != null && eeId != null) {
IVMInstall vm = JREContainerInitializer.resolveVM(container);
validateEnvironment(eeId, project, vm);
if (vm instanceof IVMInstall2) {
eeId = getCompilerCompliance((IVMInstall2) vm);
if (eeId != null) {
validateCompliance(eeId, project, vm);
}
}
} else if (container != null) {
IVMInstall vm = JREContainerInitializer.resolveVM(container);
if (vm instanceof IVMInstall2) {
eeId = getCompilerCompliance((IVMInstall2) vm);
if (eeId != null) {
validateCompliance(eeId, project, vm);
}
}
}
}
}
private boolean isReleaseFlagEnabled(String eeId, String compId, final IJavaProject project) {
boolean releaseFlagEnabled = false;
if (JavaCore.compareJavaVersions(JavaCore.VERSION_9, eeId) <= 0) {
if (JavaCore.compareJavaVersions(JavaCore.VERSION_1_6, compId) <= 0) {
String releaseVal = project.getOption(JavaCore.COMPILER_RELEASE, true);
if (JavaCore.ENABLED.equals(releaseVal)) {
releaseFlagEnabled = true;
}
}
}
return releaseFlagEnabled;
}
private void validateCompliance(String eeId, final IJavaProject project, IVMInstall vm) {
String id = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
if (!eeId.equals(id)) {
if (!isReleaseFlagEnabled(eeId, id, project)) {
IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
IExecutionEnvironment[] environments = manager.getExecutionEnvironments();
IExecutionEnvironment finalEnvironment = null;
for (IExecutionEnvironment environment : environments) {
if (environment.getId().indexOf(id) != -1) {
finalEnvironment = environment;
break;
}
}
if (finalEnvironment != null) {
if (!finalEnvironment.isStrictlyCompatible(vm)) {
String message = NLS.bind(LaunchingMessages.LaunchingPlugin_39, new String[] { id, eeId });
int sev = getSeverityLevel(JavaRuntime.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE, project.getProject());
if (sev != -1) {
createProblemMarker(project, message, sev, JavaRuntime.JRE_COMPILER_COMPLIANCE_MARKER, LaunchingMessages.LaunchingPlugin_40);
}
}
}
}
}
}
private void validateEnvironment(String id, final IJavaProject project, IVMInstall vm) {
IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
final IExecutionEnvironment environment = manager.getEnvironment(id);
if (environment != null) {
if (vm == null) {
String message = NLS.bind(
LaunchingMessages.LaunchingPlugin_38,
new String[]{environment.getId()});
createJREContainerProblem(project, message, IMarker.SEVERITY_ERROR);
} else if (!environment.isStrictlyCompatible(vm)) {
IVMInstall[] compatibleVMs = environment.getCompatibleVMs();
int exact = 0;
for (int i = 0; i < compatibleVMs.length; i++) {
if (environment.isStrictlyCompatible(compatibleVMs[i])) {
exact++;
}
}
String message = null;
if (exact == 0) {
if (vm instanceof IVMInstall2) {
String eeId = getCompilerCompliance((IVMInstall2) vm);
String compId = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
if (eeId != null && isReleaseFlagEnabled(eeId, compId, project)) {
return;
}
}
message = NLS.bind(
LaunchingMessages.LaunchingPlugin_35,
new String[]{environment.getId()});
} else {
message = NLS.bind(
LaunchingMessages.LaunchingPlugin_36,
new String[]{environment.getId()});
}
int sev = getSeverityLevel(JavaRuntime.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE, project.getProject());
if (sev != -1) {
createJREContainerProblem(project, message, sev);
}
}
}
}
public static String getCompilerCompliance(IVMInstall2 vMInstall) {
String version = vMInstall.getJavaVersion();
if (version == null) {
return null;
} else if (version.startsWith(JavaCore.VERSION_13)) {
return JavaCore.VERSION_13;
} else if (version.startsWith(JavaCore.VERSION_12)) {
return JavaCore.VERSION_12;
} else if (version.startsWith(JavaCore.VERSION_11)) {
return JavaCore.VERSION_11;
} else if (version.startsWith(JavaCore.VERSION_10)) {
return JavaCore.VERSION_10;
} else if (version.startsWith(JavaCore.VERSION_9)) {
return JavaCore.VERSION_9;
} else if (version.startsWith(JavaCore.VERSION_1_8)) {
return JavaCore.VERSION_1_8;
} else if (version.startsWith(JavaCore.VERSION_1_7)) {
return JavaCore.VERSION_1_7;
} else if (version.startsWith(JavaCore.VERSION_1_6)) {
return JavaCore.VERSION_1_6;
} else if (version.startsWith(JavaCore.VERSION_1_5)) {
return JavaCore.VERSION_1_5;
} else if (version.startsWith(JavaCore.VERSION_1_4)) {
return JavaCore.VERSION_1_4;
} else if (version.startsWith(JavaCore.VERSION_1_3)) {
return JavaCore.VERSION_1_3;
} else if (version.startsWith(JavaCore.VERSION_1_2)) {
return JavaCore.VERSION_1_3;
} else if (version.startsWith(JavaCore.VERSION_1_1)) {
return JavaCore.VERSION_1_3;
}
return null;
}
private int getSeverityLevel(String prefkey, IProject project) {
IPreferencesService service = Platform.getPreferencesService();
List<IScopeContext> scopes = new ArrayList<>();
scopes.add(InstanceScope.INSTANCE);
if(project != null) {
scopes.add(new ProjectScope(project));
}
String value = service.getString(LaunchingPlugin.ID_PLUGIN, prefkey, null, scopes.toArray(new IScopeContext[scopes.size()]));
if(value == null) {
value = InstanceScope.INSTANCE.getNode(LaunchingPlugin.ID_PLUGIN).get(prefkey, null);
}
if (JavaCore.ERROR.equals(value)) {
return IMarker.SEVERITY_ERROR;
}
if (JavaCore.WARNING.equals(value)) {
return IMarker.SEVERITY_WARNING;
}
if (JavaCore.INFO.equals(value)) {
return IMarker.SEVERITY_INFO;
}
return -1;
}
private void createJREContainerProblem(IJavaProject javaProject, String message, int severity) {
try {
IMarker marker = javaProject.getProject().createMarker(JavaRuntime.JRE_CONTAINER_MARKER);
marker.setAttributes(
new String[] {
IMarker.MESSAGE,
IMarker.SEVERITY,
IMarker.LOCATION},
new Object[] {
message,
new Integer(severity),
LaunchingMessages.LaunchingPlugin_37
});
} catch (CoreException e) {
return;
}
}
private void createProblemMarker(IJavaProject javaProject, String message, int severity, String problemId, String location) {
try {
IMarker marker = javaProject.getProject().createMarker(problemId);
marker.setAttributes(
new String[] {
IMarker.MESSAGE,
IMarker.SEVERITY,
IMarker.LOCATION },
new Object[] {
message,
new Integer(severity),
location
});
} catch (CoreException e) {
return;
}
}
}