1
2
3
4 package net.sourceforge.pmd.cpd;
5
6 import java.io.IOException;
7 import java.util.List;
8
9 import com.beust.jcommander.JCommander;
10 import com.beust.jcommander.ParameterException;
11 import java.net.URISyntaxException;
12 import java.util.logging.Logger;
13 import net.sourceforge.pmd.util.database.DBURI;
14
15 public class CPDCommandLineInterface {
16 private final static Logger LOGGER = Logger.getLogger(CPDCommandLineInterface.class.getName());
17
18 private static final int DUPLICATE_CODE_FOUND = 4;
19
20 public static final String NO_EXIT_AFTER_RUN = "net.sourceforge.pmd.cli.noExit";
21 public static final String STATUS_CODE_PROPERTY = "net.sourceforge.pmd.cli.status";
22
23 private static final String progName = "cpd";
24
25 public static void setStatusCodeOrExit(int status) {
26 if (isExitAfterRunSet())
27 System.exit(status);
28 else
29 setStatusCode(status);
30 }
31
32 private static boolean isExitAfterRunSet() {
33 String noExit = System.getenv(NO_EXIT_AFTER_RUN);
34 if (noExit == null) {
35 noExit = System.getProperty(NO_EXIT_AFTER_RUN);
36 }
37 return (noExit == null ? true : false);
38 }
39
40 private static void setStatusCode(int statusCode) {
41 System.setProperty(STATUS_CODE_PROPERTY, Integer.toString(statusCode));
42 }
43
44 public static void main(String[] args) {
45 CPDConfiguration arguments = new CPDConfiguration();
46 JCommander jcommander = new JCommander(arguments);
47 jcommander.setProgramName(progName);
48
49 try {
50 jcommander.parse(args);
51 if (arguments.isHelp()) {
52 jcommander.usage();
53 System.out.println(buildUsageText());
54 setStatusCodeOrExit(1);
55 return;
56 }
57 } catch (ParameterException e) {
58 jcommander.usage();
59 System.out.println(buildUsageText());
60 System.out.println(e.getMessage());
61 setStatusCodeOrExit(1);
62 return;
63 }
64 arguments.postContruct();
65
66
67 CPDConfiguration.setSystemProperties(arguments);
68 CPD cpd = new CPD(arguments);
69
70
71 if ( null != arguments.getFiles() && ! arguments.getFiles().isEmpty() )
72 {
73 addSourcesFilesToCPD(arguments.getFiles(),cpd, !arguments.isNonRecursive());
74 }
75
76
77 if ( null != arguments.getURI() && ! "".equals(arguments.getURI()) )
78 {
79 addSourceURIToCPD(arguments.getURI(),cpd);
80 }
81
82 cpd.go();
83 if (cpd.getMatches().hasNext()) {
84 System.out.println(arguments.getRenderer().render(cpd.getMatches()));
85 setStatusCodeOrExit(DUPLICATE_CODE_FOUND);
86 }
87 }
88
89 private static void addSourcesFilesToCPD(List<String> files, CPD cpd, boolean recursive) {
90 try {
91 for (String file : files)
92 if (recursive)
93 cpd.addRecursively(file);
94 else
95 cpd.addAllInDirectory(file);
96 } catch (IOException e) {
97 throw new IllegalStateException(e);
98 }
99 }
100
101 private static void addSourceURIToCPD(String uri, CPD cpd) {
102 try {
103 LOGGER.fine(String.format("Attempting DBURI=%s" , uri));
104 DBURI dburi = new DBURI(uri);
105 LOGGER.fine(String.format("Initialised DBURI=%s"
106 , dburi
107 )
108 );
109 LOGGER.fine(String.format("Adding DBURI=%s with DBType=%s"
110 , dburi.toString()
111 , dburi.getDbType().toString()
112 )
113 );
114 cpd.add(dburi);
115 } catch (IOException e) {
116 throw new IllegalStateException( "uri="+uri, e);
117 } catch (URISyntaxException ex) {
118 throw new IllegalStateException( "uri="+uri, ex);
119 } catch (Exception ex) {
120 throw new IllegalStateException( "uri="+uri, ex);
121 }
122 }
123
124 private static final char EOL = '\n';
125 public static String buildUsageText() {
126 String helpText = "Usage:";
127
128 helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens xxx --files xxx [--language xxx] [--encoding xxx] [--format (xml|text|csv|vs)] [--skip-duplicate-files] [--non-recursive]" + EOL;
129 helpText += "i.e: " + EOL;
130
131 helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files c:\\jdk14\\src\\java " + EOL;
132 helpText += "or: " + EOL;
133
134 helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /path/to/c/code --language c " + EOL;
135 helpText += "or: " + EOL;
136
137 helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --encoding UTF-16LE --files /path/to/java/code --format xml" + EOL;
138 return helpText;
139 }
140
141 }