blob: 814e6f5928e00249809d33491d91bcac94d0b24c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.plugins.assembly.mojos;
import java.io.File;
import java.nio.file.attribute.FileTime;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugins.assembly.archive.AssemblyArchiver;
import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugins.assembly.io.AssemblyReadException;
import org.apache.maven.plugins.assembly.io.AssemblyReader;
import org.apache.maven.plugins.assembly.model.Assembly;
import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.filtering.MavenReaderFilter;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
import org.codehaus.plexus.util.cli.CommandLineUtils;
/**
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
*/
public abstract class AbstractAssemblyMojo extends AbstractMojo implements AssemblerConfigurationSource {
protected FixedStringSearchInterpolator commandLinePropertiesInterpolator;
protected FixedStringSearchInterpolator envInterpolator;
protected FixedStringSearchInterpolator mainProjectInterpolator;
protected FixedStringSearchInterpolator rootInterpolator;
/**
* Set to false to exclude the assembly id from the assembly final name, and to create the resultant assembly
* artifacts without classifier. As such, an assembly artifact having the same format as the packaging of the
* current Maven project will replace the file for this main project artifact.
*/
@Parameter(property = "assembly.appendAssemblyId", defaultValue = "true")
boolean appendAssemblyId;
/**
* The character encoding scheme to be applied when filtering resources.
*/
@Parameter(property = "encoding", defaultValue = "${project.build.sourceEncoding}")
private String encoding;
/**
* Expressions preceded with this String won't be interpolated. If you use "\" as the escape string then \${foo}
* will be replaced with ${foo}.
*
* @since 2.4
*/
@Parameter(property = "assembly.escapeString")
private String escapeString;
/**
* Flag allowing one or more executions of the assembly plugin to be configured as skipped for a particular build.
* This makes the assembly plugin more controllable from profiles.
*/
@Parameter(property = "assembly.skipAssembly", defaultValue = "false")
private boolean skipAssembly;
/**
* If this flag is set, everything up to the call to Archiver.createArchive() will be executed.
*/
@Parameter(property = "assembly.dryRun", defaultValue = "false")
private boolean dryRun;
/**
* If this flag is set, the ".dir" suffix will be suppressed in the output directory name when using assembly/format
* == 'dir' and other formats that begin with 'dir'. <br/>
* <b>NOTE:</b> Since 2.2-beta-3, the default-value for this is true, NOT false as it used to be.
*/
@Parameter(defaultValue = "true")
private boolean ignoreDirFormatExtensions;
/**
* Contains the full list of projects in the reactor.
*/
@Parameter(defaultValue = "${reactorProjects}", required = true, readonly = true)
private List<MavenProject> reactorProjects;
/**
* The output directory of the assembled distribution file.
*/
@Parameter(defaultValue = "${project.build.directory}", required = true)
private File outputDirectory;
/**
* The filename of the assembled distribution file.<br/>
* <b>NOTE:</b> This parameter has only impact on name in project target directory,
* installed/deployed artifacts will follow convention for artifact names.
*/
@Parameter(defaultValue = "${project.build.finalName}", required = true)
private String finalName;
/**
* Directory to unpack JARs into if needed
*/
@Parameter(defaultValue = "${project.build.directory}/assembly/work", required = true)
private File workDirectory;
/**
* Specifies the formats of the assembly. Multiple formats can be supplied and the Assembly Plugin will generate an
* archive for each desired formats. When deploying your project, all file formats specified will also be deployed.
* A format is specified by supplying one of the following values in a &lt;format&gt; subelement:
* <ul>
* <li><em>dir</em> - Creates a directory</li>
* <li><em>zip</em> - Creates a ZIP file format</li>
* <li><em>tar</em> - Creates a TAR format</li>
* <li><em>tar.gz</em> or <em>tgz</em> - Creates a gzip'd TAR format</li>
* <li><em>tar.bz2</em> or <em>tbz2</em> - Creates a bzip'd TAR format</li>
* <li><em>tar.snappy</em> - Creates a snappy'd TAR format</li>
* <li><em>tar.xz</em> or <em>txz</em> - Creates a xz'd TAR format</li>
* <li><em>tar.zst</em> or <em>tzst</em> - Creates a zst'd TAR format</li>
* </ul>
*/
@Parameter
private List<String> formats;
/**
* A list of descriptor files to generate from.
*/
@Parameter
private String[] descriptors;
/**
* A list of references to assembly descriptors available on the plugin's classpath. The default classpath includes
* these built-in descriptors: <code>bin</code>, <code>jar-with-dependencies</code>, <code>src</code>, and
* <code>project</code>. You can add others by adding dependencies
* to the plugin.
*/
@Parameter
private String[] descriptorRefs;
/**
* An inline list of descriptor to generate from.
* <p/>
* Each element of list must follow <a href="./assembly.html">Assembly Descriptor</a> format.
*
* @since 3.7.0
*/
@Parameter
private List<Assembly> inlineDescriptors;
/**
* Directory to scan for descriptor files in. <b>NOTE:</b> This may not work correctly with assembly components.
*/
@Parameter
private File descriptorSourceDirectory;
/**
* This is the base directory from which archive files are created. This base directory pre-pended to any
* <code>&lt;directory&gt;</code> specifications in the assembly descriptor. This is an optional parameter.
*/
@Parameter
private File archiveBaseDirectory;
/**
* Sets the TarArchiver behavior on file paths with more than 100 characters length. Valid values are: "warn"
* (default), "fail", "truncate", "gnu", "posix", "posix_warn" or "omit".
*/
@Parameter(property = "assembly.tarLongFileMode", defaultValue = "warn")
private String tarLongFileMode;
/**
* Base directory of the project.
*/
@Parameter(defaultValue = "${project.basedir}", required = true, readonly = true)
private File basedir;
/**
* Maven ProjectHelper.
*/
@Component
private MavenProjectHelper projectHelper;
/**
* Maven shared filtering utility.
*/
@Component
private MavenReaderFilter mavenReaderFilter;
/**
* The Maven Session Object
*/
@Parameter(defaultValue = "${session}", readonly = true, required = true)
private MavenSession mavenSession;
/**
* Temporary directory that contain the files to be assembled.
*/
@Parameter(defaultValue = "${project.build.directory}/archive-tmp", required = true, readonly = true)
private File tempRoot;
/**
* Directory for site generated.
*/
@Parameter(defaultValue = "${project.reporting.outputDirectory}", readonly = true)
private File siteDirectory;
/**
* Set to true in order to not fail when a descriptor is missing.
*/
@Parameter(property = "assembly.ignoreMissingDescriptor", defaultValue = "false")
private boolean ignoreMissingDescriptor;
/**
* This is a set of instructions to the archive builder, especially for building .jar files. It enables you to
* specify a Manifest file for the jar, in addition to other options. See
* <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
*/
@Parameter
private MavenArchiveConfiguration archive;
/**
* The list of extra filter properties files to be used along with System properties, project properties, and filter
* properties files specified in the POM build/filters section, which should be used for the filtering during the
* current mojo execution. <br/> Normally, these will be configured from a plugin's execution section, to provide a
* different set of filters for a particular execution.
*/
@Parameter
private List<String> filters;
/**
* A set of additional properties to use for filtering
*
* @since 3.3.0
*/
@Parameter
private Properties additionalProperties;
/**
* If True (default) then the ${project.build.filters} are also used in addition to any further filters defined for
* the Assembly.
*
* @since 2.4.2
*/
@Parameter(property = "assembly.includeProjectBuildFilters", defaultValue = "true")
private boolean includeProjectBuildFilters;
/**
* Controls whether the assembly plugin tries to attach the resulting assembly to the project.
*
* @since 2.2-beta-1
*/
@Parameter(property = "assembly.attach", defaultValue = "true")
private boolean attach;
/**
* Indicates if zip archives (jar,zip etc) being added to the assembly should be compressed again. Compressing again
* can result in smaller archive size, but gives noticeably longer execution time.
*
* @since 2.4
*/
@Parameter(defaultValue = "true")
private boolean recompressZippedFiles;
/**
* sets the merge manifest mode in the JarArchiver
*
* @since 3
*/
@Parameter
private String mergeManifestMode;
/**
*
*/
@Component
private AssemblyArchiver assemblyArchiver;
/**
*
*/
@Component
private AssemblyReader assemblyReader;
/**
* Allows additional configuration options that are specific to a particular type of archive format. This is
* intended to capture an XML configuration that will be used to reflectively setup the options on the archiver
* instance. <br/> To see the possible options for archiver configuration visit the
* <a href="https://codehaus-plexus.github.io/plexus-archiver/apidocs/org/codehaus/plexus/archiver/Archiver.html">
* Plexus Archiver Documentation</a> <br/> For instance, to direct an assembly with the "ear" format to use a
* particular deployment descriptor, you should specify the following for the archiverConfig value in your plugin
* configuration: <br/>
* <p/>
* <p/>
* <pre>
* &lt;appxml&gt;${project.basedir}/somepath/app.xml&lt;/appxml&gt;
* </pre>
* <p/>
*
* @since 2.2-beta-3
*/
@Parameter
private PlexusConfiguration archiverConfig;
/**
* This will cause the assembly to run only at the top of a given module tree. That is, run in the project contained
* in the same folder where the mvn execution was launched.
*
* @since 2.2-beta-4
*/
@Parameter(property = "assembly.runOnlyAtExecutionRoot", defaultValue = "false")
private boolean runOnlyAtExecutionRoot;
/**
* This will cause the assembly to only update an existing archive, if it exists.
* <p>
* <strong>Note:</strong> The property that can be used on the command line was misspelled as "assembly.updatOnly"
* in versions prior to version 2.4.
* </p>
*
* @since 2.2
*/
@Parameter(property = "assembly.updateOnly", defaultValue = "false")
private boolean updateOnly;
/**
* <p>
* Set to <code>true</code> in order to avoid all chmod calls.
* </p>
* <p/>
* <p>
* <b>NOTE:</b> This will cause the assembly plugin to <b>DISREGARD</b> all fileMode/directoryMode settings in the
* assembly descriptor, and all file permissions in unpacked dependencies!
* </p>
*
* @since 2.2
*/
@Parameter(property = "assembly.ignorePermissions", defaultValue = "false")
private boolean ignorePermissions;
/**
* <p>
* Set of delimiters for expressions to filter within the resources. These delimiters are specified in the form
* 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end.
* </p>
* <p>
* So, the default filtering delimiters might be specified as:
* </p>
* <p/>
* <pre>
* &lt;delimiters&gt;
* &lt;delimiter&gt;${*}&lt;/delimiter&gt;
* &lt;delimiter&gt;@&lt;/delimiter&gt;
* &lt;/delimiters&gt;
* </pre>
* <p>
* Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
* </p>
*
* @since 2.4
*/
@Parameter
private List<String> delimiters;
/**
* Timestamp for reproducible output archive entries, either formatted as ISO 8601
* <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
* <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
*
* @since 3.2.0
*/
@Parameter(defaultValue = "${project.build.outputTimestamp}")
private String outputTimestamp;
/**
* Override of user ID in archive type which can store it.
*/
@Parameter
private Integer overrideUid;
/**
* Override of user name in archive type which can store it.
*/
@Parameter
private String overrideUserName;
/**
* Override of group ID in archive type which can store it.
*/
@Parameter
private Integer overrideGid;
/**
* Override of group name in archive type which can store it.
*/
@Parameter
private String overrideGroupName;
public static FixedStringSearchInterpolator mainProjectInterpolator(MavenProject mainProject) {
if (mainProject != null) {
// 5
return FixedStringSearchInterpolator.create(
new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
InterpolationConstants.PROJECT_PREFIXES, mainProject, true),
// 6
new org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource(
InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, mainProject.getProperties(), true));
} else {
return FixedStringSearchInterpolator.empty();
}
}
/**
* Create the binary distribution.
*/
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (skipAssembly) {
getLog().info("Assemblies have been skipped per configuration of the skipAssembly parameter.");
return;
}
// run only at the execution root.
if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) {
getLog().info("Skipping the assembly in this project because it's not the Execution Root");
return;
}
List<Assembly> assemblies;
try {
assemblies = assemblyReader.readAssemblies(this);
} catch (final AssemblyReadException e) {
throw new MojoExecutionException("Error reading assemblies: " + e.getMessage(), e);
} catch (final InvalidAssemblerConfigurationException e) {
throw new MojoFailureException(
assemblyReader, e.getMessage(), "Mojo configuration is invalid: " + e.getMessage());
}
// TODO: include dependencies marked for distribution under certain formats
// TODO: how, might we plug this into an installer, such as NSIS?
FileTime outputDate = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp)
.map(FileTime::from)
.orElse(null);
boolean warnedAboutMainProjectArtifact = false;
for (final Assembly assembly : assemblies) {
try {
final String fullName = AssemblyFormatUtils.getDistributionName(assembly, this);
List<String> effectiveFormats = formats;
if (effectiveFormats == null || effectiveFormats.isEmpty()) {
effectiveFormats = assembly.getFormats();
}
if (effectiveFormats == null || effectiveFormats.isEmpty()) {
throw new MojoFailureException(
"No formats specified in the execution parameters or the assembly descriptor.");
}
for (final String format : effectiveFormats) {
final File destFile = assemblyArchiver.createArchive(assembly, fullName, format, this, outputDate);
final MavenProject project = getProject();
final String type = project.getArtifact().getType();
if (attach && destFile.isFile()) {
if (isAssemblyIdAppended()) {
projectHelper.attachArtifact(project, format, assembly.getId(), destFile);
} else if (!"pom".equals(type) && format.equals(type)) {
if (!warnedAboutMainProjectArtifact) {
final StringBuilder message = new StringBuilder();
message.append("Configuration option 'appendAssemblyId' is set to false.");
message.append("\nInstead of attaching the assembly file: ")
.append(destFile);
message.append(", it will become the file for main project artifact.");
message.append("\nNOTE: If multiple descriptors or descriptor-formats are provided "
+ "for this project, the value of this file will be "
+ "non-deterministic!");
getLog().warn(message);
warnedAboutMainProjectArtifact = true;
}
final File existingFile = project.getArtifact().getFile();
if ((existingFile != null) && existingFile.exists()) {
getLog().warn("Replacing pre-existing project main-artifact file: " + existingFile
+ "\nwith assembly file: " + destFile);
}
project.getArtifact().setFile(destFile);
} else {
projectHelper.attachArtifact(project, format, null, destFile);
}
} else if (attach) {
getLog().warn("Assembly file: " + destFile + " is not a regular file (it may be a directory). "
+ "It cannot be attached to the project build for installation or "
+ "deployment.");
}
}
} catch (final ArchiveCreationException | AssemblyFormattingException e) {
throw new MojoExecutionException("Failed to create assembly: " + e.getMessage(), e);
} catch (final InvalidAssemblerConfigurationException e) {
throw new MojoFailureException(
assembly,
"Assembly is incorrectly configured: " + assembly.getId(),
"Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage());
}
}
}
private FixedStringSearchInterpolator createRepositoryInterpolator() {
final Properties settingsProperties = new Properties();
final MavenSession session = getMavenSession();
final File basedir = session.getRepositorySession()
.getLocalRepositoryManager()
.getRepository()
.getBasedir();
settingsProperties.setProperty("localRepository", basedir.toString());
settingsProperties.setProperty("settings.localRepository", basedir.toString());
return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(settingsProperties));
}
private FixedStringSearchInterpolator createCommandLinePropertiesInterpolator() {
Properties commandLineProperties = System.getProperties();
final MavenSession session = getMavenSession();
if (session != null) {
commandLineProperties = new Properties();
commandLineProperties.putAll(session.getSystemProperties());
commandLineProperties.putAll(session.getUserProperties());
}
PropertiesBasedValueSource cliProps = new PropertiesBasedValueSource(commandLineProperties);
return FixedStringSearchInterpolator.create(cliProps);
}
private FixedStringSearchInterpolator createEnvInterpolator() {
PrefixedPropertiesValueSource envProps = new PrefixedPropertiesValueSource(
Collections.singletonList("env."), CommandLineUtils.getSystemEnvVars(false), true);
return FixedStringSearchInterpolator.create(envProps);
}
/**
* Returns true if the current project is located at the Execution Root Directory (where mvn was launched)
*
* @return if this is the execution root
*/
boolean isThisTheExecutionRoot() {
final Log log = getLog();
log.debug("Root Folder:" + mavenSession.getExecutionRootDirectory());
log.debug("Current Folder:" + basedir);
final boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());
if (result) {
log.debug("This is the execution root.");
} else {
log.debug("This is NOT the execution root.");
}
return result;
}
@Override
public File getBasedir() {
return basedir;
}
public void setBasedir(final File basedir) {
this.basedir = basedir;
}
@Override
public String[] getDescriptorReferences() {
return descriptorRefs;
}
public List<Assembly> getInlineDescriptors() {
return inlineDescriptors;
}
@Override
public File getDescriptorSourceDirectory() {
return descriptorSourceDirectory;
}
@Override
public String[] getDescriptors() {
return descriptors;
}
public void setDescriptors(final String[] descriptors) {
this.descriptors = descriptors;
}
@Override
public File getSiteDirectory() {
return siteDirectory;
}
public void setSiteDirectory(final File siteDirectory) {
this.siteDirectory = siteDirectory;
}
@Override
public String getFinalName() {
return finalName;
}
public void setFinalName(final String finalName) {
this.finalName = finalName;
}
@Override
public boolean isAssemblyIdAppended() {
return appendAssemblyId;
}
@Override
public String getTarLongFileMode() {
return tarLongFileMode;
}
public void setTarLongFileMode(final String tarLongFileMode) {
this.tarLongFileMode = tarLongFileMode;
}
@Override
public File getOutputDirectory() {
return outputDirectory;
}
public void setOutputDirectory(final File outputDirectory) {
this.outputDirectory = outputDirectory;
}
@Override
public MavenArchiveConfiguration getJarArchiveConfiguration() {
return archive;
}
@Override
public File getWorkingDirectory() {
return workDirectory;
}
@Override
public File getTemporaryRootDirectory() {
return tempRoot;
}
@Override
public File getArchiveBaseDirectory() {
return archiveBaseDirectory;
}
@Override
public List<String> getFilters() {
if (filters == null) {
filters = getProject().getBuild().getFilters();
if (filters == null) {
filters = Collections.emptyList();
}
}
return filters;
}
public void setFilters(final List<String> filters) {
this.filters = filters;
}
public Properties getAdditionalProperties() {
return additionalProperties;
}
@Override
public boolean isIncludeProjectBuildFilters() {
return includeProjectBuildFilters;
}
@Override
public List<MavenProject> getReactorProjects() {
return reactorProjects;
}
public void setReactorProjects(final List<MavenProject> reactorProjects) {
this.reactorProjects = reactorProjects;
}
public void setAppendAssemblyId(final boolean appendAssemblyId) {
this.appendAssemblyId = appendAssemblyId;
}
public void setArchive(final MavenArchiveConfiguration archive) {
this.archive = archive;
}
public void setDescriptorRefs(final String[] descriptorRefs) {
this.descriptorRefs = descriptorRefs;
}
public void setTempRoot(final File tempRoot) {
this.tempRoot = tempRoot;
}
public void setWorkDirectory(final File workDirectory) {
this.workDirectory = workDirectory;
}
@Override
public boolean isDryRun() {
return dryRun;
}
@Override
public boolean isIgnoreDirFormatExtensions() {
return ignoreDirFormatExtensions;
}
@Override
public boolean isIgnoreMissingDescriptor() {
return ignoreMissingDescriptor;
}
@Override
public MavenSession getMavenSession() {
return mavenSession;
}
@Override
public String getArchiverConfig() {
return archiverConfig == null ? null : archiverConfig.toString();
}
@Override
public MavenReaderFilter getMavenReaderFilter() {
return mavenReaderFilter;
}
@Override
public boolean isUpdateOnly() {
return updateOnly;
}
@Override
public boolean isIgnorePermissions() {
return ignorePermissions;
}
@Override
public String getEncoding() {
return encoding;
}
@Override
public boolean isRecompressZippedFiles() {
return recompressZippedFiles;
}
@Override
public String getMergeManifestMode() {
return mergeManifestMode;
}
@Override
public String getEscapeString() {
return escapeString;
}
@Override
public List<String> getDelimiters() {
return delimiters;
}
public void setDelimiters(List<String> delimiters) {
this.delimiters = delimiters;
}
@Override
public synchronized FixedStringSearchInterpolator getCommandLinePropsInterpolator() {
if (commandLinePropertiesInterpolator == null) {
this.commandLinePropertiesInterpolator = createCommandLinePropertiesInterpolator();
}
return commandLinePropertiesInterpolator;
}
@Override
public synchronized FixedStringSearchInterpolator getEnvInterpolator() {
if (envInterpolator == null) {
this.envInterpolator = createEnvInterpolator();
}
return envInterpolator;
}
@Override
public synchronized FixedStringSearchInterpolator getRepositoryInterpolator() {
if (rootInterpolator == null) {
this.rootInterpolator = createRepositoryInterpolator();
}
return rootInterpolator;
}
@Override
public synchronized FixedStringSearchInterpolator getMainProjectInterpolator() {
if (mainProjectInterpolator == null) {
this.mainProjectInterpolator = mainProjectInterpolator(getProject());
}
return mainProjectInterpolator;
}
@Override
public Integer getOverrideUid() {
return this.overrideUid;
}
@Override
public String getOverrideUserName() {
return this.overrideUserName;
}
@Override
public Integer getOverrideGid() {
return this.overrideGid;
}
@Override
public String getOverrideGroupName() {
return this.overrideGroupName;
}
}