forked from phoedos/pmd
removing module install class and larger rewrite of automatic scanning (mostly to address http://www.netbeans.org/issues/show_bug.cgi?id=72766)
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4300 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -2,7 +2,6 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module-Specification-Version: 1.5.1
|
||||
Created-By: Ole-Martin Mørk and Gunnlaugur Þór Briem and Radim Kubacki
|
||||
OpenIDE-Module: pmd
|
||||
OpenIDE-Module-Install: pmd/PMDInstall.class
|
||||
OpenIDE-Module-Layer: pmd/mf-layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: pmd/Bundle.properties
|
||||
OpenIDE-Module-Requires:
|
||||
|
@ -1,3 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2003, the pmd-netbeans team
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
package pmd;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
@ -1,20 +0,0 @@
|
||||
package pmd;
|
||||
|
||||
import org.openide.modules.ModuleInstall;
|
||||
|
||||
/** Extends default set of rules avaliable in PMD.
|
||||
*
|
||||
* @author Radim Kubacki
|
||||
*/
|
||||
public class PMDInstall extends ModuleInstall {
|
||||
|
||||
/** Adds custom RuleSetFactory when IDE is started. */
|
||||
public void restored () {
|
||||
pmd.config.ConfigUtils.addRuleSetFactory (NbRuleSetFactory.getDefault ());
|
||||
}
|
||||
|
||||
/** Unregisters RuleSetFactory. */
|
||||
public void uninstalled () {
|
||||
pmd.config.ConfigUtils.removeRuleSetFactory (NbRuleSetFactory.getDefault ());
|
||||
}
|
||||
}
|
@ -158,7 +158,7 @@ public class RunPMDAction extends CookieAction {
|
||||
* @return the list of rule violations found in the run, not null. Elements are instanceof {@link Fault}.
|
||||
* @throws IOException on failure to read one of the files or to write to the output window.
|
||||
*/
|
||||
public static List checkCookies( List/*<DataObject>*/ dataobjects ) throws IOException {
|
||||
public static List/*<Fault>*/ performScan( List/*<DataObject>*/ dataobjects ) throws IOException {
|
||||
assert dataobjects != null: "Cannot pass null to RunPMDAction.checkCookies()";
|
||||
SourceLevelQuery sourceLevelQuery =
|
||||
(SourceLevelQuery) Lookup.getDefault().lookup(SourceLevelQuery.class);
|
||||
@ -166,7 +166,7 @@ public class RunPMDAction extends CookieAction {
|
||||
PMD pmd_1_3 = null;
|
||||
PMD pmd_1_4 = null;
|
||||
PMD pmd_1_5 = null;
|
||||
ArrayList list = new ArrayList( 100 );
|
||||
ArrayList/*<Fault>*/ list = new ArrayList( 100 );
|
||||
|
||||
CancelCallback cancel = new CancelCallback();
|
||||
ProgressHandle prgHdl = ProgressHandleFactory.createHandle("PMD check", cancel); // PENDING action to show output
|
||||
@ -274,7 +274,7 @@ public class RunPMDAction extends CookieAction {
|
||||
try {
|
||||
StatusDisplayer.getDefault().setStatusText("PMD checking for rule violations");
|
||||
List list = getDataObjects(node);
|
||||
List violations = checkCookies(list);
|
||||
List violations = performScan(list);
|
||||
IOProvider ioProvider = (IOProvider)Lookup.getDefault().lookup(IOProvider.class);
|
||||
InputOutput output = ioProvider.getIO("PMD output", false);
|
||||
if(violations.isEmpty()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2003, the pmd-netbeans team
|
||||
* Copyright (c) 2002-2006, the pmd-netbeans team
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -38,6 +38,7 @@ import net.sourceforge.pmd.RuleSet;
|
||||
import net.sourceforge.pmd.RuleSetFactory;
|
||||
import net.sourceforge.pmd.RuleSetNotFoundException;
|
||||
import org.openide.ErrorManager;
|
||||
import pmd.NbRuleSetFactory;
|
||||
import pmd.config.ui.RuleComparator;
|
||||
import pmd.custom.RuleClassLoader;
|
||||
|
||||
@ -46,34 +47,34 @@ import pmd.custom.RuleClassLoader;
|
||||
*/
|
||||
public abstract class ConfigUtils {
|
||||
|
||||
/**
|
||||
* Extra ruleset factories added by calling {@link #addRuleSetFactory}.
|
||||
* May be null (equivalent to empty).
|
||||
*/
|
||||
private static ArrayList extraFactories = null;
|
||||
/**
|
||||
* Extra ruleset factories added by calling {@link #addRuleSetFactory}.
|
||||
* May be null (equivalent to empty).
|
||||
*/
|
||||
private static ArrayList extraFactories;
|
||||
|
||||
/**
|
||||
* Registers extra rules that are available.
|
||||
*
|
||||
* @param rules Collection of Rule objects.
|
||||
*/
|
||||
public static synchronized void addRuleSetFactory(RuleSetFactory fact) {
|
||||
if (extraFactories == null) {
|
||||
extraFactories = new ArrayList();
|
||||
}
|
||||
extraFactories.add(fact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters extra rules previously registered.
|
||||
*
|
||||
* @param rules Collection of Rule objects.
|
||||
*/
|
||||
public static synchronized void removeRuleSetFactory(RuleSetFactory fact) {
|
||||
if (extraFactories != null) {
|
||||
extraFactories.remove(fact);
|
||||
}
|
||||
}
|
||||
static {
|
||||
extraFactories = new ArrayList();
|
||||
extraFactories.add(NbRuleSetFactory.getDefault ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers extra rules that are available.
|
||||
*
|
||||
* @param rules Collection of Rule objects.
|
||||
*/
|
||||
public static synchronized void addRuleSetFactory(RuleSetFactory fact) {
|
||||
extraFactories.add(fact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters extra rules previously registered.
|
||||
*
|
||||
* @param rules Collection of Rule objects.
|
||||
*/
|
||||
public static synchronized void removeRuleSetFactory(RuleSetFactory fact) {
|
||||
extraFactories.remove(fact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the list of rules to use. This is done by iterating over all
|
||||
|
@ -62,7 +62,7 @@ public class EditorChangeListener implements PropertyChangeListener {
|
||||
// settings changed, so chuck out current scanner if any.
|
||||
if(scanner != null) {
|
||||
tracelog("Stopping scanner " + scanner + " because of changed PMD settings");
|
||||
scanner.stopThread();
|
||||
scanner.cancel();
|
||||
scanner = null;
|
||||
currentlyScannedNode = null;
|
||||
}
|
||||
@ -99,14 +99,11 @@ public class EditorChangeListener implements PropertyChangeListener {
|
||||
}
|
||||
// not the same one, so we replace the scanner.
|
||||
tracelog(" Stopping scanner " + scanner);
|
||||
scanner.stopThread();
|
||||
scanner.cancel();
|
||||
}
|
||||
scanner = new Scanner( node );
|
||||
tracelog(" Starting scanner " + scanner);
|
||||
Thread thread = new Thread( scanner );
|
||||
thread.setPriority( Thread.MIN_PRIORITY );
|
||||
this.currentlyScannedNode = node;
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void tracelog(String str) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2003, the pmd-netbeans team
|
||||
* Copyright (c) 2002-2006, the pmd-netbeans team
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -44,6 +44,7 @@ import org.openide.cookies.LineCookie;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.text.Line;
|
||||
import org.openide.text.Line.Part;
|
||||
import org.openide.util.RequestProcessor;
|
||||
import pmd.Fault;
|
||||
import pmd.RunPMDAction;
|
||||
import pmd.config.PMDOptionsSettings;
|
||||
@ -53,114 +54,93 @@ import pmd.config.PMDOptionsSettings;
|
||||
*/
|
||||
public class Scanner implements Runnable, DocumentListener, PropertyChangeListener {
|
||||
|
||||
private final Node node;
|
||||
private boolean running = true;
|
||||
private StyledDocument subscribedDoc = null;
|
||||
private EditorCookie.Observable subscribedObservable = null;
|
||||
|
||||
/**
|
||||
* If this is -1, scan constantly. Else, scan only when this has changed.
|
||||
*/
|
||||
private int modCount;
|
||||
|
||||
/** Creates a new instance of Scanner */
|
||||
public Scanner( Node node ) {
|
||||
this.node = node;
|
||||
EditorCookie edtCookie = (EditorCookie)node.getCookie(EditorCookie.class);
|
||||
if(edtCookie != null) {
|
||||
StyledDocument doc = edtCookie.getDocument();
|
||||
if(doc != null) {
|
||||
doc.removeDocumentListener(this); // prevent duplicate listener registration
|
||||
doc.addDocumentListener(this);
|
||||
subscribedDoc = doc;
|
||||
} // else document has probably been unloaded because the editor window was closed.
|
||||
EditorCookie.Observable obs = (EditorCookie.Observable)node.getCookie(EditorCookie.Observable.class);
|
||||
if(obs != null) {
|
||||
obs.removePropertyChangeListener(this); // prevent duplicate listener registration
|
||||
obs.addPropertyChangeListener(this);
|
||||
subscribedObservable = obs;
|
||||
}
|
||||
modCount = 0;
|
||||
} else {
|
||||
modCount = -1;
|
||||
}
|
||||
|
||||
}
|
||||
private static RequestProcessor PMD_RP = new RequestProcessor("PMD scanner", 1);
|
||||
|
||||
private final Node node;
|
||||
private boolean running = true;
|
||||
private StyledDocument subscribedDoc = null;
|
||||
private EditorCookie.Observable subscribedObservable = null;
|
||||
|
||||
private RequestProcessor.Task task;
|
||||
|
||||
/** Creates a new instance of Scanner.
|
||||
* This is created from EditorChangeListener only.
|
||||
*/
|
||||
Scanner( Node node ) {
|
||||
this.node = node;
|
||||
EditorCookie edtCookie = (EditorCookie)node.getCookie(EditorCookie.class);
|
||||
if(edtCookie != null) {
|
||||
StyledDocument doc = edtCookie.getDocument();
|
||||
if(doc != null) {
|
||||
doc.removeDocumentListener(this); // prevent duplicate listener registration
|
||||
doc.addDocumentListener(this);
|
||||
subscribedDoc = doc;
|
||||
} // else document has probably been unloaded because the editor window was closed.
|
||||
EditorCookie.Observable obs = (EditorCookie.Observable)node.getCookie(EditorCookie.Observable.class);
|
||||
if(obs != null) {
|
||||
obs.removePropertyChangeListener(this); // prevent duplicate listener registration
|
||||
obs.addPropertyChangeListener(this);
|
||||
subscribedObservable = obs;
|
||||
}
|
||||
}
|
||||
|
||||
task = PMD_RP.post(this, PMDOptionsSettings.getDefault().getScanInterval().intValue() * 1000, Thread.MIN_PRIORITY);
|
||||
}
|
||||
|
||||
public StyledDocument getSubscribedDocument() {
|
||||
return subscribedDoc;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
tracelog("started");
|
||||
while( running ) {
|
||||
|
||||
int tabSize = 8;
|
||||
Integer foo = (Integer) Settings.getValue(JavaKit.class, SettingsNames.TAB_SIZE);
|
||||
if (foo != null)
|
||||
tabSize = foo.intValue();
|
||||
|
||||
int lastModCount = modCount;
|
||||
tracelog("run starting at modcount: " + lastModCount);
|
||||
DataObject object = ( DataObject )node.getCookie( DataObject.class ) ;
|
||||
LineCookie cookie = ( LineCookie )object.getCookie( LineCookie.class );
|
||||
Line.Set lineset = cookie.getLineSet();
|
||||
List list = Collections.singletonList(object);
|
||||
List faults = RunPMDAction.checkCookies(list );
|
||||
PMDScanAnnotation.clearAll();
|
||||
for( int i = 0; i < faults.size(); i++ ) {
|
||||
Fault fault = (Fault)faults.get( i );
|
||||
int lineNum = fault.getLine();
|
||||
Line line = lineset.getCurrent( lineNum - 1 );
|
||||
if(line == null)
|
||||
{
|
||||
tracelog("no original line found for line " + lineNum + " in lineset; probably document closed" );
|
||||
}
|
||||
else
|
||||
{
|
||||
tracelog("Line class : " + line.getClass().getName());
|
||||
tracelog("Node: " + node + ", count: " + line.getAnnotationCount() );
|
||||
|
||||
String text = line.getText();
|
||||
if (text != null) {
|
||||
int firstNonWhiteSpaceCharIndex = findFirstNonWhiteSpaceCharIndex(text);
|
||||
if (firstNonWhiteSpaceCharIndex == -1)
|
||||
continue;
|
||||
int lastNonWhiteSpaceCharIndex = findLastNonWhiteSpaceCharIndex(text);
|
||||
String initialWhiteSpace = text.substring(0, firstNonWhiteSpaceCharIndex);
|
||||
String content = text.substring(firstNonWhiteSpaceCharIndex, lastNonWhiteSpaceCharIndex + 1);
|
||||
int start = expandedLength(0, initialWhiteSpace, tabSize);
|
||||
int length = expandedLength(start, content, tabSize);
|
||||
public void run() {
|
||||
try {
|
||||
tracelog("started");
|
||||
|
||||
int tabSize = 8;
|
||||
Integer foo = (Integer) Settings.getValue(JavaKit.class, SettingsNames.TAB_SIZE);
|
||||
if (foo != null)
|
||||
tabSize = foo.intValue();
|
||||
|
||||
Part part = line.createPart(start, length);
|
||||
DataObject object = ( DataObject )node.getCookie( DataObject.class ) ;
|
||||
LineCookie cookie = ( LineCookie )object.getCookie( LineCookie.class );
|
||||
Line.Set lineset = cookie.getLineSet();
|
||||
List list = Collections.singletonList(object);
|
||||
List faults = RunPMDAction.performScan(list );
|
||||
PMDScanAnnotation.clearAll();
|
||||
for( int i = 0; i < faults.size(); i++ ) {
|
||||
Fault fault = (Fault)faults.get( i );
|
||||
int lineNum = fault.getLine();
|
||||
Line line = lineset.getCurrent( lineNum - 1 );
|
||||
if(line == null) {
|
||||
tracelog("no original line found for line " + lineNum + " in lineset; probably document closed" );
|
||||
} else {
|
||||
tracelog("Line class : " + line.getClass().getName());
|
||||
tracelog("Node: " + node + ", count: " + line.getAnnotationCount() );
|
||||
|
||||
PMDScanAnnotation annotation = PMDScanAnnotation.getNewInstance();
|
||||
String msg = fault.getMessage();
|
||||
annotation.setErrorMessage( msg );
|
||||
annotation.attach( part );
|
||||
part.addPropertyChangeListener( annotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
tracelog("run finished at modcount: " + lastModCount);
|
||||
do {
|
||||
try {
|
||||
Thread.sleep( PMDOptionsSettings.getDefault().getScanInterval().intValue() * 1000 );
|
||||
}
|
||||
catch( InterruptedException e ) {
|
||||
ErrorManager.getDefault().notify(e);
|
||||
}
|
||||
} while(running && modCount != -1 && modCount == lastModCount);
|
||||
}
|
||||
}
|
||||
catch( IOException e ) {
|
||||
ErrorManager.getDefault().notify(e);
|
||||
}
|
||||
finally {
|
||||
tracelog("stopped");
|
||||
}
|
||||
}
|
||||
String text = line.getText();
|
||||
if (text != null) {
|
||||
int firstNonWhiteSpaceCharIndex = findFirstNonWhiteSpaceCharIndex(text);
|
||||
if (firstNonWhiteSpaceCharIndex == -1)
|
||||
continue;
|
||||
int lastNonWhiteSpaceCharIndex = findLastNonWhiteSpaceCharIndex(text);
|
||||
String initialWhiteSpace = text.substring(0, firstNonWhiteSpaceCharIndex);
|
||||
String content = text.substring(firstNonWhiteSpaceCharIndex, lastNonWhiteSpaceCharIndex + 1);
|
||||
int start = expandedLength(0, initialWhiteSpace, tabSize);
|
||||
int length = expandedLength(start, content, tabSize);
|
||||
|
||||
Part part = line.createPart(start, length);
|
||||
|
||||
PMDScanAnnotation annotation = PMDScanAnnotation.getNewInstance();
|
||||
String msg = fault.getMessage();
|
||||
annotation.setErrorMessage( msg );
|
||||
annotation.attach( part );
|
||||
part.addPropertyChangeListener( annotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch( IOException e ) {
|
||||
ErrorManager.getDefault().notify(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int findFirstNonWhiteSpaceCharIndex(String text) {
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
@ -200,8 +180,9 @@ public class Scanner implements Runnable, DocumentListener, PropertyChangeListen
|
||||
return length;
|
||||
}
|
||||
|
||||
public void stopThread() {
|
||||
running = false;
|
||||
public void cancel() {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -213,11 +194,15 @@ public class Scanner implements Runnable, DocumentListener, PropertyChangeListen
|
||||
}
|
||||
|
||||
public void insertUpdate(DocumentEvent evt) {
|
||||
incrementModCount();
|
||||
if (task != null) {
|
||||
task.schedule(PMDOptionsSettings.getDefault().getScanInterval().intValue() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent evt) {
|
||||
incrementModCount();
|
||||
if (task != null) {
|
||||
task.schedule(PMDOptionsSettings.getDefault().getScanInterval().intValue() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
@ -230,8 +215,7 @@ public class Scanner implements Runnable, DocumentListener, PropertyChangeListen
|
||||
StyledDocument doc = cookie.getDocument();
|
||||
if(doc == null) {
|
||||
// stop the scanner thread -- this document has ben closed.
|
||||
running = false;
|
||||
incrementModCount();
|
||||
cancel();
|
||||
} else {
|
||||
doc.removeDocumentListener(this);
|
||||
doc.addDocumentListener(this);
|
||||
@ -252,10 +236,6 @@ public class Scanner implements Runnable, DocumentListener, PropertyChangeListen
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void incrementModCount() {
|
||||
modCount++;
|
||||
}
|
||||
|
||||
private void tracelog(String str) {
|
||||
if(RunPMDAction.TRACE_LOGGING) {
|
||||
ErrorManager.getDefault().log(ErrorManager.ERROR, this.toString() + ": " + str);
|
||||
|
@ -77,7 +77,7 @@ public class RunPMDActionTest extends NbTestCase {
|
||||
|
||||
// try on empty list
|
||||
|
||||
result = pmd.RunPMDAction.checkCookies(Collections.EMPTY_LIST);
|
||||
result = pmd.RunPMDAction.performScan(Collections.EMPTY_LIST);
|
||||
// assertEquals(expResult, result);
|
||||
|
||||
FileObject dir = FileUtil.toFileObject(getWorkDir());
|
||||
@ -87,7 +87,7 @@ public class RunPMDActionTest extends NbTestCase {
|
||||
assertNotNull("Cannot create file in work dir", f1);
|
||||
DataObject d1 = DataObject.find(f1);
|
||||
assertNotNull("Cannot find a data object", d1);
|
||||
result = pmd.RunPMDAction.checkCookies(Collections.singletonList(d1));
|
||||
result = pmd.RunPMDAction.performScan(Collections.singletonList(d1));
|
||||
assertEquals("There should be no error for MANIFEST.MF file", 0, result.size());
|
||||
|
||||
f1 = dir.createData("PMDSample.java");
|
||||
@ -106,7 +106,7 @@ public class RunPMDActionTest extends NbTestCase {
|
||||
}
|
||||
d1 = DataObject.find(f1);
|
||||
assertNotNull("Cannot find a data object", d1);
|
||||
result = pmd.RunPMDAction.checkCookies(Collections.singletonList(d1));
|
||||
result = pmd.RunPMDAction.performScan(Collections.singletonList(d1));
|
||||
assertEquals("There should be no error for PMDSample.java file", 0, result.size());
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user