/* * [FindImports.java] * * Summary: Scan Java source code for import statements. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2005-06-30 loosely based on SeeSort * 1.1 2006-03-05 reformat with IntelliJ, add Javadoc */ package com.mindprod.findimports; import com.mindprod.commandline.CommandLine; import com.mindprod.common18.EIO; import com.mindprod.filter.AllButSVNDirectoriesFilter; import com.mindprod.filter.ExtensionListFilter; import com.mindprod.hunkio.HunkIO; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; import static java.lang.System.*; /** * Scan Java source code for import statements. *

* scans all *.java files in current dir tree for import statements to generate and include file for source and class * files for the packages referenced. Works only one level deep. Handles zip at package level, unlike Jar which must be * done at the class level. Works using regex. This may serve as a base for other programs that use regexev to extract * data from set of files. * * @author Roedy Green, Canadian Mind Products * @version 1.1 2006-03-05 reformat with IntelliJ, add Javadoc * @since 2005-06-30 */ public final class FindImports { private static final int FIRST_COPYRIGHT_YEAR = 2005; /** * undisplayed copyright notice */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String RELEASE_DATE = "2006-03-06"; /** * embedded version string. */ private static final String VERSION_STRING = "1.1"; // this is the preferred pattern. Finds classname, which we later chop to // classname private static final Pattern importPattern = Pattern .compile( "import\\s+(com\\.mindprod\\.([\\w\\.\\*]++))\\s*\\;" ); /** * dotted names of imports found in java source, no wildcards! , strippd of leading import and trailing ;, trimmed */ private static ArrayList foundImportedPackages; /** * Constructor */ private FindImports() { } /** * Remove any duplicates. The first object encountered is kept. Subsequent ones are removed. * * @param withDups ArrayList with duplicates. (will be sorted as side effect by natural comparator ) * * @return list with any duplicates removed and sorted in order by the natural comparator. */ private static ArrayList deDupKeepingFirst( ArrayList withDups ) { Collections.sort( withDups ); int size = withDups.size(); ArrayList result = new ArrayList<>( size ); if ( size <= 1 ) { if ( size == 1 ) { result.add( withDups.get( 0 ) ); } return result; } String prev = withDups.get( 0 ); result.add( prev ); for ( int i = 1; i < size; i++ ) { String o = withDups.get( i ); if ( o.compareTo( prev ) != 0 ) { result.add( o ); prev = o; } } return result; } /** * compact and tidy one file to fix verbose hrefs. * * @param fileBeingProcessed File to scan for imports * * @throws IOException if cannot read file. */ private static void findImportsInFile( File fileBeingProcessed ) throws IOException { String big = HunkIO.readEntireFile( fileBeingProcessed ); // find stuff between import ... ; out.println( fileBeingProcessed + " " + big.length() ); Matcher m = importPattern.matcher( big ); while ( m.find() ) { // group 0 import static java.lang.System.err; import static java.lang.System.*; import com.mindprod // .hunkio.HunkIO; // group 1 com.mindprod.hunkio.HunkIO // group 2 hunkio.HunkIO // we only are interested in group 1, allowing for future multiple // prefixes. String importedClassName = m.group( 1 ).trim(); // impuortedClassname will end in .xxxx or .*, chop it off to get // package name. int place = importedClassName.lastIndexOf( '.' ); // just ignore, might have been gibberish in a comment. We are // pretty mindless about parsing. if ( place < 1 ) { continue; } String packageName = importedClassName.substring( 0, place ); foundImportedPackages.add( packageName ); } } // end findImportsInFile /** * finds imports in java source in current directory. * * @param args not used If there is no index for the dir, then use empty.ser */ public static void main( String[] args ) { // global over all wantedFiles. foundImportedPackages = new ArrayList<>( 500 ); out.println( "Gathering files to process..." ); CommandLine commmandLine = new CommandLine( new String[] { "-s", "." }, new AllButSVNDirectoriesFilter(), new ExtensionListFilter( "java" ) ); for ( File wantedFile : commmandLine ) { try { findImportsInFile( wantedFile ); } catch ( FileNotFoundException e ) { out.println( "Error: " + EIO.getCanOrAbsPath( wantedFile ) + " not found." ); } catch ( Exception e ) { err.println(); e.printStackTrace( err ); err.println( " in file " + EIO.getCanOrAbsPath( wantedFile ) ); err.println(); } } // end for // foundImportedPackages has our big list of packages. // sort and dedup foundImportedPackages = deDupKeepingFirst( foundImportedPackages ); try { out.println( "Saving forZipsCore.list" ); PrintWriter emit = new PrintWriter( new FileWriter( new File( "forZipsCore.list" ) ) ); for ( String packageName : foundImportedPackages ) { // generate lines like: // com\mindprod\hunkio\*.class // com\mindprod\hunkio\*.java packageName = packageName.replace( '.', '\\' ); emit.println( packageName + "\\*.class" ); emit.println( packageName + "\\*.java" ); } emit.close(); } catch ( IOException e ) { err.println(); e.printStackTrace( err ); err.println( "trouble generating forZipsCore.list" ); err.println(); } } // end main } // end FindImports