
org.neo4j.build.plugins.docs.DocsAssembler Maven / Gradle / Ivy
/**
* Copyright (c) 2011-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.neo4j.build.plugins.docs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.codehaus.plexus.util.FileUtils;
final class DocsAssembler
{
static final String CLASSIFIER = "docs";
static final String TYPE = "jar";
private static final int BUFFER_SIZE = 4096;
private static final String DOCS_DIRNAME = "docs";
private static final List NON_FILTERED_FILE_EXTENSIONS;
private final Log log;
private final List sourceDirectories;
private final boolean filter;
private final MavenProject project;
private final MavenProjectHelper projectHelper;
private final MavenResourcesFiltering resourceFiltering;
private final MavenSession session;
static
{
// these are always non-filtered anyhow:
// jpg, jpeg, gif, bmp, png
// as defined in
// org.apache.maven.shared.filtering.DefaultMavenResourcesFiltering
NON_FILTERED_FILE_EXTENSIONS = Arrays.asList( "tiff",
"tif", "pdf", "zip", "gz" );
}
public DocsAssembler( final List sourceDirectories,
final boolean filter, final Log log, MavenSession session,
final MavenProject project, final MavenProjectHelper projectHelper,
MavenResourcesFiltering resourceFiltering )
{
this.sourceDirectories = sourceDirectories;
this.filter = filter;
this.project = project;
this.log = log;
this.projectHelper = projectHelper;
this.resourceFiltering = resourceFiltering;
this.session = session;
}
public File doAssembly() throws MojoExecutionException
{
log.info( "Filtering is: " + (filter ? "on" : "off") );
List dirs = getDirectories( sourceDirectories );
if ( dirs.size() == 0 )
{
log.warn( "There are no docs to assemble." );
return null;
}
File destinationFile;
if ( filter )
{
File target = new File( new File( project.getBuild()
.getDirectory() ), "filtered-docs" );
deleteRecursively( target );
filterResources( dirs, target );
destinationFile = createArchive( Collections.singletonList( target ) );
}
else
{
destinationFile = createArchive( dirs );
}
projectHelper.attachArtifact( project, TYPE, CLASSIFIER, destinationFile );
return destinationFile;
}
private File createArchive( final List directories )
throws MojoExecutionException
{
log.info( "Creating docs archive." );
final String filename = project.getArtifactId() + "-"
+ project.getVersion() + "-" + CLASSIFIER + "."
+ TYPE;
File targetDirectory = new File( project.getBuild()
.getDirectory() );
if ( !targetDirectory.exists() && !targetDirectory.mkdir() )
{
throw new MojoExecutionException(
"Could not create: " + targetDirectory.getAbsolutePath() );
}
final File destFile = new File( project.getBuild()
.getDirectory(), filename );
if ( destFile.exists() && !destFile.delete() )
{
throw new MojoExecutionException( "Could not delete: "
+ destFile.getAbsolutePath() );
}
FileOutputStream fileOut;
ZipOutputStream zipOut = null;
try
{
fileOut = new FileOutputStream( destFile );
zipOut = new ZipOutputStream( fileOut );
for ( File dir : directories )
{
int currentBaseDirPathLength = dir.getAbsolutePath()
.length();
log.info( "Adding source directory: " + dir );
zipDirectory( dir, currentBaseDirPathLength, zipOut );
}
}
catch ( FileNotFoundException e )
{
log.error( e );
}
finally
{
if ( zipOut != null )
{
try
{
zipOut.close();
}
catch ( ZipException e )
{
if ( "ZIP file must have at least one entry".equals( e.getMessage() ) )
{
log.warn( "There were no docs to assemble." );
}
else
{
log.error( e );
}
}
catch ( IOException e )
{
log.error( e );
}
}
}
return destFile;
}
private void filterResources( final List directories, File targetDir )
{
log.info( "Filter target: " + targetDir );
int baseDirLength = project.getBasedir()
.getAbsolutePath()
.length() + 1;
List resources = new ArrayList();
for ( File dir : directories )
{
Resource resource = new Resource();
resource.setDirectory( dir.getAbsolutePath()
.substring( baseDirLength ) );
resource.setFiltering( true );
log.info( "Adding source directory: " + dir );
resources.add( resource );
}
MavenResourcesExecution resourcesExecution = new MavenResourcesExecution(
resources, targetDir, project, "UTF-8",
Collections.emptyList(), NON_FILTERED_FILE_EXTENSIONS, session );
resourcesExecution.setResourcesBaseDirectory( project.getBasedir() );
resourcesExecution.addFilterWrapper( new FileUtils.FilterWrapper()
{
@Override
public Reader getReader( final Reader reader )
{
return reader;
}
} );
try
{
resourceFiltering.filterResources( resourcesExecution );
}
catch ( MavenFilteringException e )
{
log.error( e );
}
}
private void zipDirectory( final File dir, int currentBaseDirPathLength, ZipOutputStream zipOut ) throws MojoExecutionException
{
byte[] buf = new byte[BUFFER_SIZE];
for ( File file : dir.listFiles() )
{
if ( file.isDirectory() )
{
zipDirectory( file, currentBaseDirPathLength, zipOut );
continue;
}
FileInputStream inFile = null;
try
{
log.debug( "Adding: " + file.getAbsolutePath() );
inFile = new FileInputStream( file.getAbsolutePath() );
zipOut.putNextEntry( new ZipEntry( file.getAbsolutePath()
.substring( currentBaseDirPathLength ) ) );
int len;
while ( ( len = inFile.read( buf ) ) > 0 )
{
zipOut.write( buf, 0, len );
}
}
catch ( FileNotFoundException e )
{
log.error( e );
}
catch ( IOException e )
{
log.error( e );
}
finally
{
try
{
zipOut.closeEntry();
inFile.close();
}
catch ( IOException e )
{
log.error( e );
}
}
}
}
private List getDirectories( final List sourceDirectories )
throws MojoExecutionException
{
List directories = new ArrayList();
if ( sourceDirectories == null )
{
log.info( "No directories configured, using defaults." );
// add default directories
// ./src/docs and ./target/docs
addDirectory( new File( new File( project.getBasedir(), "src" ),
DOCS_DIRNAME ), directories );
addDirectory( new File( project.getBuild()
.getDirectory(), DOCS_DIRNAME ), directories );
}
else
{
for ( String dir : sourceDirectories )
{
addDirectory( new File( dir ), directories );
}
}
return directories;
}
private void addDirectory( final File dir, final List directories )
throws MojoExecutionException
{
if ( !dir.exists() )
{
log.info( "Skipping, does not exist: " + dir );
return;
}
if ( dir.listFiles().length == 0 )
{
log.info( "Skipping, is empty: " + dir );
return;
}
if ( !dir.isDirectory() )
{
throw new MojoExecutionException( "Not a directory: "
+ dir.getAbsolutePath() );
}
if ( !dir.canRead() )
{
throw new MojoExecutionException( "Can not read directory: "
+ dir.getAbsolutePath() );
}
directories.add( dir );
}
private static void deleteRecursively( File file )
{
if ( !file.exists() )
{
return;
}
if ( file.isDirectory() )
{
for ( File child : file.listFiles() )
{
deleteRecursively( child );
}
}
if ( !file.delete() )
{
throw new RuntimeException(
"Couldn't delete directory. Offending file:" + file );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy