1 19 20 package org.netbeans.modules.tasklist.pmd; 21 22 import net.sourceforge.pmd.PMD; 23 import net.sourceforge.pmd.Report; 24 import net.sourceforge.pmd.Rule; 25 import net.sourceforge.pmd.RuleContext; 26 import net.sourceforge.pmd.RuleSet; 27 import net.sourceforge.pmd.RuleViolation; 28 import pmd.*; 29 import pmd.config.ConfigUtils; 30 import pmd.config.PMDOptionsSettings; 31 import java.io.Reader ; 32 import java.io.StringReader ; 33 import java.util.ArrayList ; 34 import java.util.Iterator ; 35 import javax.swing.text.*; 36 import javax.swing.event.*; 37 import java.awt.*; 38 import java.awt.event.*; 39 import javax.swing.*; 40 import java.util.List ; 41 import org.openide.cookies.SourceCookie; 42 import org.openide.explorer.view.*; 43 import org.openide.nodes.*; 44 import org.openide.ErrorManager; 45 import org.openide.loaders.DataObject; 46 import org.openide.loaders.DataObjectNotFoundException; 47 import org.openide.text.Line; 48 import org.openide.util.NbBundle; 49 import org.openide.util.Utilities; 50 import org.openide.text.DataEditorSupport; 51 52 import org.netbeans.modules.tasklist.core.TLUtils; 53 import org.netbeans.modules.tasklist.client.*; 54 import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider; 55 import org.netbeans.modules.tasklist.providers.SuggestionContext; 56 import org.openide.src.ClassElement; 57 import org.openide.src.Identifier; 58 59 70 71 72 public class ViolationProvider extends DocumentSuggestionProvider { 73 74 final private static String TYPE = "pmd-violations"; private SuggestionContext env; 76 77 public String getType() { 78 return TYPE; 79 } 80 81 private Thread last; 82 83 public List scan(SuggestionContext env) { 84 assert last == null || last == Thread.currentThread() : "Concurent access by: " + last + " and: " + Thread.currentThread(); 85 last = Thread.currentThread(); 86 try { 87 89 List tasks = null; 90 try { 91 92 SuggestionManager manager = SuggestionManager.getDefault(); 93 if (!manager.isEnabled(TYPE)) { 94 return null; 95 } 96 97 DataObject dataObject = DataObject.find(env.getFileObject()); 98 SourceCookie cookie = 99 (SourceCookie)dataObject.getCookie(SourceCookie.class); 100 101 if(cookie == null) { 103 return null; 104 } 105 106 String text = env.getCharSequence().toString(); 107 Reader reader = new StringReader (text); 108 ClassElement[] topClazzes = cookie.getSource().getClasses(); 110 if (topClazzes.length == 0) { 111 return null; 113 } 114 assert topClazzes[0] != null : cookie.getSource().getClass().getName(); 115 Identifier topClazzName = topClazzes[0].getName(); 116 assert topClazzName != null : topClazzes[0].getClass().getName(); 117 String name = topClazzName.getFullName(); 118 PMD pmd = new PMD(); 119 RuleContext ctx = new RuleContext(); 120 Report report = new Report(); 121 ctx.setReport(report); 122 ctx.setSourceCodeFilename(name); 123 124 RuleSet set = new RuleSet(); 125 List rlist = ConfigUtils.createRuleList( 126 PMDOptionsSettings.getDefault().getRules()); 127 Iterator it = rlist.iterator(); 128 while(it.hasNext()) { 129 set.addRule((Rule)it.next()); 130 } 131 try { 132 pmd.processFile(reader, set, ctx); 133 } catch (Exception e) { 134 ; } catch (Error e) { 141 ; } 144 Iterator iterator = ctx.getReport().iterator(); 145 146 Image taskIcon = Utilities.loadImage("org/netbeans/modules/tasklist/pmd/fixable.gif"); 148 if(!ctx.getReport().isEmpty()) { 149 while(iterator.hasNext()) { 150 final RuleViolation violation = (RuleViolation)iterator.next(); 151 try { 152 final Line line = TLUtils.getLineByNumber(dataObject, violation.getLine()); 154 155 157 boolean fixable = false; 158 SuggestionPerformer action = null; 159 String rulename = violation.getRule().getName(); 160 if (rulename.equals("UnusedImports") || rulename.equals("ImportFromSamePackage") || rulename.equals("DontImportJavaLang") || rulename.equals("DuplicateImports")) { fixable = true; 165 boolean comment = false; 166 action = new ImportPerformer(line, violation, comment); 167 } else if (rulename.equals("UnusedLocalVariable") && isDeleteSafe(line)) { fixable = true; 170 action = new SuggestionPerformer() { 171 public void perform(Suggestion s) { 172 TLUtils.deleteLine(line, ""); 174 } 175 public boolean hasConfirmation() { 176 return true; 177 } 178 public Object getConfirmation(Suggestion s) { 179 DataObject dao = DataEditorSupport.findDataObject(line); 180 int linenumber = line.getLineNumber(); 181 String filename = dao.getPrimaryFile().getNameExt(); 182 String ruleDesc = violation.getRule().getDescription(); 183 String ruleExample = violation.getRule().getExample(); 184 String beforeDesc = NbBundle.getMessage(ViolationProvider.class, 185 "UnusedConfirmation"); 187 StringBuffer sb = new StringBuffer (200); 188 Line l = line; 189 sb.append("<html>"); TLUtils.appendSurroundingLine(sb, l, -1); 191 sb.append("<br>"); 192 sb.append("<b><strike>"); 193 sb.append(line.getText()); 194 sb.append("</strike></b>"); 195 sb.append("<br>"); 196 TLUtils.appendSurroundingLine(sb, l, +1); 197 sb.append("</html>"); String beforeContents = sb.toString(); 199 200 return new org.netbeans.modules.tasklist.core.ConfPanel(beforeDesc, 201 beforeContents, null, null, 202 filename, linenumber, getBottomPanel(ruleDesc, ruleExample)); 203 } 204 }; 205 206 } else if (rulename.equals("UnusedPrivateField")) { fixable = true; 208 boolean comment = false; 209 action = new RemovePerformer(true, 210 line, violation, 211 comment); 212 } else if (rulename.equals("UnusedPrivateMethod")) { fixable = true; 214 boolean comment = false; 215 action = new RemovePerformer(false, 216 line, violation, 217 comment); 218 } else { 219 action = null; 220 } 221 222 SuggestionAgent s = manager.createSuggestion( 223 TYPE, 224 rulename + " : " + violation.getDescription(), 226 action, 227 this); 228 229 switch (violation.getRule().getPriority()) { 233 case 1: s.setPriority(SuggestionPriority.HIGH); break; 234 case 2: s.setPriority(SuggestionPriority.MEDIUM_HIGH); break; 235 case 3: s.setPriority(SuggestionPriority.MEDIUM); break; 236 case 4: s.setPriority(SuggestionPriority.MEDIUM_LOW); break; 237 case 5: s.setPriority(SuggestionPriority.LOW); break; 238 default: s.setPriority(SuggestionPriority.MEDIUM); break; 239 } 240 241 s.setLine(line); 242 if (fixable) { 243 s.setIcon(taskIcon); 244 } 245 if (tasks == null) { 246 tasks = new ArrayList (ctx.getReport().size()); 247 } 248 tasks.add(s.getSuggestion()); 249 } catch (Exception e) { 250 ErrorManager.getDefault().notify(e); 251 } 252 } 253 } 254 } catch (Exception e) { 255 ErrorManager.getDefault().notify(e); 256 } 257 return tasks; 258 } finally { 259 last = null; 260 } 261 } 262 263 269 private static boolean isDeleteSafe(String text) { 270 282 283 int n = text.length(); 286 boolean inString = false; 287 boolean escaped = false; 288 289 boolean comment = false; 296 297 boolean seenSemi = false; 298 boolean seenComma = false; 299 for (int i = 0; i < n; i++) { 300 char c = text.charAt(i); 301 if (comment) { 302 if ((c == '*') && (i < (n-1)) && 303 ((text.charAt(i+1) == '/'))) { 304 comment = false; 305 } else { 306 continue; 307 } 308 } else if (c == '\\') { 309 escaped = !escaped; 310 } else if (c == '"') { 311 if (!escaped) { 312 inString = !inString; 313 } 314 } else if ((c == '/') && (i < (n-1)) && 315 ((text.charAt(i+1) == '*'))) { 316 comment = true; 317 } else if (c == '(') { 318 if (!inString && !escaped) { 319 return false; 324 } 325 } else if (c == ',') { 326 if (!inString && !escaped) { 327 seenComma = true; 328 } 329 } else if (c == ';') { 330 if (!inString && !escaped) { 331 seenSemi = true; 332 } 333 } else if (Character.isWhitespace(c)) { 334 } else { 336 if (!inString && !escaped && (seenSemi || seenComma)) { 338 return false; 342 } 343 } 344 } 345 return true; 346 } 347 348 352 public static boolean isDeleteSafe(Line line) { 353 Document doc = TLUtils.getDocument(line); 354 Element elm = TLUtils.getElement(doc, line); 355 if (elm == null) { 356 return false; 357 } 358 int offset = elm.getStartOffset(); 359 int endOffset = elm.getEndOffset(); 360 361 try { 362 String text = doc.getText(offset, endOffset-offset); 363 return isDeleteSafe(text); 364 } catch (BadLocationException ex) { 365 ErrorManager.getDefault().notify(ErrorManager.WARNING, ex); 366 } 367 return false; 368 } 369 370 static JPanel getBottomPanel(String ruleDesc, String ruleExample) { 371 java.awt.GridBagConstraints gridBagConstraints; 372 javax.swing.JLabel jLabel9; 374 javax.swing.JLabel jLabel8; 375 javax.swing.JScrollPane jScrollPane2; 376 javax.swing.JTextArea descText; 377 javax.swing.JScrollPane jScrollPane1; 378 javax.swing.JPanel jPanel1; 379 javax.swing.JTextArea exampleText; 380 382 383 jPanel1 = new javax.swing.JPanel (); 384 jLabel8 = new javax.swing.JLabel (); 385 jScrollPane1 = new javax.swing.JScrollPane (); 386 descText = new javax.swing.JTextArea (); 387 jLabel9 = new javax.swing.JLabel (); 388 jScrollPane2 = new javax.swing.JScrollPane (); 389 exampleText = new javax.swing.JTextArea (); 390 391 jPanel1.setLayout(new java.awt.GridBagLayout ()); 392 393 jLabel8.setText(NbBundle.getMessage(ViolationProvider.class, "Description")); gridBagConstraints = new java.awt.GridBagConstraints (); 395 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 396 jPanel1.add(jLabel8, gridBagConstraints); 397 398 jScrollPane1.setPreferredSize(new java.awt.Dimension (200, 200)); 399 descText.setWrapStyleWord(true); 400 descText.setLineWrap(true); 401 descText.setEditable(false); 402 jScrollPane1.setViewportView(descText); 403 404 gridBagConstraints = new java.awt.GridBagConstraints (); 405 gridBagConstraints.gridx = 0; 406 gridBagConstraints.gridy = 1; 407 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 408 gridBagConstraints.weightx = 1.0; 409 gridBagConstraints.weighty = 1.0; 410 jPanel1.add(jScrollPane1, gridBagConstraints); 411 412 jLabel9.setText(NbBundle.getMessage(ViolationProvider.class, "Example")); gridBagConstraints = new java.awt.GridBagConstraints (); 414 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 415 jPanel1.add(jLabel9, gridBagConstraints); 416 417 jScrollPane2.setPreferredSize(new java.awt.Dimension (200, 200)); 418 exampleText.setEditable(false); 419 exampleText.setPreferredSize(null); 420 jScrollPane2.setViewportView(exampleText); 421 422 gridBagConstraints = new java.awt.GridBagConstraints (); 423 gridBagConstraints.gridx = 1; 424 gridBagConstraints.gridy = 1; 425 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 426 gridBagConstraints.weightx = 1.0; 427 gridBagConstraints.weighty = 1.0; 428 jPanel1.add(jScrollPane2, gridBagConstraints); 429 430 gridBagConstraints = new java.awt.GridBagConstraints (); 431 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 432 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 433 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 434 gridBagConstraints.weightx = 1.0; 435 gridBagConstraints.weighty = 1.0; 436 gridBagConstraints.insets = new java.awt.Insets (18, 12, 11, 11); 437 438 descText.setFont(jLabel8.getFont()); 440 exampleText.setFont(jLabel8.getFont()); 441 442 descText.setText(ruleDesc.trim()); 443 exampleText.setText(ruleExample.trim()); 444 445 return jPanel1; 446 } 447 448 449 private List showingTasks = null; 450 451 private Object request = null; 452 } 453 | Popular Tags |