package org.codehaus.mojo.cis.maven; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.xml.transform.Result; import javax.xml.transform.stream.StreamResult; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.mojo.cis.core.CisConfig; import org.codehaus.mojo.cis.core.CisConfigTransformer; import org.codehaus.mojo.cis.core.CisCoreException; import org.codehaus.mojo.cis.core.CisUtils; import org.codehaus.mojo.cis.core.DefaultResource; import org.xml.sax.InputSource; /** * A mojo for transforming the {@code cisconfig.xml} file. The source * file can either be read from the {@code cis.war} file or from a * copy of the original {@code cisconfig.xml} file. * * @goal cisConfig * @phase generate-resources */ public class CisConfigTransformerMojo extends AbstractCisMojo { /** * The {@code cisconfig.xml} file. If this is configured, then it will * be taken as the transformations source file. * @parameter */ private File cisConfigSourceFile; /** * The created {@code cisconfig.xml} file. This is required, unless * you specify the {@code cisHome CIS home directory}, in which case * the file {@code cis/config/cisconfig.xml} in the CIS home directory * will be used as a default. * @parameter */ private File cisConfigTargetFile; /** * The configuration changes, which are being applied. * * @parameter * @required */ private CisConfig cisConfig; /** * Returns the {@code cisconfig.xml} file. If this is configured, then it will * be taken as the transformations source file. */ protected File getCisConfigSourceFile() { return cisConfigSourceFile; } /** * Returns the created {@code cisconfig.xml} file. This is required, unless * you specify the {@code cisHome CIS home directory}, in which case * the file {@code cis/config/cisconfig.xml} in the CIS home directory * will be used as a default. */ protected File getCisConfigTargetFile() { return cisConfigTargetFile; } /** * Returns the file, which is being used as the source file. * <ul> * <li>If the {@link #cisConfigSourceFile} is specified, * returns this file.</li> * <li>If the {@link #cisWebappArtifact} is specified, * ensures that this artifact is present in the local * repository and uses the specified war file.</li> * <li>Otherwise, searches for a CIS jar artifact in the * projects dependencies. If such an artifact is found, * uses the artifacts group, name and version to derive * a corresponding CIS war artifact. In that case, * ensures that this artifact is present in the local * repository and uses the the specified war file.</li> * <li>Otherwise, aborts with an error message that no source * file is found.</li> * </ul> */ protected File getSourceFile() throws MojoExecutionException, MojoFailureException { if ( cisConfigSourceFile != null ) { return cisConfigSourceFile; } return getCisWebappFile(); } private File getTargetFile() throws MojoFailureException { if ( cisConfigTargetFile == null ) { File cisHome = getCisHomeDir(); if ( cisHome == null ) { throw new MojoFailureException( "Unable to determine a target file. " + " Use either of the parameters " + " cisConfigTargetFile or" + " cisHomeDir to configure it." ); } cisConfigTargetFile = new File( new File( new File( cisHome, "cis" ), "config"), "cisconfig.xml" ); } return cisConfigTargetFile; } private Result getResult() { return new StreamResult( cisConfigTargetFile ); } private InputSource getSource( File sourceFile ) throws MojoFailureException, MojoExecutionException { try { final InputStream istream; final String systemId; if ( cisConfigSourceFile == null ) { final ZipFile zipFile = new ZipFile( sourceFile ); final ZipEntry zipEntry = zipFile.getEntry( "cis/config/cisconfig.xml" ); systemId = "jar:" + sourceFile.toURI().toURL().toExternalForm() + "!" + zipEntry.getName(); istream = zipFile.getInputStream( zipEntry ); } else { systemId = sourceFile.toURI().toURL().toExternalForm(); istream = new FileInputStream( sourceFile ); } final InputSource isource = new InputSource( istream ); isource.setSystemId( systemId ); return isource; } catch ( FileNotFoundException e ) { throw new MojoFailureException( "The source file " + sourceFile.getPath() + " does not exist or could not be opened.", e ); } catch ( IOException e ) { throw new MojoExecutionException( "Failed to open the source file " + sourceFile.getPath() + ": " + e.getMessage(), e ); } } private void close( InputSource pSource ) throws IOException { InputStream is = pSource.getByteStream(); if ( is != null ) { pSource.setByteStream( null ); is.close(); } } private void close( Result pResult ) throws IOException { if ( pResult instanceof StreamResult ) { StreamResult sr = (StreamResult) pResult; final OutputStream os = sr.getOutputStream(); if ( os != null ) { sr.setOutputStream( null ); os.close(); } final Writer w = sr.getWriter(); if ( w != null ) { sr.setWriter( null ); w.close(); } } } public void execute() throws MojoExecutionException, MojoFailureException { final File sourceFile = getSourceFile(); final File targetFile = getTargetFile(); final CisUtils cisUtils = newCisUtils(); final CisUtils.Resource sourceResource = new DefaultResource( sourceFile ); final CisUtils.Resource targetResource = new DefaultResource( targetFile ); final boolean uptodate; InputSource source = null; Result result = null; try { uptodate = cisUtils.isUpToDate( sourceResource, targetResource, true ); if ( uptodate ) { getLog().debug( "Target file " + targetFile.getPath() + " is uptodate." ); } else { cisUtils.makeDirOf( targetFile ); source = getSource( sourceFile ); result = getResult(); final CisConfigTransformer cisConfigTransformer = new CisConfigTransformer(); cisConfigTransformer.setCisConfig( cisConfig ); cisConfigTransformer.transform( source, result ); close( source ); source = null; close( result ); result = null; } } catch ( IOException e ) { throw new MojoExecutionException( "Failed to transform cisconfig.xml: " + e.getMessage(), e ); } catch ( CisCoreException e ) { throw new MojoExecutionException( "Failed to transform cisconfig.xml: " + e.getMessage(), e ); } finally { if ( source != null ) { try { close( source ); } catch ( Throwable t ) { /* Ignore me */ } } if ( result != null ) { try { close( result ); } catch ( Throwable t ) { /* Ignore me */ } } } } }