1 /*** 2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 3 */ 4 package net.sourceforge.pmd.cpd; 5 6 import java.io.File; 7 import java.io.FileNotFoundException; 8 import java.io.IOException; 9 import java.util.HashMap; 10 import java.util.Iterator; 11 import java.util.List; 12 import java.util.Map; 13 14 public class CPD { 15 16 private Map source = new HashMap(); 17 private CPDListener listener = new CPDNullListener(); 18 private Tokens tokens = new Tokens(); 19 private int minimumTileSize; 20 private MatchAlgorithm matchAlgorithm; 21 private Language language; 22 23 public CPD(int minimumTileSize, Language language) { 24 this.minimumTileSize = minimumTileSize; 25 this.language = language; 26 } 27 28 public void setCpdListener(CPDListener cpdListener) { 29 this.listener = cpdListener; 30 } 31 32 public void go() { 33 TokenEntry.clearImages(); 34 matchAlgorithm = new MatchAlgorithm(source, tokens, minimumTileSize, listener); 35 matchAlgorithm.findMatches(); 36 } 37 38 public Iterator getMatches() { 39 return matchAlgorithm.matches(); 40 } 41 42 public void add(File file) throws IOException { 43 add(1, file); 44 } 45 46 public void addAllInDirectory(String dir) throws IOException { 47 addDirectory(dir, false); 48 } 49 50 public void addRecursively(String dir) throws IOException { 51 addDirectory(dir, true); 52 } 53 54 public void add(List files) throws IOException { 55 for (Iterator i = files.iterator(); i.hasNext();) { 56 add(files.size(), (File) i.next()); 57 } 58 } 59 60 private void addDirectory(String dir, boolean recurse) throws IOException { 61 if (!(new File(dir)).exists()) { 62 throw new FileNotFoundException("Couldn't find directory " + dir); 63 } 64 FileFinder finder = new FileFinder(); 65 add(finder.findFilesFrom(dir, language.getFileFilter(), recurse)); 66 } 67 68 private void add(int fileCount, File file) throws IOException { 69 listener.addedFile(fileCount, file); 70 SourceCode sourceCode = new SourceCode(new SourceCode.FileCodeLoader(file)); 71 language.getTokenizer().tokenize(sourceCode, tokens); 72 source.put(sourceCode.getFileName(), sourceCode); 73 } 74 75 public static Renderer getRendererFromString(String name) { 76 Renderer renderer = new SimpleRenderer(); 77 try { 78 renderer = (Renderer) Class.forName(name).newInstance(); 79 } catch (Exception e) { 80 System.out.println("Can't find class '" + name + "' so defaulting to SimpleRenderer."); 81 } 82 return renderer; 83 } 84 85 public static void main(String[] args) { 86 if (args.length > 4 || args.length < 2) { 87 usage(); 88 System.exit(1); 89 } 90 91 try { 92 String lang = LanguageFactory.JAVA_KEY; 93 Renderer renderer = new SimpleRenderer(); 94 if (args.length > 2) { 95 lang = args[2]; 96 } 97 if (args.length > 3) { 98 renderer = CPD.getRendererFromString(args[3]); 99 } 100 LanguageFactory f = new LanguageFactory(); 101 Language language = f.createLanguage(lang); 102 CPD cpd = new CPD(Integer.parseInt(args[0]), language); 103 cpd.addRecursively(args[1]); 104 cpd.go(); 105 System.out.println(renderer.render(cpd.getMatches())); 106 } catch (Exception e) { 107 e.printStackTrace(); 108 } 109 } 110 111 private static void usage() { 112 System.out.println("Usage:"); 113 System.out.println(" java net.sourceforge.pmd.cpd.CPD <tile size> <directory> [<language>] [<format>]"); 114 System.out.println("i.e: "); 115 System.out.println(" java net.sourceforge.pmd.cpd.CPD 100 c://jdk14//src//java "); 116 System.out.println("or: "); 117 System.out.println(" java net.sourceforge.pmd.cpd.CPD 100 c://apache//src// cpp"); 118 System.out.println("Formats:"); 119 System.out.println("Simple"); 120 System.out.println("net.sourceforge.pmd.cpd.CSVRenderer"); 121 System.out.println("net.sourceforge.pmd.cpd.XMLRenderer"); 122 } 123 124 }