/**
* Copyright (c) 2002-2015 "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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.wrapper;
import java.io.File;
import java.io.FilenameFilter;
import java.util.LinkedList;
import java.util.List;
public class ClasspathParser
{
String parse( File workingDir, String classpathSystemProperty )
{
String preClasspath = classpathSystemProperty;
String[] preClasspathEntries = preClasspath.split( ";" );
StringBuffer classpathBuffer = new StringBuffer( "\"-classpath\" \"" );
for ( String preClasspathEntry : preClasspathEntries )
{
if ( preClasspathEntry.contains( "**/" ) )
{
handleRecursiveCase( preClasspathEntry, workingDir, classpathBuffer );
}
int globSeparator = preClasspathEntry.lastIndexOf( "/" );
String classpathEntryBaseDir = preClasspathEntry.substring( 0,
globSeparator );
String classpathEntryGlob = preClasspathEntry.substring( globSeparator + 1 );
File classpathDirectory = new File( workingDir,
classpathEntryBaseDir );
if ( classpathDirectory.exists() )
{
List<File> jars = getWildcardEntries( classpathDirectory,
classpathEntryGlob );
for ( File jar : jars )
{
classpathBuffer.append( jar.getAbsolutePath() );
classpathBuffer.append( ";" );
}
}
}
classpathBuffer.append( "\"" );
return classpathBuffer.toString();
}
private void handleRecursiveCase( String preClasspathEntry, File workingDir, StringBuffer classpathBuffer )
{
String[] baseAndGlob = split( preClasspathEntry );
File classpathDirectory = new File( workingDir,
baseAndGlob[0] );
LinkedList<File> directoriesToSearch = new LinkedList<File>();
directoriesToSearch.add( classpathDirectory );
while ( !directoriesToSearch.isEmpty() )
{
File directoryToSearch = directoriesToSearch.remove();
List<File> jars = getWildcardEntries( directoryToSearch, baseAndGlob[1] );
for ( File jar : jars )
{
classpathBuffer.append( jar.getAbsolutePath() );
classpathBuffer.append( ";" );
}
File[] subDirectories = getSubDirectories( directoryToSearch );
for ( File directory : subDirectories )
{
directoriesToSearch.add( directory );
}
}
}
private File[] getSubDirectories( File directoryToSearch )
{
return directoryToSearch.listFiles( new DirectoryFilter() );
}
private String[] split( String preClasspathEntry )
{
if ( preClasspathEntry.indexOf( "**" ) != preClasspathEntry.lastIndexOf( "**" ) )
{
throw new UnsupportedOperationException( "Double **'s not supported." );
}
String[] strings = preClasspathEntry.split( "\\*\\*/" );
return strings;
}
/**
* @param directory The directory to search for.
* @return A List of Files whose filenames end with the supplied suffix
*/
private static List<File> getWildcardEntries( File directory,
final String glob )
{
final String regExp = glob.trim() == "" ? ".*"
: compileToRegexpFromGlob( glob );
final FilenameFilter filter = new FilenameFilter()
{
@Override
public boolean accept( File dir, String name )
{
return name.matches( regExp );
}
};
List<File> result = new LinkedList<File>();
String[] contents = directory.list( filter );
if ( contents != null )
{
for ( String filename : contents )
{
result.add( new File( directory, filename ) );
}
}
return result;
}
private static String compileToRegexpFromGlob( String glob )
{
StringBuffer result = new StringBuffer();
char currentChar;
for ( int i = 0; i < glob.length(); i++ )
{
currentChar = glob.charAt( i );
if ( currentChar == '*' )
{
result.append( ".*" );
}
else if ( currentChar == '.' )
{
result.append( "[.]" );
}
else
{
result.append( currentChar );
}
}
return result.toString();
}
}