View Javadoc

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.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  		// Pass extra parameters as System properties to allow language
66  		// implementation to retrieve their associate values...
67  		CPDConfiguration.setSystemProperties(arguments);
68  		CPD cpd = new CPD(arguments);
69  
70                  //Add files 
71                  if ( null != arguments.getFiles() && ! arguments.getFiles().isEmpty() )
72                  {
73                    addSourcesFilesToCPD(arguments.getFiles(),cpd, !arguments.isNonRecursive());
74                  }
75  
76                  //Add Database URIS
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 }