diff --git a/pmd-jdeveloper/etc/Manifest.mf b/pmd-jdeveloper/etc/Manifest.mf
new file mode 100644
index 0000000000..01d15e37b4
--- /dev/null
+++ b/pmd-jdeveloper/etc/Manifest.mf
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Created-By: Apache Ant 1.5.1
+AddinCount: 1
+Addin0: net.sourceforge.pmd.jdeveloper.Plugin
+
+Name: net/sourceforge/pmd/jdeveloper/
+Specification-Title: PMD Static Code Analyzer
+Specification-Version: 0.1
+Specification-Vendor: Tom Copeland
+Implementation-Title: net.sourceforge.pmd.jdeveloper
+Implementation-Version: 0.1
+Implementation-Vendor: Tom Copeland
+Implementation-URL: http://pmd.sf.net/
\ No newline at end of file
diff --git a/pmd-jdeveloper/etc/build.xml b/pmd-jdeveloper/etc/build.xml
new file mode 100644
index 0000000000..7ab70abb5e
--- /dev/null
+++ b/pmd-jdeveloper/etc/build.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pmd-jdeveloper/etc/changelog.txt b/pmd-jdeveloper/etc/changelog.txt
new file mode 100644
index 0000000000..3f72f00665
--- /dev/null
+++ b/pmd-jdeveloper/etc/changelog.txt
@@ -0,0 +1,2 @@
+??? - 0.1:
+Initial release
diff --git a/pmd-jdeveloper/etc/doing_the_next_pmd_jdeveloper_release.txt b/pmd-jdeveloper/etc/doing_the_next_pmd_jdeveloper_release.txt
new file mode 100644
index 0000000000..7bdce12f24
--- /dev/null
+++ b/pmd-jdeveloper/etc/doing_the_next_pmd_jdeveloper_release.txt
@@ -0,0 +1,39 @@
+update the release date in the changelog
+change config/pmd.props to reflect actual pmd.jar file version
+change config/pmd.props to reflect pmd-jedit release 1.4
+change config/jedit.html to reflect pmd-jedit release 1.4
+change the build.xml to reflect pmd-jedit release 1.4
+
+Create the binary release:
+ant release
+move the zip file into c:\tmp
+TESTS:
+1) Can you run jedit ok?
+2) Can you run it it on a file and find some unused code?
+3) Are options persistant?
+
+Create the src release:
+cvs -q rtag -D tomorrow "pmd_jedit_release_1_4" pmd-jedit
+rmdir /q /s c:\tmp\pmd-jedit
+mkdir c:\tmp\pmd-jedit
+cvs -q export -d c:\tmp\pmd-jedit -r pmd_jedit_release_1_4 pmd-jedit
+copy pmd-jedit\lib\PMDJEditPlugin-1.4.jar c:\tmp\pmd-jedit\lib
+cd c:\tmp
+"c:\program files\winzip\wzzip.exe" -r -p pmd-jedit-src-1.4.zip pmd-jedit
+rmdir /q /s pmd-jedit
+
+FTP the zip file to SF
+ftp upload.sourceforge.net
+generic userid/password: anonymous/tom@infoether.com
+cd incoming
+bin
+put pmd-jedit-src-1.4.zip
+put pmd-jedit-bin-1.4.zip
+
+Go to Admin, Edit/Release Files, click on Add new release
+Paste stuff into the changelog/readme boxes
+Add the pmd-jedit-src-1.4.zip file
+Add the pmd-jedit-bin-1.4.zip file
+Classify the file
+
+Submit some news saying "hey, new release of the JEdit plugin!"
diff --git a/pmd-jdeveloper/etc/scp.bat b/pmd-jdeveloper/etc/scp.bat
new file mode 100755
index 0000000000..946fc5684a
--- /dev/null
+++ b/pmd-jdeveloper/etc/scp.bat
@@ -0,0 +1,6 @@
+@echo off
+set CLASSPATH=..\build
+set CLASSPATH=%CLASSPATH%;..\lib\ErrorList.jar
+set CLASSPATH=%CLASSPATH%;..\lib\jedit.jar
+set CVS_RSH=c:\bin\ssh\ssh
+set HOME=c:
diff --git a/pmd-jdeveloper/lib/jdeveloper.jar b/pmd-jdeveloper/lib/jdeveloper.jar
new file mode 100644
index 0000000000..7c8284ae1e
Binary files /dev/null and b/pmd-jdeveloper/lib/jdeveloper.jar differ
diff --git a/pmd-jdeveloper/lib/pmd-1.03.jar b/pmd-jdeveloper/lib/pmd-1.03.jar
new file mode 100644
index 0000000000..108b904859
Binary files /dev/null and b/pmd-jdeveloper/lib/pmd-1.03.jar differ
diff --git a/pmd-jdeveloper/lib/pmd-jdeveloper-0.1.jar b/pmd-jdeveloper/lib/pmd-jdeveloper-0.1.jar
new file mode 100644
index 0000000000..3a2e63d377
Binary files /dev/null and b/pmd-jdeveloper/lib/pmd-jdeveloper-0.1.jar differ
diff --git a/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/JDeveloperRuleSetFactory.java b/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/JDeveloperRuleSetFactory.java
new file mode 100644
index 0000000000..3ac97af63e
--- /dev/null
+++ b/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/JDeveloperRuleSetFactory.java
@@ -0,0 +1,75 @@
+package net.sourceforge.pmd.jdeveloper;
+
+import net.sourceforge.pmd.ExternalRuleID;
+import net.sourceforge.pmd.Rule;
+import net.sourceforge.pmd.RuleSet;
+import net.sourceforge.pmd.RuleSetFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.InputStream;
+
+public class JDeveloperRuleSetFactory extends RuleSetFactory {
+
+ public RuleSet createRuleSet(InputStream inputStream) {
+ try {
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ org.w3c.dom.Document doc = builder.parse(inputStream);
+ org.w3c.dom.Element root = doc.getDocumentElement();
+
+ RuleSet ruleSet = new RuleSet();
+ ruleSet.setName(root.getAttribute("name"));
+ ruleSet.setDescription(root.getChildNodes().item(1).getFirstChild().getNodeValue());
+
+ NodeList rules = root.getElementsByTagName("rule");
+ for (int i =0; i JCheckBox
+ private Map rules = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ Rule r1 = (Rule)o1;
+ Rule r2 = (Rule)o2;
+ return r1.getName().compareTo(r2.getName());
+ }
+ });
+
+ public SelectedRules() throws RuleSetNotFoundException {
+ RuleSetFactory rsf = new JDeveloperRuleSetFactory();
+ for (Iterator i = rsf.getRegisteredRuleSets(); i.hasNext();) {
+ RuleSet rs = (RuleSet)i.next();
+ for (Iterator j = rs.getRules().iterator(); j.hasNext();) {
+ Rule rule = (Rule)j.next();
+ rules.put(rule, createCheckBox(rule.getName()));
+ }
+ }
+ }
+
+ public int size() {
+ return rules.size();
+ }
+
+ public Rule getRule(JCheckBox candidate) {
+ for (Iterator i = rules.keySet().iterator(); i.hasNext();) {
+ Rule rule = (Rule)i.next();
+ JCheckBox box = (JCheckBox)rules.get(rule);
+ if (box.equals(candidate)) {
+ return rule;
+ }
+ }
+ throw new RuntimeException("Couldn't find a rule that mapped to the passed in JCheckBox " + candidate);
+ }
+
+ public JCheckBox get(Object key) {
+ return (JCheckBox)rules.get(key);
+ }
+
+ public Object[] getAllBoxes() {
+ Object[] foo = new Object[rules.size()];
+ int idx = 0;
+ for (Iterator i = rules.values().iterator(); i.hasNext();) {
+ foo[idx] = i.next();
+ idx++;
+ }
+ return foo;
+ }
+
+ public void save() {
+ for (Iterator i = rules.keySet().iterator(); i.hasNext();) {
+ Rule rule = (Rule)i.next();
+ Ide.setProperty("pmd.rule." + rule.getName(), String.valueOf(get(rule).isSelected()));
+ }
+ }
+
+ public RuleSet getSelectedRules() {
+ RuleSet newRuleSet = new RuleSet();
+ for (Iterator i = rules.keySet().iterator(); i.hasNext();) {
+ Rule rule = (Rule)i.next();
+ if (get(rule).isSelected()) {
+ newRuleSet.addRule(rule);
+ }
+ }
+ return newRuleSet;
+ }
+
+ private JCheckBox createCheckBox(String name) {
+ JCheckBox box = new JCheckBox(name);
+ box.setSelected(Boolean.valueOf(Ide.getProperty("pmd.rule." + name)).booleanValue());
+ return box;
+ }
+
+}
diff --git a/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/SettingsPanel.java b/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/SettingsPanel.java
new file mode 100644
index 0000000000..3db0db8d9e
--- /dev/null
+++ b/pmd-jdeveloper/src/net/sourceforge/pmd/jdeveloper/SettingsPanel.java
@@ -0,0 +1,102 @@
+package net.sourceforge.pmd.jdeveloper;
+
+import net.sourceforge.pmd.RuleSetNotFoundException;
+import oracle.ide.panels.DefaultTraversablePanel;
+import oracle.ide.panels.TraversableContext;
+
+import javax.swing.BorderFactory;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
+import javax.swing.UIManager;
+import javax.swing.border.EmptyBorder;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+public class SettingsPanel extends DefaultTraversablePanel {
+
+ public class CheckboxList extends JList {
+
+ private class MyMouseAdapter extends MouseAdapter {
+ public void mouseEntered(MouseEvent e) {
+ int index = locationToIndex(e.getPoint());
+ if (index != -1) {
+ JCheckBox box = (JCheckBox)getModel().getElementAt(index);
+ String example = rules.getRule(box).getExample();
+ exampleTextArea.setText(example);
+ exampleTextArea.setCaretPosition(0);
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {
+ int index = locationToIndex(e.getPoint());
+ if (index != -1) {
+ JCheckBox box = (JCheckBox)getModel().getElementAt(index);
+ box.setSelected(!box.isSelected());
+ repaint();
+ }
+ }
+ }
+
+ public class CheckboxListCellRenderer implements ListCellRenderer {
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ JCheckBox box = (JCheckBox)value;
+ box.setEnabled(isEnabled());
+ box.setFont(getFont());
+ box.setFocusPainted(false);
+ box.setBorderPainted(true);
+ box.setBorder(isSelected ? UIManager.getBorder("List.focusCellHighlightBorder") : new EmptyBorder(1,1,1,1));
+ return box;
+ }
+ }
+
+ public CheckboxList(Object[] args) {
+ super(args);
+ setCellRenderer(new CheckboxListCellRenderer());
+ addMouseListener(new MyMouseAdapter());
+ }
+
+ }
+
+ private SelectedRules rules;
+ private JTextArea exampleTextArea= new JTextArea(10, 50);
+
+ public void onEntry(TraversableContext tc) {
+ super.removeAll();
+ try {
+ rules = new SelectedRules();
+ } catch (RuleSetNotFoundException rsne) {
+ rsne.printStackTrace();
+ }
+
+ JPanel boxesPanel = new JPanel();
+ boxesPanel.setBorder(BorderFactory.createTitledBorder("Rules"));
+ JList list = new CheckboxList(rules.getAllBoxes());
+ list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ boxesPanel.add(new JScrollPane(list), BorderLayout.NORTH);
+ JPanel textPanel = new JPanel();
+ textPanel.setBorder(BorderFactory.createTitledBorder("Example"));
+ textPanel.add(new JScrollPane(exampleTextArea));
+ JPanel selectionPanel = new JPanel();
+ selectionPanel.setLayout(new BorderLayout());
+ selectionPanel.add(boxesPanel, BorderLayout.NORTH);
+ selectionPanel.add(textPanel, BorderLayout.CENTER);
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(new JLabel("Please see http://pmd.sf.net/ for more information"), BorderLayout.NORTH);
+ mainPanel.add(selectionPanel, BorderLayout.CENTER);
+
+ add(mainPanel);
+ }
+
+ public void onExit(TraversableContext tc) {
+ rules.save();
+ }
+}