CPD xref

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.File;
7 import java.io.FileNotFoundException;
8 import java.io.IOException;
9 import java.util.ArrayList;
10 import java.util.HashSet;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.TreeMap;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18 
19 import net.sourceforge.pmd.lang.ast.TokenMgrError;
20 import net.sourceforge.pmd.util.FileFinder;
21 import net.sourceforge.pmd.util.database.DBMSMetadata;
22 import net.sourceforge.pmd.util.database.DBURI;
23 import net.sourceforge.pmd.util.database.SourceObject;
24 
25 import org.apache.commons.io.FilenameUtils;
26 
27 public class CPD {
28 private final static Logger LOGGER = Logger.getLogger(CPD.class.getName()); 
29 
30 	private CPDConfiguration configuration;
31 
32 	private Map<String, SourceCode> source = new TreeMap<String, SourceCode>();
33 private CPDListener listener = new CPDNullListener();
34 private Tokens tokens = new Tokens();
35 private MatchAlgorithm matchAlgorithm;
36 
37 public CPD(CPDConfiguration theConfiguration) {
38 	configuration = theConfiguration;
39 // before we start any tokenizing (add(File...)), we need to reset the static TokenEntry status
40 TokenEntry.clearImages();
41 }
42 
43 public void setCpdListener(CPDListener cpdListener) {
44 this.listener = cpdListener;
45 }
46 
47 public void go() {
48 matchAlgorithm = new MatchAlgorithm(source, tokens,configuration.getMinimumTileSize(),listener);
49 matchAlgorithm.findMatches();
50 }
51 
52 public Iterator<Match> getMatches() {
53 return matchAlgorithm.matches();
54 }
55 
56 public void addAllInDirectory(String dir) throws IOException {
57 addDirectory(dir, false);
58 }
59 
60 public void addRecursively(String dir) throws IOException {
61 addDirectory(dir, true);
62 }
63 
64 public void add(List<File> files) throws IOException {
65 for (File f: files) {
66 add(f);
67 }
68 }
69 
70 private void addDirectory(String dir, boolean recurse) throws IOException {
71 if (!(new File(dir)).exists()) {
72 throw new FileNotFoundException("Couldn't find directory " + dir);
73 }
74 FileFinder finder = new FileFinder();
75 // TODO - could use SourceFileSelector here
76 add(finder.findFilesFrom(dir, configuration.filenameFilter(), recurse));
77 }
78 
79 private Set<String> current = new HashSet<String>();
80 
81 public void add(File file) throws IOException {
82 
83 if (configuration.isSkipDuplicates()) {
84 // TODO refactor this thing into a separate class
85 String signature = file.getName() + '_' + file.length();
86 if (current.contains(signature)) {
87 System.err.println("Skipping " + file.getAbsolutePath() + " since it appears to be a duplicate file and --skip-duplicate-files is set");
88 return;
89 }
90 current.add(signature);
91 }
92 
93 if (!FilenameUtils.equalsNormalizedOnSystem(file.getAbsoluteFile().getCanonicalPath(), file.getAbsolutePath())) {
94 System.err.println("Skipping " + file + " since it appears to be a symlink");
95 return;
96 }
97 
98 if (!file.exists()) {
99 System.err.println("Skipping " + file + " since it doesn't exist (broken symlink?)");
100 return;
101 }
102 
103 SourceCode sourceCode = configuration.sourceCodeFor(file);
104 add(sourceCode);
105 }
106 
107 public void add(DBURI dburi) throws IOException {
108 
109 try 
110 {
111 DBMSMetadata dbmsmetadata = new DBMSMetadata(dburi) ; 
112 
113 List<SourceObject> sourceObjectList = dbmsmetadata.getSourceObjectList ();
114 LOGGER.log(Level.FINER, "Located {0} database source objects", sourceObjectList.size());
115 
116 for (SourceObject sourceObject: sourceObjectList )
117 {
118 // Add DBURI as a faux-file 
119 String falseFilePath = sourceObject.getPseudoFileName();
120 LOGGER.log(Level.FINEST, "Adding database source object {0}", falseFilePath);
121 
122 SourceCode sourceCode = configuration.sourceCodeFor( dbmsmetadata.getSourceCode(sourceObject) 
123 ,falseFilePath
124 );
125 add(sourceCode);
126 }
127 }
128 catch (Exception sqlException)
129 {
130 LOGGER.log(Level.SEVERE, "Problem with Input URI", sqlException);
131 throw new RuntimeException("Problem with DBURI: "+dburi , sqlException ) ; 
132 }
133 }
134 
135 private void add(SourceCode sourceCode) throws IOException {
136 if (configuration.isSkipLexicalErrors()) {
137 addAndSkipLexicalErrors(sourceCode);
138 } else {
139 addAndThrowLexicalError(sourceCode);
140 }
141 }
142 
143 private void addAndThrowLexicalError(SourceCode sourceCode) throws IOException {
144 configuration.tokenizer().tokenize(sourceCode, tokens);
145 listener.addedFile(1, new File(sourceCode.getFileName()));
146 source.put(sourceCode.getFileName(), sourceCode);
147 }
148 
149 private void addAndSkipLexicalErrors(SourceCode sourceCode) throws IOException {
150 TokenEntry.State savedTokenEntry = new TokenEntry.State(tokens.getTokens());
151 try {
152 addAndThrowLexicalError(sourceCode);
153 } catch (TokenMgrError e) {
154 System.err.println("Skipping " + e.getMessage());
155 tokens.getTokens().clear();
156 tokens.getTokens().addAll(savedTokenEntry.restore());
157 }
158 }
159 
160 /**
161  * List names/paths of each source to be processed.
162  * 
163  * @return names of sources to be processed 
164  */
165 public List<String> getSourcePaths() {
166 return new ArrayList<String>(source.keySet()); 
167 }
168 
169 /**
170  * Get each Source to be processed.
171  * 
172  * @return all Sources to be processed 
173  */
174 public List<SourceCode> getSources() {
175 return new ArrayList<SourceCode>(source.values()); 
176 }
177 
178 
179 	public static void main(String[] args) {
180 		CPDCommandLineInterface.main(args);
181 	}
182 }

AltStyle によって変換されたページ (->オリジナル) /