package org.codehaus.mojo.rpm;
/*
* 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.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* A description of a file or directory to be installed. It includes the properties to be assigned and the location(s)
* where the file(s) can be found for packaging.
*
* @version $Id$
*/
public class Mapping
{
// // // Properties
/** Destination directory name. */
private String directory;
/**
* Indicates the configuration value for the files.
* <p>
* For passivity purposes, a value of <i>true</i> or <i>false</i> will indicate whether the <code>%config</code>
* descriptor will be written in the spec file.<br/> However, any other value (such as <i>noreplace</i>) can be
* passed and will be written into the spec file after <code>%config</code>. In the case of <i>noreplace</i>, it
* would look like <code>%config(noreplace)</code>.
* </p>
*/
private String configuration;
/** <code>true</code> if the files are documentation. */
private boolean documentation;
/** File mode (octal string) to assign to files when installed. */
private String filemode;
/** User name for files when installed. */
private String username;
/** Group name for files when installed. */
private String groupname;
/** Mapping information for source directories. */
private List sources;
/** Mapping information for artifacts. */
private ArtifactMap artifact;
/** Mapping information for dependencies. */
private Dependency dependency;
/**
* Indicates if the {@link #directory} should be used for the {@link #getAttrString() attribute string}.
*
* @since 2.0-beta-2
*/
private boolean directoryIncluded = true;
/**
* Indicates if sub-directories contained in the {@link #getSources()} should be explicitly listed in
* {@code %files}. This includes listing the {@link #getDestination()}, if {@link #isDirectoryIncluded()}
* is {@code true}.
*
* @since 2.1-alpha-1
*/
private boolean recurseDirectories = false;
/**
* List of files actually copied for the Mapping.
* <p>
* This is a <tt>List</tt> of <tt>String</tt> objects which identify files relative to the
* {@link #getDestination()}.
* </p>
* <p>
* This is populated by {@link #sources}, {@link #artifact}, and {@link #dependency}.
* </p>
*/
private List copiedFileNamesRelativeToDestination;
/**
* List of files that will be added by soft link for the Mapping.
* <p>
* This is a <tt>List</tt> of <tt>String</tt> objects which identify files relative to the
* {@link #getDestination()}.
* </p>
* @since 2.0-beta-3
*/
private List linkedFileNamesRelativeToDestination;
/**
* Indicates if the {@link #sources} contain any {@link SoftlinkSource} instances.
* @since 2.0-beta-3
*/
private boolean hasSoftLinks = false;
/**
* The absolute destination in the {@link AbstractRPMMojo#getBuildroot() buildroot}. This includes evaluating
* any/all macros.
*
* @since 2.1-alpha-1
*/
private File absoluteDestination;
/**
* Retrieve the destination during package installation.
*
* @return The destination during package installation.
*/
public String getDirectory()
{
return directory;
}
/**
* Set the destination during package installation.
*
* @param dir The new destination during package installation.
*/
public void setDirectory( String dir )
{
directory = dir;
}
/**
* Returns if the {@link #getDirectory()} should be used for the
* {@link #getAttrString(String, String, String) attribute string} (if and only if {@link #getSources() sources}
* make up everything that gets copied to the directory).<br/> By default, this returns <code>true</code>.
*
* @return Whether the {@link #getDirectory()} should be used for the
* {@link #getAttrString(String, String, String) attribute string}.
*/
public boolean isDirectoryIncluded()
{
return this.directoryIncluded;
}
/**
* Sets if the {@link #getDirectory()} should be used for the
* {@link #getAttrString(String, String, String) attribute string} (if and only if {@link #getSources() sources}
* make up everything that gets copied to the directory).<br/> By default, this is <code>true</code>.
*
* @param directoryIncluded The {@link #directoryIncluded} to set.
*/
public void setDirectoryIncluded( boolean directoryIncluded )
{
this.directoryIncluded = directoryIncluded;
}
/**
* Retrieve the configuration status. This value is <code>true</code> if the file(s) in this mapping are
* configuration files.
*
* @return The configuration status.
* @deprecated use {@link #getConfiguration()}
*/
public boolean isConfiguration()
{
return configuration == null || !"FALSE".equalsIgnoreCase( configuration );
}
/**
* Retrieves the configuration value. This may be just a string representation of {@link #isConfiguration()}.
* However, modifications to the <i>%config</i> declaration (such as <i>noreplace</i>) are allowed.
*
* @return The configuration value.
*/
public String getConfiguration()
{
return configuration;
}
/**
* Set the configuration status. This value is <code>true</code> if the file(s) in this mapping are configuration
* files. Any value other than <code>true</code> or <code>false</code> will be considered a modifier of the
* <i>%config</i> declaration in the spec file.
*
* @param cfg The new configuration value.
*/
public void setConfiguration( String cfg )
{
configuration = cfg;
}
/**
* Retrieve the documentation status. This value is <code>true</code> if the file(s) in this mapping are
* documentation files.
*
* @return The documentation status.
*/
public boolean isDocumentation()
{
return documentation;
}
/**
* Set the documentation status. This value is <code>true</code> if the file(s) in this mapping are documentation
* files.
*
* @param isDoc The new documentation status.
*/
public void setDocumentation( boolean isDoc )
{
documentation = isDoc;
}
/**
* Retrieve the UNIX file permissions. This is a three-digit octal number which specifies the permissions to be
* applied to each file in the mapping when it is installed.
*
* @return The UNIX file permissions.
*/
public String getFilemode()
{
return filemode;
}
/**
* Set the UNIX file permissions. This is a three-digit octal number which specifies the permissions to be applied
* to each file in the mapping when it is installed.
*
* @param fmode The new UNIX file permissions.
*/
public void setFilemode( String fmode )
{
filemode = fmode;
}
/**
* Retrieve the UNIX user name to own the installed files. Note that this must be a name, not a numeric user ID.
*
* @return The UNIX user name to own the installed files.
*/
public String getUsername()
{
return username;
}
/**
* Set the UNIX user name to own the installed files. Note that this must be a name, not a numeric user ID.
*
* @param uname The new UNIX user name to own the installed files.
*/
public void setUsername( String uname )
{
username = uname;
}
/**
* Retrieve the UNIX group name to own the installed files. Note that this must be a name, not a numeric group ID.
*
* @return The UNIX group name to own the installed files.
*/
public String getGroupname()
{
return groupname;
}
/**
* Set the UNIX group name to own the installed files. Note that this must be a name, not a numeric group ID.
* Indicates if sub-directories contained in the {@link #getSources()} should be explicitly listed in
* {@code %files}.
* @param grpname The new UNIX group name to own the installed files.
*/
public void setGroupname( String grpname )
{
groupname = grpname;
}
/**
* Retrieve the list of source file specifications.
*
* @return The list of source file specifications.
*/
public List getSources()
{
return sources;
}
/**
* Set the list of source file specifications.
*
* @param srclist The new list of source file specifications.
*/
public void setSources( List srclist )
{
sources = srclist;
}
/**
* Retrieve the artifact specification.
*
* @return The artifact specification.
*/
public ArtifactMap getArtifact()
{
return artifact;
}
/**
* Set the artifact specification.
*
* @param am The new artifact specification.
*/
public void setArtifact( ArtifactMap am )
{
artifact = am;
}
/**
* Retrieve the dependency specification.
*
* @return The dependency specification.
*/
public Dependency getDependency()
{
return dependency;
}
/**
* Set the dependency specification.
*
* @param am The new dependency specification.
*/
public void setDependency( Dependency am )
{
dependency = am;
}
/**
* Indicates if sub-directories contained in the {@link #getSources()} should be explicitly listed in
* {@code %files}. This includes listing the {@link #getDestination()}, if {@link #isDirectoryIncluded()}
* is {@code true}.
*
* @return Returns the {@link #recurseDirectories}.
* @since 2.1-alpha-1
*/
public final boolean isRecurseDirectories()
{
return this.recurseDirectories;
}
/**
* Indicates if sub-directories contained in the {@link #getSources()} should be explicitly listed in
* {@code %files}. This includes listing the {@link #getDestination()}, if {@link #isDirectoryIncluded()}
* is {@code true}.
*
* @param recurseDirectories The {@link #recurseDirectories} to set.
* @since 2.1-alpha-1
*/
public final void setRecurseDirectories( boolean recurseDirectories )
{
this.recurseDirectories = recurseDirectories;
}
/**
* Assemble the RPM SPEC file attributes for a mapping.
*
* @param defaultFileMode Default file mode to use if not set for this mapping.
* @param defaultGrp Default group to use if not set for this mapping.
* @param defaultUsr Default user to use if not set for this mapping.
*
* @return The attribute string for the SPEC file.
*/
public String getAttrString( String defaultFileMode, String defaultGrp, String defaultUsr )
{
defaultFileMode = defaultFileMode == null ? "-" : defaultFileMode;
defaultGrp = defaultGrp == null ? "-" : defaultGrp;
defaultUsr = defaultUsr == null ? "-" : defaultUsr;
StringBuffer sb = new StringBuffer();
if ( configuration != null && !"FALSE".equalsIgnoreCase( configuration ) )
{
sb.append( "%config" );
if ( configuration.length() > 0 && !"TRUE".equalsIgnoreCase( configuration ) )
{
sb.append( '(' );
sb.append( configuration );
sb.append( ')' );
}
sb.append( ' ' );
}
if ( documentation )
{
sb.append( "%doc " );
}
if ( ( ( sources == null ) || ( sources.size() == 0 ) ) && ( dependency == null ) && ( artifact == null ) )
{
sb.append( "%dir " );
}
/* do not include %attr if no attributes are specified */
if ( !( filemode == null && username == null && groupname == null ) )
{
sb.append( "%attr(" );
sb.append( filemode != null ? filemode : defaultFileMode );
sb.append( ',' );
sb.append( username != null ? username : defaultUsr );
sb.append( ',' );
sb.append( groupname != null ? groupname : defaultGrp );
sb.append( ')' );
}
return sb.toString();
}
/**
* Return the destination directory name.
*
* @return The name of the destination directory.
*/
public String getDestination()
{
if ( directory == null )
{
return "nowhere";
}
return directory;
}
/**
* Return directory-only status.
*
* @return <code>true</code> if no sources were specified in the mapping
*/
public boolean isDirOnly()
{
if ( ( sources != null ) && ( !sources.isEmpty() ) )
{
return false;
}
if ( artifact != null )
{
return false;
}
if ( dependency != null )
{
return false;
}
return true;
}
/**
* Returns the names of files copied to the {@link #getDestination() destination}.<br/>
* This is a <tt>List</tt> of <tt>String</tt> objects which identify files relative to the
* <tt>destination</tt>.
*
* @return The names of files copied to the <tt>destination</tt>. The <tt>List</tt> returned will never be
* <code>null</code>, but may be immutable.
*/
List getCopiedFileNamesRelativeToDestination()
{
return this.copiedFileNamesRelativeToDestination != null ? this.copiedFileNamesRelativeToDestination
: Collections.EMPTY_LIST;
}
/**
* Add a <tt>List</tt> of relative file names which have c
*
* @param copiedFileNamesRelativeToDestination relative names of files to add
* @see #getCopiedFileNamesRelativeToDestination()
*/
void addCopiedFileNamesRelativeToDestination( List copiedFileNamesRelativeToDestination )
{
if ( this.copiedFileNamesRelativeToDestination == null )
{
this.copiedFileNamesRelativeToDestination = new ArrayList( copiedFileNamesRelativeToDestination );
}
else
{
this.copiedFileNamesRelativeToDestination.addAll( copiedFileNamesRelativeToDestination );
}
}
/**
* Adds a relative file name that has been copied to the {@link #getDestination() destination}.
*
* @param copiedFileNameRelativeToDestination relative name of file to add to list
* @see #getCopiedFileNamesRelativeToDestination()
*/
void addCopiedFileNameRelativeToDestination( String copiedFileNameRelativeToDestination )
{
if ( this.copiedFileNamesRelativeToDestination == null )
{
this.copiedFileNamesRelativeToDestination = new LinkedList();
}
this.copiedFileNamesRelativeToDestination.add( copiedFileNameRelativeToDestination );
}
/**
* Returns the names of files linked to in the {@link #getDestination() destination}.<br/> This is a <tt>List</tt>
* of <tt>String</tt> objects which identify files which will be created by link relative to the
* <tt>destination</tt>.
*
* @return The names of files copied to the <tt>destination</tt>. The <tt>List</tt> returned will never be
* <code>null</code>, but may be immutable.
* @since 2.0-beta-3
*/
List getLinkedFileNamesRelativeToDestination()
{
return this.linkedFileNamesRelativeToDestination != null ? this.linkedFileNamesRelativeToDestination
: Collections.EMPTY_LIST;
}
/**
* Adds a relative file name that will be linked to the {@link #getDestination() destination}.
*
* @param linkedFileNameRelativeToDestination
* @see #getLinkedFileNamesRelativeToDestination()
* @since 2.0-beta-3
*/
void addLinkedFileNameRelativeToDestination( String linkedFileNameRelativeToDestination )
{
if ( this.linkedFileNamesRelativeToDestination == null )
{
this.linkedFileNamesRelativeToDestination = new LinkedList();
}
linkedFileNamesRelativeToDestination.add( linkedFileNameRelativeToDestination );
}
/**
* @return Returns the {@link #hasSoftLinks}.
* @since 2.0-beta-3
*/
boolean hasSoftLinks()
{
return this.hasSoftLinks;
}
/**
* @param hasSoftLinks The {@link #hasSoftLinks} to set.
* @since 2.0-beta-3
*/
void setHasSoftLinks( boolean hasSoftLinks )
{
this.hasSoftLinks = hasSoftLinks;
}
/**
* @return Returns the {@link #absoluteDestination}.
* @since 2.1-alpha-1
*/
final File getAbsoluteDestination()
{
return this.absoluteDestination;
}
/**
* @param absoluteDestination The {@link #absoluteDestination} to set.
* @since 2.1-alpha-1
*/
final void setAbsoluteDestination( File absoluteDestination )
{
this.absoluteDestination = absoluteDestination;
}
/** {@inheritDoc} */
public String toString()
{
boolean sourceShown = false;
StringBuffer sb = new StringBuffer();
sb.append( "[\"" + getDestination() + "\" " );
sb.append( "{" + getAttrString( null, null, null ) + "}" );
if ( isDirOnly() )
{
sb.append( " (dir only)]" );
}
else
{
sb.append( " from " );
if ( sources != null )
{
sb.append( sources.toString() );
sourceShown = true;
}
if ( artifact != null )
{
if ( sourceShown )
{
sb.append( ", " );
}
sb.append( artifact.toString() );
sourceShown = true;
}
if ( dependency != null )
{
if ( sourceShown )
{
sb.append( ", " );
}
sb.append( dependency.toString() );
sourceShown = true;
}
sb.append( "]" );
}
return sb.toString();
}
}