KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > checkstyle > ViolationProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tasklist.checkstyle;
21
22 import com.puppycrawl.tools.checkstyle.Checker;
23 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
24 import com.puppycrawl.tools.checkstyle.ModuleFactory;
25 import com.puppycrawl.tools.checkstyle.PropertiesExpander;
26 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
27 import com.puppycrawl.tools.checkstyle.api.AuditListener;
28 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
29 import com.puppycrawl.tools.checkstyle.api.Configuration;
30 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
31 import java.io.BufferedOutputStream JavaDoc;
32 import java.io.File JavaDoc;
33 import java.io.FileOutputStream JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.OutputStreamWriter JavaDoc;
38 import java.io.Writer JavaDoc;
39 import java.util.List JavaDoc;
40 import javax.swing.text.Document JavaDoc;
41 import org.netbeans.modules.tasklist.checkstyle.options.CheckstyleSettings;
42 import org.netbeans.modules.tasklist.client.SuggestionAgent;
43 import org.netbeans.modules.tasklist.client.SuggestionManager;
44 import org.netbeans.modules.tasklist.client.SuggestionPerformer;
45 import org.netbeans.modules.tasklist.client.SuggestionPriority;
46
47 import org.openide.filesystems.FileUtil;
48 import org.openide.filesystems.FileObject;
49 import org.openide.ErrorManager;
50 import org.openide.loaders.DataObject;
51 import org.openide.loaders.DataObjectNotFoundException;
52 import org.openide.text.Line;
53 import org.openide.util.SharedClassObject;
54
55 import org.netbeans.modules.tasklist.core.TLUtils;
56 import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider;
57 import org.netbeans.modules.tasklist.providers.SuggestionContext;
58
59 /**
60  * This class uses the Checkstyle rule checker to provide rule violation
61  * suggestions.
62  * <p>
63  * @todo This version only operates on the disk-versions of
64  * the source files! Either get checkstyle modified to
65  * have a Reader interface, or save files to temporary buffers.
66  * @todo Add automatic fixers for some of these rules.
67  * @todo Refactor so I can share some code with the pmd bridge
68  * <p>
69  * @author <a HREF="mailto:mick@wever.org">Michael Semb Wever</a>
70  */

71
72
73 public class ViolationProvider extends DocumentSuggestionProvider
74     implements AuditListener {
75
76     /** TODO comment me **/
77     final private static String JavaDoc TYPE = "checkstyle-violations"; // NOI18N
78

79     /** **/
80     public String JavaDoc getType() {
81         return TYPE;
82     }
83
84     /** List "owned" by the scan() method and updated by the audit listener
85      * methods. */

86     private List JavaDoc tasks = null;
87     
88     /** TODO comment me **/
89     public List JavaDoc scan(final SuggestionContext env) {
90         tasks = null;
91         this.env = env;
92         final SuggestionManager manager = SuggestionManager.getDefault();
93         if (!manager.isEnabled(TYPE)) {
94             return null;
95         }
96
97         /* This code is for looking up the dynamic content of the
98            document - but see below - we don't need it yet...
99         SourceCookie cookie =
100             (SourceCookie)dobj.getCookie(SourceCookie.class);
101
102         // The file is not a java file
103         if(cookie == null) {
104             return null;
105         }
106         String text = null;
107         try {
108             int len = doc.getLength();
109             text = doc.getText(0, len);
110         } catch (BadLocationException e) {
111             ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
112             return null;
113         }
114         Reader reader = new StringReader(text);
115         //String name = cookie.getSource().getClasses()[0].getName().getFullName();
116         */

117         
118         // Checkstyle doesn't seem to have an API where I can pass in
119
// a string reader - it wants to read the files directly!
120
final FileObject fo = env.getFileObject();
121         try {
122             dataobject = DataObject.find(fo);
123         } catch (DataObjectNotFoundException e) {
124             ErrorManager.getDefault().notify(e);
125         }
126         final File JavaDoc file = (dataobject != null && !dataobject.isModified()) ? FileUtil.toFile(fo) : null;
127
128         if (file != null) {
129             try {
130                 if (callCheckstyle(file) == false) {
131                     return null;
132                 }
133             } catch (Exception JavaDoc e) {
134                 ErrorManager.getDefault().notify(e);
135                 return null;
136             }
137         } else {
138             Writer JavaDoc out = null;
139             try {
140                 final File JavaDoc tmp = File.createTempFile("tl_cs", "tmp"); // NOI18N
141
tmp.deleteOnExit();
142                 out = new OutputStreamWriter JavaDoc(new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(tmp)));
143                 final CharSequence JavaDoc chars = env.getCharSequence();
144                 for (int i = 0; i < chars.length(); i++) {
145                     out.write(chars.charAt(i));
146                 }
147                 if (callCheckstyle(file) == false) {
148                     return null;
149                 }
150                 tmp.delete();
151             } catch (IOException JavaDoc e) {
152                 ErrorManager.getDefault().notify(e);
153                 return null;
154             } finally {
155                 if (out != null) {
156                     try {
157                         out.close();
158                     } catch (IOException JavaDoc e) {
159                         ErrorManager.getDefault().notify(e);
160                     }
161                 }
162             }
163
164         }
165         return tasks;
166     }
167
168     /** TODO comment me **/
169     private boolean callCheckstyle(final File JavaDoc file) {
170         // TODO: this should only be done once, not for each scan!!!
171
try {
172             final Checker checker = new Checker();
173             ModuleFactory moduleFactory = null;
174             checker.setModuleFactory(moduleFactory);
175             Configuration config = null;
176             final Properties JavaDoc props = System.getProperties();
177             
178             final CheckstyleSettings settings
179                     = (CheckstyleSettings) SharedClassObject.findObject(CheckstyleSettings.class, true);
180
181             config = ConfigurationLoader.loadConfiguration(settings.getCheckstyle(), new PropertiesExpander(props));
182             checker.configure(config);
183             checker.addListener(this);
184             checker.process(new File JavaDoc[] {file }); // Yuck!
185
return true;
186         } catch (CheckstyleException e) {
187             ErrorManager.getDefault().notify(e);
188             return false;
189         }
190     }
191
192     // Implements AuditListener ~~~~~~~~~~~~~~~~~~~~~~~~
193

194     /**
195      * notify that the audit is about to start
196      * @param aEvt the event details
197      */

198     public void auditStarted(final AuditEvent aEvt) {
199         //System.out.println("audidStarted(" + aEvt + ")");
200
}
201
202     /**
203      * notify that the audit is finished
204      * @param aEvt the event details
205      */

206     public void auditFinished(final AuditEvent aEvt) {
207         //System.out.println("audidFinished(" + aEvt + ")");
208
}
209
210     /**
211      * notify that audit is about to start on a specific file
212      * @param aEvt the event details
213      */

214     public void fileStarted(final AuditEvent aEvt) {
215         //System.out.println("fileStarted(" + aEvt + ")");
216
}
217
218     /**
219      * notify that audit is finished on a specific file
220      * @param aEvt the event details
221      */

222     public void fileFinished(final AuditEvent aEvt) {
223         //System.out.println("fileFinished(" + aEvt + ")");
224
}
225
226     /**
227      * notify that an exception happened while performing audit
228      * @param aEvt the event details
229      * @param aThrowable details of the exception
230      */

231     public void addException(final AuditEvent aEvt, final Throwable JavaDoc aThrowable) {
232         ///System.out.println("addException(" + aEvt + "," + aThrowable + ")");
233
}
234     
235     
236     /**
237      * notify that an audit error was discovered on a specific file
238      * @param aEvt the event details
239      */

240     public void addError(AuditEvent aEvt) {
241         //System.out.println("addError(" + aEvt + ")");
242

243         try {
244             final int lineNo = Math.max(1, aEvt.getLine());
245             final Line line = TLUtils.getLineByNumber(dataobject, lineNo);
246
247             final SuggestionPerformer action = getAction(aEvt);
248             final String JavaDoc description = aEvt.getLocalizedMessage().getMessage();
249                     
250             final SuggestionManager manager = SuggestionManager.getDefault();
251
252             final SuggestionAgent s = manager.createSuggestion(
253                         env.getFileObject(),
254                         TYPE,
255                         description,
256                         action,
257                         this);
258
259             final SeverityLevel sv = aEvt.getSeverityLevel();
260             
261             if (sv != SeverityLevel.IGNORE) {
262                 
263                 if (sv == SeverityLevel.INFO) {
264                     s.setPriority(SuggestionPriority.LOW);
265                     
266                 } else if (sv == SeverityLevel.WARNING) {
267                     s.setPriority(SuggestionPriority.MEDIUM_LOW);
268                     
269                 } else if (sv == SeverityLevel.ERROR) {
270                     // Even most of the errors seem pretty tame - "line longer than
271
// 80 characters", etc. - so make these medium as well.
272
// Would be nice if Checkstyle would be more careful with
273
// the use of the ERROR level.
274
s.setPriority(SuggestionPriority.MEDIUM);
275                 }
276
277                 s.setLine(line);
278                 s.setDetails(aEvt.getLocalizedMessage().getKey());
279
280                 if (tasks == null) {
281                     tasks = new ArrayList JavaDoc(40); // initial guess
282
}
283                 tasks.add(s.getSuggestion());
284             }
285
286         } catch (Exception JavaDoc e) {
287             ErrorManager.getDefault().notify(e);
288         }
289     }
290
291     /** TODO comment me **/
292     private SuggestionPerformer getAction(
293             final AuditEvent aEvt) {
294
295         final String JavaDoc key = aEvt.getLocalizedMessage().getKey();
296         if (key != null) {
297             
298             
299             if (key.contains("trailing") // FIXME i18n me. problem is that this comes from the checkstyle.xml
300
&& key.contains("spaces")) { // and can be specified in any language with a common key.
301
return new TrailingSpacesSuggestionPerformer(env.getDocument(),aEvt.getLine());
302                 
303             } else if ("import.unused".equals(key) || "import.avoidStar".equals(key)) {
304                 return new DeleteLineSuggestionPerformer(env.getDocument(),aEvt.getLine());
305                 
306             } else if ("ws.notPreceded".equals(key) || "ws.notFollowed".equals(key)) {
307                 return new InsertStringSuggestionPerformer(env.getDocument(), aEvt.getLine(), aEvt.getColumn())
308                         .setString(" ");
309                 
310             } else if ("ws.preceded".equals(key) || "ws.followed".equals(key)) {
311                 return new DeleteSpaceSuggestionPerformer(env.getDocument(), aEvt.getLine(), aEvt.getColumn());
312                 
313             } else if ("final.parameter".equalsIgnoreCase(key)) {
314                 return new InsertStringSuggestionPerformer(env.getDocument(), aEvt.getLine(), aEvt.getColumn())
315                         .setString("final ");
316                 
317             } else if ("final.variable".equalsIgnoreCase(key)) {
318                 return new InsertFinalVariableKeywordSuggestionPerformer(env.getDocument(),aEvt.getLine(),aEvt.getColumn());
319                 
320             } else if ("javadoc.missing".equalsIgnoreCase(key)){
321                 return new InsertStringSuggestionPerformer(env.getDocument(),aEvt.getLine(),aEvt.getColumn())
322                         .setString("/** TODO comment me. **/\n ");
323                 
324             } else if ("javadoc.noperiod".equalsIgnoreCase(key)) {
325                 return new InsertStringSuggestionPerformer(env.getDocument(), aEvt.getLine(), aEvt.getColumn())
326                         .setString(".");
327                 
328             }
329
330         }
331         return null;
332     }
333     
334     
335     /** The list of tasks we're currently showing in the tasklist */
336     private List JavaDoc showingTasks = null;
337
338     /** **/
339     private SuggestionContext env;
340     /** TODO comment me **/
341     private DataObject dataobject = null;
342     /** TODO comment me **/
343     private Document JavaDoc document = null;
344     /** **/
345     private Object JavaDoc request = null;
346 }
347
348
Popular Tags