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 }