001package org.andromda.maven.plugin.cartridge;
002
003import java.io.File;
004import java.io.IOException;
005import java.util.HashSet;
006import java.util.List;
007import java.util.Set;
008import org.apache.commons.io.FilenameUtils;
009import org.apache.maven.artifact.Artifact;
010import org.apache.maven.model.Dependency;
011import org.apache.maven.plugin.AbstractMojo;
012import org.apache.maven.plugin.MojoExecutionException;
013import org.apache.maven.project.MavenProject;
014import org.apache.maven.settings.Settings;
015import org.codehaus.plexus.archiver.ArchiverException;
016import org.codehaus.plexus.archiver.UnArchiver;
017import org.codehaus.plexus.archiver.manager.ArchiverManager;
018
019/**
020 * Abstract base mojo for cartridge tests. Must be subclassed.
021 *
022 * @author Chad Brandon
023 * @author Peter Friese
024 * @author Bob Fields
025 */
026public abstract class AbstractCartridgeTestMojo
027    extends AbstractMojo
028{
029    /**
030     * Base directory to which the cartridge test report is written
031     *
032     * @parameter expression="${project.build.directory}/cartridge-test/reports"
033     */
034    protected File reportDirectory;
035
036    /**
037     * Specifies the directory that contains the "actual" output (meaning the output
038     * that was currently generated)
039     * @parameter expression="${project.build.directory}/cartridge-test/actual"
040     * @required
041     */
042    protected File actualDirectory;
043
044    /**
045     * Specifies the directory that contains the "expected" output.
046     * @parameter expression="${project.build.directory}/cartridge-test/expected"
047     * @required
048     */
049    protected File expectedDirectory;
050
051    /**
052     * The location of the archive storing the expected output.
053     * @parameter expression="${basedir}/src/test/expected/cartridge-outputUML2.zip"
054     * @required
055     */
056    protected File expectedOutputArchive;
057
058    /**
059     * This is the URI to the AndroMDA configuration file.
060     *
061     * @parameter expression="file:${basedir}/conf/test/andromdaUML2.xml"
062     * @required
063     */
064    protected String configurationUri;
065
066    /**
067     * @parameter expression="${project}"
068     * @required
069     * @readonly
070     */
071    protected MavenProject project;
072
073    /**
074     * @parameter expression="${project.build.filters}"
075     */
076    protected List<String> propertyFiles;
077
078    /**
079     * The current user system settings for use in Maven. (allows us to pass the user
080     * settings to the AndroMDA configuration).
081     *
082     * @parameter expression="${settings}"
083     * @required
084     * @readonly
085     */
086    protected Settings settings;
087
088    /**
089     * Defines the extensions of binary files, binary files are checked for presence
090     * and equality, however they aren't compared as strings, like every other file.
091     *
092     * @parameter expression="jpg,jpeg,gif,png,jar,zip"
093     */
094    protected String binaryOutputSuffixes;
095
096    /**
097     * To look up Archiver/UnArchiver implementations
098     *
099     * @component role="org.codehaus.plexus.archiver.manager.ArchiverManager"
100     * @required
101     */
102    protected ArchiverManager archiverManager;
103
104    /**
105     * Set this to 'true' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.
106     *
107     * @parameter expression="${maven.test.skip}"
108     */
109    protected boolean skip;
110
111    /**
112     *  Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite convenient on occasion.
113     *
114     * @parameter expression="${skipTests}"
115     */
116    protected boolean skipTests;
117
118    /**
119     * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.
120     *
121     * @parameter expression="${maven.test.failure.ignore}" default-value="false"
122     */
123    protected boolean testFailureIgnore;
124
125    /**
126     *  Set this to 'true' to skip code generation if code has not changed since the latest model date.
127     *
128     * @parameter expression="${lastModifiedCheck}"
129     */
130    protected boolean lastModifiedCheck;
131
132    /**
133     * Adds any dependencies for the cartridge plugin
134     * to the current dependencies of the project.
135     */
136    protected void changeScopeForTestDependencies()
137    {
138        // - get all test dependencies, change the scope and add them to them to the dependencies of this
139        //   project as runtime scope so that the AndroMDA plugin can see them.
140        for (final Dependency dependency : (Iterable<Dependency>) this.project.getTestDependencies())
141        {
142            //process only test dependencies
143            if (dependency.getScope().equals(Artifact.SCOPE_TEST))
144            {
145                dependency.setScope(Artifact.SCOPE_RUNTIME);
146                project.getDependencies().add(dependency);
147            }
148        }
149
150        final Set artifacts = new HashSet<Artifact>(this.project.getArtifacts());
151        for (final Artifact artifact : (Iterable<Artifact>) this.project.getTestArtifacts())
152        {
153            //process only test dependencies
154            if (artifact.getScope().equals(Artifact.SCOPE_TEST))
155            {
156                artifact.setScope(Artifact.SCOPE_RUNTIME);
157                artifacts.add(artifact);
158            }
159        }
160        project.setArtifacts(artifacts);
161    }
162
163    /**
164     * Unpacks the expected archive file to the expected directory
165     *
166     * @param file File to be unpacked.
167     * @param location Location where to put the unpacked files.
168     * @throws MojoExecutionException Error unpacking file
169     */
170    protected void unpack(
171        final File file,
172        final File location)
173        throws MojoExecutionException
174    {
175        final String archiveExt = FilenameUtils.getExtension(file.getAbsolutePath()).toLowerCase();
176        try
177        {
178            final UnArchiver unArchiver;
179            unArchiver = this.archiverManager.getUnArchiver(archiveExt);
180            unArchiver.setSourceFile(file);
181            location.mkdirs();
182            unArchiver.setDestDirectory(location);
183            unArchiver.extract();
184        }
185        catch (Throwable throwable)
186        {
187            if (this.testFailureIgnore)
188            {
189                this.getLog().error(this.project.getArtifactId() + ": Error unpacking file: " + file + " to " + location, throwable);
190            }
191            else if (throwable instanceof IOException || throwable instanceof ArchiverException)
192            {
193                throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location, throwable);
194            }
195        }
196    }
197}