![JAR search and dependency download from the Maven repository](/logo.png)
io.sarl.lang.maven.compiler.abstractmojos.AbstractCompileMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sarl-maven-plugin Show documentation
Show all versions of sarl-maven-plugin Show documentation
Maven plugin for compiling SARL code
The newest version!
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014-2024 SARL.io, the Original Authors and Main Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.sarl.lang.maven.compiler.abstractmojos;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.JarFile;
import com.google.common.base.Strings;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.arakhne.afc.vmutil.FileSystem;
import io.sarl.lang.compiler.batch.OptimizationLevel;
import io.sarl.lang.core.SARLVersion;
import io.sarl.lang.core.SREBootstrap;
import io.sarl.lang.maven.compiler.compiler.JavaCompiler;
import io.sarl.lang.maven.compiler.utils.Utils;
/** Abstract Mojo for compiling SARL (standard en test).
*
* @author Stéphane Galland
* @version sarl-maven-plugin 0.14.0 20241106-161406
* @mavengroupid io.sarl.lang
* @mavenartifactid sarl-maven-plugin
* @since 0.8
*/
public abstract class AbstractCompileMojo extends AbstractSarlBatchCompilerMojo {
private static final String STUB_FOLDER = "sarl-temp"; //$NON-NLS-1$
private static final String METAINF_FOLDER_NAME = "META-INF"; //$NON-NLS-1$
private static final String METAINF_SERVICE_FOLDER_NAME = "services"; //$NON-NLS-1$
private static final String JAR_SEPARATOR = "/"; //$NON-NLS-1$
/** Version of the Java specification used for the source files.
*/
@Parameter(defaultValue = SARLVersion.MINIMAL_JDK_VERSION_IN_SARL_PROJECT_CLASSPATH, required = false)
private String source;
/** Encoding.
*/
@Parameter(required = false)
private String encoding;
/**
* Location of the temporary compiler directory.
*/
@Parameter
private File tempDirectory;
/** Indicates the Java compiler to be invoked by the SARL maven plugin.
*/
@Parameter(required = false)
private String javaCompiler;
private JavaCompiler javaCompilerInstance;
/** Indicates if the inline annotations must be generated by the SARL maven plugin.
*/
@Parameter(defaultValue = "false", required = false)
private boolean generateInlines;
/** Indicates if the pure annotations must be generated by the SARL maven plugin.
*/
@Parameter(defaultValue = "true", required = false)
private boolean generatePures;
/** Indicates if the trace files should be generated.
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateTraceFiles;
/** Indicates if the storage files should be generated.
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateStorageFiles;
/** Indicates if the equality test functions must be generated by the SARL maven plugin.
* @since 0.8
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateEqualityTestFunctions;
/** Indicates if the toString functions must be generated by the SARL maven plugin.
* @since 0.8
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateToStringFunctions;
/** Indicates if the clone functions must be generated by the SARL maven plugin.
* @since 0.8
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateCloneFunctions;
/** Indicates if the serial number fields must be generated by the SARL maven plugin.
* @since 0.8
*/
@Parameter(defaultValue = "true", required = false)
private boolean generateSerialNumberFields;
/** Indicates if the classpath is provided by Tycho.
*/
@Parameter(defaultValue = "false", required = false)
private boolean tycho;
/** Indicates if the extra-language generators to be enabled.
*
* @since 0.8
*/
@Parameter(required = false)
private String[] extraGenerators;
/** Indicates the level of optimization.
*
* @since 0.8
*/
@Parameter(required = false)
private String optimization;
private OptimizationLevel optimizationInstance;
/** Indicates if the JRE must be first on the classpath.
* @since 0.12
*/
@Parameter(defaultValue = "false")
private boolean fixClasspathJdtJse;
/** Indicates if the the plugin verify if SRE is in the Maven dependencies.
* @since 0.13
*/
@Parameter(defaultValue = "true")
private boolean verifySREInDependencies;
/** If the SRE on the classpath is verified, this parameter indicates if SRE missing generates an error or not.
* @since 0.13
*/
@Parameter(defaultValue = "false")
private boolean failWhenMissedSRE;
@Override
protected boolean isTychoEnvironment() {
return this.tycho;
}
@Override
protected boolean isFixingJavaClasspathForJre() {
return this.fixClasspathJdtJse;
}
@Override
protected List buildClassPath() throws MojoExecutionException {
if (isFixingJavaClasspathForJre()) {
return fixJreClassPathFiles(super.buildClassPath(), Messages.AbstractCompileMojo_3);
}
return super.buildClassPath();
}
@Override
protected List buildTestClassPath() throws MojoExecutionException {
if (isFixingJavaClasspathForJre()) {
return fixJreClassPathFiles(super.buildTestClassPath(), Messages.AbstractCompileMojo_4);
}
return super.buildTestClassPath();
}
@Override
protected String[] getExtraGenerators() {
if (this.extraGenerators == null) {
this.extraGenerators = new String[0];
}
return this.extraGenerators;
}
@Override
protected String getSourceVersion() {
return this.source;
}
@Override
protected String getEncoding() {
return this.encoding == null || this.encoding.isEmpty() ? Charset.defaultCharset().displayName() : this.encoding;
}
@Override
protected File getTempDirectory() {
if (this.tempDirectory == null) {
final var targetDir = new File(getProject().getBuild().getDirectory());
return makeAbsolute(new File(targetDir, STUB_FOLDER));
}
return makeAbsolute(this.tempDirectory);
}
@Override
protected JavaCompiler getJavaCompiler() {
if (this.javaCompilerInstance == null) {
if (!Strings.isNullOrEmpty(this.javaCompiler)) {
this.javaCompilerInstance = JavaCompiler.valueOfCaseInsensitive(this.javaCompiler);
if (this.javaCompilerInstance == null) {
String values = null;
for (final var comp : JavaCompiler.values()) {
if (values == null) {
values = comp.getNameInMavenConfiguration();
} else {
values = MessageFormat.format(Messages.AbstractCompileMojo_1, values,
comp.getNameInMavenConfiguration());
}
}
getLogger().warn(MessageFormat.format(Messages.AbstractCompileMojo_0, this.javaCompiler,
values, JavaCompiler.getDefault().getNameInMavenConfiguration()));
}
}
if (this.javaCompilerInstance == null) {
this.javaCompilerInstance = JavaCompiler.getDefault();
}
}
return this.javaCompilerInstance;
}
@Override
protected OptimizationLevel getOptimization() {
if (this.optimizationInstance == null) {
if (!Strings.isNullOrEmpty(this.optimization)) {
this.optimizationInstance = OptimizationLevel.valueOfCaseInsensitive(this.optimization);
if (this.optimizationInstance == null) {
String values = null;
for (final var lvl : OptimizationLevel.values()) {
if (values == null) {
values = lvl.getCaseInsensitiveName();
} else {
values = MessageFormat.format(Messages.AbstractCompileMojo_1, values,
lvl.getCaseInsensitiveName());
}
}
getLogger().warn(MessageFormat.format(Messages.AbstractCompileMojo_2, this.optimization,
values, OptimizationLevel.getDefault().getCaseInsensitiveName()));
}
}
if (this.optimizationInstance == null) {
this.optimizationInstance = OptimizationLevel.getDefault();
}
}
return this.optimizationInstance;
}
@Override
protected boolean getGenerateInlines() {
return this.generateInlines;
}
@Override
protected boolean getGenerateEqualityTestFunctions() {
return this.generateEqualityTestFunctions;
}
@Override
protected boolean getGenerateToStringFunctions() {
return this.generateToStringFunctions;
}
@Override
protected boolean getGenerateCloneFunctions() {
return this.generateCloneFunctions;
}
@Override
protected boolean getGenerateSerialNumberFields() {
return this.generateSerialNumberFields;
}
@Override
protected boolean getGeneratePures() {
return this.generatePures;
}
@Override
protected boolean getGenerateTraceFiles() {
return this.generateTraceFiles;
}
@Override
protected boolean getGenerateStorageFiles() {
return this.generateStorageFiles;
}
@Override
protected void buildPropertyString(StringBuilder buffer) {
super.buildPropertyString(buffer);
buffer.append("source = ").append(this.source).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("encoding = ").append(this.encoding).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("tempDirectory = ").append(this.tempDirectory).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("javaCompiler = ").append(this.javaCompiler).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateInlines = ").append(this.generateInlines).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateTraceFiles = ").append(this.generateTraceFiles).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateStorageFiles = ").append(this.generateStorageFiles).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateEqualityTestFunctions = ").append(this.generateEqualityTestFunctions).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateToStringFunctions = ").append(this.generateToStringFunctions).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateCloneFunctions = ").append(this.generateCloneFunctions).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
buffer.append("generateSerialNumberFields = ").append(this.generateSerialNumberFields).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
}
@Override
protected void ensureDefaultParameterValues() {
super.ensureDefaultParameterValues();
if (Strings.isNullOrEmpty(this.encoding)) {
final var properties = this.mavenHelper.getSession().getCurrentProject().getProperties();
this.encoding = properties.getProperty("project.build.sourceEncoding", null); //$NON-NLS-1$
if (Strings.isNullOrEmpty(this.encoding)) {
this.encoding = Charset.defaultCharset().name();
}
}
}
@Override
protected void executeMojo() throws MojoExecutionException, MojoFailureException {
ensureSARLVersions();
validateDependencyVersions();
compileSARL();
}
private static boolean containsVersion(ArtifactVersion version, ArtifactVersion rangeMin, ArtifactVersion rangeMax) {
return (version.compareTo(rangeMin) >= 0) && (version.compareTo(rangeMax) < 0);
}
private void ensureSARLVersions() throws MojoExecutionException, MojoFailureException {
final var compilerVersionString = this.mavenHelper.getConfig("plugin.version"); //$NON-NLS-1$
final var compilerVersion = new DefaultArtifactVersion(compilerVersionString);
final var maxCompilerVersion = new DefaultArtifactVersion(
compilerVersion.getMajorVersion() + "." //$NON-NLS-1$
+ (compilerVersion.getMinorVersion() + 1)
+ ".0"); //$NON-NLS-1$
getLogger().info(MessageFormat.format(Messages.AbstractCompileMojo_5, compilerVersionString, maxCompilerVersion));
final var classpath = new StringBuilder();
final var foundVersions = findSARLLibrary(compilerVersion, maxCompilerVersion, classpath,
isTychoEnvironment());
if (foundVersions.isEmpty()) {
throw new MojoFailureException(MessageFormat.format(Messages.AbstractCompileMojo_6, classpath.toString()));
}
final var versions = new StringBuilder();
for (final var version : foundVersions) {
if (versions.length() > 0) {
versions.append(", "); //$NON-NLS-1$
}
versions.append(version);
}
if (foundVersions.size() > 1) {
getLogger().info(MessageFormat.format(Messages.AbstractCompileMojo_7, versions));
} else {
getLogger().info(MessageFormat.format(Messages.AbstractCompileMojo_8, versions));
}
}
private Set findSARLLibrary(ArtifactVersion compilerVersion, ArtifactVersion maxCompilerVersion,
StringBuilder classpath, boolean enableTycho) throws MojoExecutionException, MojoFailureException {
final var sarlLibGroupId = this.mavenHelper.getConfig("sarl-lib.groupId"); //$NON-NLS-1$
final var sarlLibArtifactId = this.mavenHelper.getConfig("sarl-lib.artifactId"); //$NON-NLS-1$
final var sarlLibGroupIdTycho = "p2.eclipse-plugin"; //$NON-NLS-1$
final var sarlLibArtifactIdTycho = this.mavenHelper.getConfig("sarl-lib.osgiBundleId"); //$NON-NLS-1$
final var foundVersions = new TreeSet();
for (final var dep : this.mavenHelper.getSession().getCurrentProject().getArtifacts()) {
getLogger().debug(MessageFormat.format(Messages.AbstractCompileMojo_9, dep.getGroupId(), dep.getArtifactId(), dep.getVersion()));
if (classpath.length() > 0) {
classpath.append(":"); //$NON-NLS-1$
}
classpath.append("{"); //$NON-NLS-1$
classpath.append(ArtifactUtils.versionlessKey(dep));
classpath.append("}"); //$NON-NLS-1$
String gid = null;
String aid = null;
if (sarlLibGroupId.equals(dep.getGroupId())
&& sarlLibArtifactId.equals(dep.getArtifactId())) {
gid = sarlLibGroupId;
aid = sarlLibArtifactId;
} else if (enableTycho
&& sarlLibGroupIdTycho.equals(dep.getGroupId())
&& sarlLibArtifactIdTycho.equals(dep.getArtifactId())) {
gid = sarlLibGroupIdTycho;
aid = sarlLibArtifactIdTycho;
}
if (gid != null && aid != null) {
final var dependencyVersion = new DefaultArtifactVersion(dep.getVersion());
if (!containsVersion(dependencyVersion, compilerVersion, maxCompilerVersion)) {
final String shortMessage = MessageFormat.format(Messages.AbstractCompileMojo_10,
gid, aid, dependencyVersion.toString(),
compilerVersion.toString(), maxCompilerVersion.toString());
final String longMessage = MessageFormat.format(Messages.AbstractCompileMojo_11,
sarlLibGroupId, sarlLibArtifactId, dependencyVersion.toString(),
compilerVersion.toString(), maxCompilerVersion.toString());
throw new MojoFailureException(this, shortMessage, longMessage);
}
foundVersions.add(dep.getVersion());
}
}
return foundVersions;
}
private void validateDependencyVersions() throws MojoExecutionException, MojoFailureException {
final var projectDependencyTree = this.mavenHelper.getSession().getCurrentProject().getArtifactMap();
validateSarlSdk(projectDependencyTree);
validateSreOnClasspath(projectDependencyTree);
}
private void validateSarlSdk(Map projectDependencyTree) throws MojoExecutionException, MojoFailureException {
getLogger().info(Messages.AbstractCompileMojo_12);
final var sarlSdkGroupId = this.mavenHelper.getConfig("sarl-sdk.groupId"); //$NON-NLS-1$
final var sarlSdkArtifactId = this.mavenHelper.getConfig("sarl-sdk.artifactId"); //$NON-NLS-1$
var hasError = false;
final var sdkArtifactKey = ArtifactUtils.versionlessKey(sarlSdkGroupId, sarlSdkArtifactId);
final var sdkArtifact = projectDependencyTree.get(sdkArtifactKey);
if (sdkArtifact != null) {
final var pluginDependencyTree = new TreeMap();
final var pluginScopeDependencies = this.mavenHelper.resolveDependencies(sdkArtifactKey, false);
for (final var pluginScopeDependency : pluginScopeDependencies) {
final var pluginScopeDependencyVersion = new DefaultArtifactVersion(pluginScopeDependency.getVersion());
final var pluginScopeDependencyKey = ArtifactUtils.versionlessKey(pluginScopeDependency);
final var currentVersion = pluginDependencyTree.get(pluginScopeDependencyKey);
if (currentVersion == null || pluginScopeDependencyVersion.compareTo(currentVersion) > 0) {
pluginDependencyTree.put(pluginScopeDependencyKey, pluginScopeDependencyVersion);
}
}
for (final var projectDependency : projectDependencyTree.entrySet()) {
final var pluginDependencyArtifactVersion = pluginDependencyTree.get(projectDependency.getKey());
if (pluginDependencyArtifactVersion != null) {
final var projectArtifact = projectDependency.getValue();
final var projectDependencyVersion = new DefaultArtifactVersion(projectArtifact.getVersion());
if (Utils.compareMajorMinorVersions(pluginDependencyArtifactVersion, projectDependencyVersion) != 0) {
final var message = MessageFormat.format(Messages.AbstractCompileMojo_13,
projectArtifact.getGroupId(), projectArtifact.getArtifactId(),
pluginDependencyArtifactVersion.toString(), projectDependencyVersion.toString());
getLogger().error(message);
hasError = true;
}
}
}
}
if (hasError) {
throw new MojoFailureException(Messages.AbstractCompileMojo_14);
}
}
private void validateSreOnClasspath(Map projectDependencyTree) {
if (this.verifySREInDependencies) {
getLogger().info(Messages.AbstractCompileMojo_15);
for (final var artifact : projectDependencyTree.values()) {
final var file = artifact.getFile();
var found = false;
if (file != null) {
if (file.isDirectory()) {
final var sreServiceFile = FileSystem.join(file, METAINF_FOLDER_NAME, METAINF_SERVICE_FOLDER_NAME, SREBootstrap.class.getName());
found = sreServiceFile.exists();
} else {
try (final var jarFile = new JarFile(file)) {
found = jarFile.getEntry(METAINF_FOLDER_NAME + JAR_SEPARATOR + METAINF_SERVICE_FOLDER_NAME + JAR_SEPARATOR + SREBootstrap.class.getName()) != null;
} catch (IOException ex) {
// Ignore this error. Assume the given file is not a valid SRE implementation
}
}
}
if (found) {
// The SRE service file was found in the project
getLogger().info(MessageFormat.format(Messages.AbstractCompileMojo_17, artifact.getId()));
return;
}
}
// No SRE implementation was found
getLogger().warn(Messages.AbstractCompileMojo_18);
} else if (getLogger().isDebugEnabled()) {
getLogger().debug(Messages.AbstractCompileMojo_16);
}
}
/** Run the SARL compiler.
*
* @throws MojoExecutionException if the mojo cannot be run.
* @throws MojoFailureException if an error occurs during the compilation.
*/
protected abstract void compileSARL() throws MojoExecutionException, MojoFailureException;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy