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:
Radim Kubacki
2006-03-16 09:13:28 +00:00
parent 2a3b617b1a
commit a7a9fc55c9
8 changed files with 155 additions and 172 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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 ());
}
}

View File

@ -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()) {

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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());
}