diff --git a/pmd-jedit/PMDPlugin/LICENSE.txt b/pmd-jedit/PMDPlugin/LICENSE.txt
new file mode 100644
index 0000000000..801cb60717
--- /dev/null
+++ b/pmd-jedit/PMDPlugin/LICENSE.txt
@@ -0,0 +1,2 @@
+http://cougaar.org/docman/view.php/17/58/license.html
+
diff --git a/pmd-jedit/PMDPlugin/actions.xml b/pmd-jedit/PMDPlugin/actions.xml
new file mode 100644
index 0000000000..bed3103487
--- /dev/null
+++ b/pmd-jedit/PMDPlugin/actions.xml
@@ -0,0 +1,49 @@
+
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.check(buffer, view);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkAllOpenBuffers(view);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkDirectory(view);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkDirectoryRecursively(view);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.clearErrorList();
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.cpdCurrentFile(view);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.cpdDir(view,false);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.cpdDir(view,true);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkFile(view,browser);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkFile(view,browser);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkDirectory(view, browser,false);
+
+
+ net.sourceforge.pmd.jedit.PMDJEditPlugin.checkDirectory(view, browser,true);
+
+
PMD is a Java source code analyzer - it finds unused variables, questionable design decisions, empty catch blocks, and so forth. +You can read much more about PMD here - http://pmd.sf.net/.
+There's a new 'PMD' menu item in the Plugins menu. This has several submenu options
+"Current directory" means "the directory which is displayed in the file system browser". So, for +example, if you wanted to run PMD on your whole source tree, and your top level +source directory is named "src", you would 1) double-click on the "src" directory and +then 2) select the "PMD->Check directory recursively" menu option.
+All those options put any errors into the ErrorList so you can then go jumping around your project fixing stuff. +
There's a section in the Utilities->Global Options->Plugins configuration panel that lets you pick which rule sets you want to use.
+Note that the configuration panel also contains the minimum tile size for CPD to turn up a duplicate chunk. + +
Starting 2.1, you can now add Custom Defined Rulesets with PMD plugin. Previously, if you want to use your own rulesets with the PMD plugin, you had to unjar the pmd.jar file & add your ruleset defination in the jar file & re-jar it & use it. But this procedure had to be repeated whenever a new PMD is out. But not anymore. Now you can simply point PMD plugin to your custom rulesets.xml file & drop your custom ruleset jars in either of jEdit jars directory(either system or user). Once this is done, you will be able to manipulate your Custom Rulesets just the way like the built-in ones.
+ +PMD jEdit 2.2 adds updates PMD plugin to the latest and the greatest PMD release, updates to Dynamic class loading feature of jEdit and adds PMD to jEdit's File System Browser for easy access.
+The PMD-JEdit plugin is free software released under the Apache license.
+ + \ No newline at end of file diff --git a/pmd-jedit/PMDPlugin/lib/jaxen-core-1.0-fcs.jar b/pmd-jedit/PMDPlugin/lib/jaxen-core-1.0-fcs.jar new file mode 100644 index 0000000000..86618d142e Binary files /dev/null and b/pmd-jedit/PMDPlugin/lib/jaxen-core-1.0-fcs.jar differ diff --git a/pmd-jedit/PMDPlugin/lib/saxpath-1.0-fcs.jar b/pmd-jedit/PMDPlugin/lib/saxpath-1.0-fcs.jar new file mode 100644 index 0000000000..5bb1924aa7 Binary files /dev/null and b/pmd-jedit/PMDPlugin/lib/saxpath-1.0-fcs.jar differ diff --git a/pmd-jedit/PMDPlugin/pmd.props b/pmd-jedit/PMDPlugin/pmd.props new file mode 100644 index 0000000000..6981629c85 --- /dev/null +++ b/pmd-jedit/PMDPlugin/pmd.props @@ -0,0 +1,53 @@ +# +# Plugin properties +# +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.name=PMD +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.author=Jiger Patel, Tom Copeland +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.version=2.2 +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.docs=jedit.html +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.depend.0=jdk 1.3 +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.depend.1=jedit 04.02.01.00 +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.depend.2=plugin errorlist.ErrorListPlugin 1.2 +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.jars=pmd-1.2.1.jar jaxen-core-1.0-fcs.jar saxpath-1.0-fcs.jar pmd-swingui-0.1.jar + +# +# Menu properties +# + +#New jEdit 4.2 properties +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.activate=defer + +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.menu.label=$PMD + +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.menu=pmd-check-current-buffer pmd-check-all-open-buffers pmd-check-current-directory pmd-check-current-directory-recursively pmd-clear-errorlist %pmd-cpd +pmd-cpd=cpd-currentfile cpd-dir cpd-dir-recursively + +pmd-check-current-buffer.label=Check current buffer +pmd-check-all-open-buffers.label=Check all open buffers +pmd-check-current-directory.label=Check all files in current directory +pmd-check-current-directory-recursively.label=Check directory recursively +pmd-clear-errorlist.label=Clear ErrorList +pmd-cpd.label=Detect Duplicate Code +cpd-currentfile.label=In Current File +cpd-dir.label=In Directory +cpd-dir-recursively.label=In Directory Recursively +pmd-check-file.label=Check selected file(s) +# +# Option pane properties +# + +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.option-pane=pmd +options.pmd.label=PMD +options.pmd.code=new net.sourceforge.pmd.jedit.PMDOptionPane() + +#Dockables properties. +cpd-viewer.title=Copy/Paste Detector + +#FS Browser properties + +plugin.net.sourceforge.pmd.jedit.PMDJEditPlugin.browser-menu=pmd-check-file pmd-check-current-directory pmd-check-current-directory-recursively + + + + + diff --git a/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/CPDDuplicateCodeViewer.java b/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/CPDDuplicateCodeViewer.java new file mode 100644 index 0000000000..a387014d31 --- /dev/null +++ b/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/CPDDuplicateCodeViewer.java @@ -0,0 +1,194 @@ +package net.sourceforge.pmd.jedit; + +//Imports +import org.gjt.sp.jedit.Buffer; +import org.gjt.sp.jedit.View; +import org.gjt.sp.jedit.io.VFSManager; +import org.gjt.sp.jedit.jEdit; +import org.gjt.sp.jedit.textarea.Selection; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeSelectionModel; +import java.awt.BorderLayout; +import java.util.List; +import java.util.ArrayList; +//End of Imports + +/** + * A GUI Component to display Duplicate code. + * + * @created 05 Apr 2003 + * @author Jiger Patel + * + */ + +public class CPDDuplicateCodeViewer extends JPanel +{ + JTree tree; + DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode("CPD Results",true)); + View view; + + public CPDDuplicateCodeViewer(View view) + { + this.view = view; + setLayout(new BorderLayout()); + tree = new JTree(treeModel); + tree.getSelectionModel().setSelectionMode + (TreeSelectionModel.SINGLE_TREE_SELECTION); + tree.addTreeSelectionListener(new TreeSelectionListener() + { + public void valueChanged(TreeSelectionEvent e) + { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); + if (node != null) + { + //System.out.println("Node is " + node +" class "+ node.getClass()); + if (node.isLeaf() && node instanceof Duplicate) + { + Duplicate duplicate = (Duplicate)node; + gotoDuplicate(duplicate); + //System.out.println("Got!! " + duplicate); + } + } + } + }); + + + add(new JScrollPane(tree)); + + }//End of CPDDuplicateCodeViewer constructor + + + public void refreshTree() + { + treeModel.reload(); + } + + public void gotoDuplicate(final Duplicate duplicate) + { + if(duplicate != null) + { + final Buffer buffer = jEdit.openFile(view,duplicate.getFilename()); + + VFSManager.runInAWTThread(new Runnable() + { + public void run() + { + view.setBuffer(buffer); + + int start = buffer.getLineStartOffset(duplicate.getBeginLine()); + int end = buffer.getLineEndOffset(duplicate.getEndLine()-2); + //Log.log(Log.DEBUG, this.getClass(), "Start Line "+ duplicate.getBeginLine() + " End Line "+ duplicate.getEndLine() + " Start " + start + " End "+ end); + //Since an AIOOB Exception is thrown if the end is the end of file. we do a -1 from end to fix it. + view.getTextArea().setSelection(new Selection.Range(start,end -1)); + view.getTextArea().moveCaretPosition(start); + } + }); + } + } + + public DefaultMutableTreeNode getRoot() + { + return (DefaultMutableTreeNode)treeModel.getRoot(); + } + + public void addDuplicates(Duplicates duplicates) + { + //System.out.println("Inside addDuplicates " + duplicates +" Root child count "+ treeModel.getChildCount(treeModel.getRoot())); + getRoot().add(duplicates); + //vecDuplicates.addElement(duplicates); + } + + public class Duplicates extends DefaultMutableTreeNode + { + List vecduplicate = new ArrayList(); + String message, sourcecode; + + public Duplicates(String message, String sourcecode) + { + this.message = message; + this.sourcecode = sourcecode; + } + + public String getSourceCode() + { + return sourcecode; + } + + public void addDuplicate(Duplicate duplicate) + { + add(duplicate); + //vecduplicate.addElement(duplicate); + } + + public String toString() + { + return message; + } + } + + public class Duplicate extends DefaultMutableTreeNode + { + private String filename; + private int beginLine, endLine; + + public Duplicate(String filename,int beginLine, int endLine) + { + this.filename = filename; + this.beginLine = beginLine; + this.endLine = endLine; + } + + public String getFilename() + { + return filename; + } + + public int getBeginLine() + { + return beginLine; + } + + public int getEndLine() + { + return endLine; + } + + public String toString() + { + return filename + ":"+ getBeginLine()+"-"+getEndLine(); + } + } + + public void expandAll() + { + int row = 0; + while (row < tree.getRowCount()) + { + tree.expandRow(row); + row++; + } + } + + public void collapseAll() + { + int row = tree.getRowCount() - 1; + while (row >= 0) { + tree.collapseRow(row); + row--; + } + } + + public void clearDuplicates() + { + getRoot().removeAllChildren(); + } + +}//End of class CPDDuplicateCodeViewer + diff --git a/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/PMDJEditPlugin.java b/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/PMDJEditPlugin.java new file mode 100644 index 0000000000..e953800761 --- /dev/null +++ b/pmd-jedit/PMDPlugin/src/net/sourceforge/pmd/jedit/PMDJEditPlugin.java @@ -0,0 +1,434 @@ +/* + * User: tom + * Date: Jul 3, 2002 + * Time: 2:33:24 PM + */ +package net.sourceforge.pmd.jedit; + +import errorlist.*; +import net.sourceforge.pmd.*; +import net.sourceforge.pmd.cpd.*; +import org.gjt.sp.jedit.*; +import org.gjt.sp.jedit.browser.*; +import org.gjt.sp.jedit.io.*; + +import javax.swing.*; +import java.io.*; +import java.util.*; +import org.gjt.sp.jedit.msg.*; + + +public class PMDJEditPlugin extends EBPlugin { + + public static final String NAME = "PMD"; + public static final String OPTION_RULES_PREFIX = "options.pmd.rules."; + public static final String OPTION_UI_DIRECTORY_POPUP = "options.pmd.ui.directorypopup"; + public static final String DEFAULT_TILE_MINSIZE_PROPERTY = "pmd.cpd.defMinTileSize"; + public static final String RUN_PMD_ON_SAVE = "pmd.runPMDOnSave"; + public static final String CUSTOM_RULES_PATH_KEY = "pmd.customRulesPath"; + //private static RE re = new UncheckedRE("Starting at line ([0-9]*) of (\\S*)"); + + private static PMDJEditPlugin instance; + + static { + instance = new PMDJEditPlugin(); + instance.start(); + } + + private DefaultErrorSource errorSource; + + // boilerplate JEdit code + public void start() { + errorSource = new DefaultErrorSource(NAME); + ErrorSource.registerErrorSource(errorSource); + } + +/* public void createMenuItems(Vector menuItems) { + menuItems.addElement(GUIUtilities.loadMenu("pmd-menu")); + } + + public void createOptionPanes(OptionsDialog optionsDialog) { + optionsDialog.addOptionPane(new PMDOptionPane()); + } */ + // boilerplate JEdit code + + public static void checkDirectory(View view) { + instance.instanceCheckDirectory(view); + } + + public void instanceCheckDirectory(View view) { + if (jEdit.getBooleanProperty(PMDJEditPlugin.OPTION_UI_DIRECTORY_POPUP)) + { + String dir = JOptionPane.showInputDialog(jEdit.getFirstView(), "Please type in a directory to scan", NAME, JOptionPane.QUESTION_MESSAGE); + if (dir != null) + { + if (!(new File(dir)).exists() || !(new File(dir)).isDirectory() ) + { + JOptionPane.showMessageDialog(jEdit.getFirstView(), dir + " is not a valid directory name", NAME, JOptionPane.ERROR_MESSAGE); + return; + } + process(findFiles(dir, false)); + } + } + else + { + VFSBrowser browser = (VFSBrowser)view.getDockableWindowManager().getDockable("vfs.browser"); + if(browser == null) { + JOptionPane.showMessageDialog(jEdit.getFirstView(), "Can't run PMD on a directory unless the file browser is open", NAME, JOptionPane.ERROR_MESSAGE); + return; + } + process(findFiles(browser.getDirectory(), false)); + } + } + + public void handleMessage(EBMessage ebmess) + { + if (ebmess instanceof BufferUpdate) + { + if(jEdit.getBooleanProperty(PMDJEditPlugin.RUN_PMD_ON_SAVE)) + { + BufferUpdate bu = (BufferUpdate)ebmess; + if (bu.getWhat() == BufferUpdate.SAVED) + { + instance.check(bu.getBuffer(),bu.getView()); + } + } + } + } + + // check all open buffers + public static void checkAllOpenBuffers(View view) { + instance.instanceCheckAllOpenBuffers(view); + } + + public void instanceCheckAllOpenBuffers(View view) { + // I'm putting the files in a Set to work around some + // odd behavior in jEdit - the buffer.getNext() + // seems to iterate over the files twice. + Buffer buffers[] = jEdit.getBuffers(); + + if(buffers != null) + { + for (int i=0; i