From d09bbf640cb172d7b9122530e8e5a66bbd2d11f7 Mon Sep 17 00:00:00 2001 From: Ole-Martin Mork Date: Fri, 21 Feb 2003 01:03:47 +0000 Subject: [PATCH] Preparing for custom rulesets git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@1457 51baf565-9d33-0410-a72c-fc3788e3496d --- pmd-netbeans/src/pmd/config/Bundle.properties | 8 + .../src/pmd/config/PMDOptionsSettings.java | 67 +++++--- .../config/PMDOptionsSettingsBeanInfo.java | 14 +- .../src/pmd/config/ui/RuleSetChooser.form | 112 ++++++++++++ .../src/pmd/config/ui/RuleSetChooser.java | 162 ++++++++++++++++++ .../pmd/config/ui/RuleSetChooserEditor.java | 114 ++++++++++++ .../src/pmd/config/ui/RuleSetFilter.java | 25 +++ .../src/pmd/custom/RuleClassLoader.java | 80 +++++++++ 8 files changed, 553 insertions(+), 29 deletions(-) create mode 100644 pmd-netbeans/src/pmd/config/ui/RuleSetChooser.form create mode 100644 pmd-netbeans/src/pmd/config/ui/RuleSetChooser.java create mode 100644 pmd-netbeans/src/pmd/config/ui/RuleSetChooserEditor.java create mode 100644 pmd-netbeans/src/pmd/config/ui/RuleSetFilter.java create mode 100644 pmd-netbeans/src/pmd/custom/RuleClassLoader.java diff --git a/pmd-netbeans/src/pmd/config/Bundle.properties b/pmd-netbeans/src/pmd/config/Bundle.properties index 317fb96053..ec478edc2b 100644 --- a/pmd-netbeans/src/pmd/config/Bundle.properties +++ b/pmd-netbeans/src/pmd/config/Bundle.properties @@ -29,3 +29,11 @@ LBL_settings=PMD Settings PROP_rules=Rules HINT_rules=The rules that the pmd action uses Services/pmd-config-option.settings=\PMD Settings + +HINT_classpath=The classpath for custom rules + +PROP_classpath=Classpath + +PROP_rulesets=Rulesets + +HINT_rulesets=The custom rulesets to use diff --git a/pmd-netbeans/src/pmd/config/PMDOptionsSettings.java b/pmd-netbeans/src/pmd/config/PMDOptionsSettings.java index 561b698fe2..7c99723fd9 100644 --- a/pmd-netbeans/src/pmd/config/PMDOptionsSettings.java +++ b/pmd-netbeans/src/pmd/config/PMDOptionsSettings.java @@ -41,24 +41,22 @@ public class PMDOptionsSettings extends SystemOption { /** The serialVersionUID. Don't change! */ private final static long serialVersionUID = 8418202279282091070L; - /** - * The constant for the rulesets property - * @deprecated this property is not in use. - */ - public final static String PROP_RULESETS = "rulesets"; - /** The constant for the rulesets property */ public final static String PROP_RULES = "rules"; + + public final static String PROP_CLASSPATH = "classpath"; + + public final static String PROP_RULESETS = "rulesets"; /** The default rules.*/ - private static final String DEFAULT_RULES = + private static final String DEFAULT_RULES = "AvoidDuplicateLiterals, StringToString, StringInstantiation, JUnitStaticSuite, " + "JUnitSpelling, ForLoopsMustUseBracesRule, IfElseStmtsMustUseBracesRule, " + "WhileLoopsMustUseBracesRule, IfStmtsMustUseBraces, EmptyCatchBlock, EmptyIfStmt, " + - "EmptyWhileStmt, JumbledIncrementer, UnnecessaryConversionTemporaryRule, " + + "EmptyWhileStmt, JumbledIncrementer, UnnecessaryConversionTemporaryRule, " + "OverrideBothEqualsAndHashcodeRule, EmptyTryBlock, EmptySwitchStatements, " + "EmptyFinallyBlock, UnusedLocalVariable, UnusedPrivateField, UnusedFormalParameter, " + - "UnnecessaryConstructorRule, UnusedPrivateMethod, SwitchStmtsShouldHaveDefault, " + + "UnnecessaryConstructorRule, UnusedPrivateMethod, SwitchStmtsShouldHaveDefault, " + "SimplifyBooleanReturnsRule, LooseCouplingRule, AvoidDeeplyNestedIfStmts, " + "AvoidReassigningParametersRule, OnlyOneReturn, UseSingletonRule, " + "DontImportJavaLang, UnusedImports, DuplicateImports, "; @@ -68,7 +66,6 @@ public class PMDOptionsSettings extends SystemOption { /** Sets the default rulesets and initializes the option */ protected void initialize() { super.initialize(); - setRulesets( "" ); setRules( DEFAULT_RULES ); } @@ -104,24 +101,6 @@ public class PMDOptionsSettings extends SystemOption { } - /** Returns the rulesets property - * @deprecated not used anymore, use {@link #getRules} - * @return the rulesets property - */ - public String getRulesets() { - return ( String )getProperty( PROP_RULESETS ); - } - - - /** Sets the rulesets property - * @deprecated not used anymore, use {@link #setRules} - * @param rulesets the rulesets value to set - */ - public void setRulesets( String rulesets ) { - putProperty( PROP_RULESETS, rulesets, true ); - } - - /** * Returns the rulesets property * @@ -141,4 +120,36 @@ public class PMDOptionsSettings extends SystemOption { putProperty( PROP_RULES, rules, true ); } + /** Getter for property classpath. + * @return Value of property classpath. + * + */ + public String getClasspath() { + return (String)getProperty( PROP_CLASSPATH ); + } + + /** Setter for property classpath. + * @param classpath New value of property classpath. + * + */ + public void setClasspath(String classpath) { + putProperty( PROP_CLASSPATH, classpath, true ); + } + + /** Getter for property rulesets. + * @return Value of property rulesets. + * + */ + public String getRulesets() { + return (String)getProperty( PROP_RULESETS ); + } + + /** Setter for property rulesets. + * @param rulesets New value of property rulesets. + * + */ + public void setRulesets(String rulesets) { + putProperty( PROP_RULESETS, rulesets, true ); + } + } diff --git a/pmd-netbeans/src/pmd/config/PMDOptionsSettingsBeanInfo.java b/pmd-netbeans/src/pmd/config/PMDOptionsSettingsBeanInfo.java index b1310d9e28..b071bfecf7 100644 --- a/pmd-netbeans/src/pmd/config/PMDOptionsSettingsBeanInfo.java +++ b/pmd-netbeans/src/pmd/config/PMDOptionsSettingsBeanInfo.java @@ -36,6 +36,7 @@ import org.openide.ErrorManager; import org.openide.util.NbBundle; import org.openide.util.Utilities; import pmd.config.ui.RuleEditor; +import pmd.config.ui.RuleSetChooserEditor; /** * Description of {@link PMDOptionsSettings}. @@ -51,13 +52,24 @@ public class PMDOptionsSettingsBeanInfo extends SimpleBeanInfo { * @return the description of the rulesets property */ public PropertyDescriptor[] getPropertyDescriptors() { - PropertyDescriptor descriptor[] = new PropertyDescriptor[1]; + PropertyDescriptor descriptor[] = new PropertyDescriptor[3]; try { PropertyDescriptor rules = new PropertyDescriptor( "rules", PMDOptionsSettings.class, "getRules", "setRules" ); rules.setDisplayName( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "PROP_rules" ) ); rules.setShortDescription( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "HINT_rules" ) ); rules.setPropertyEditorClass( RuleEditor.class ); descriptor[0] = rules; + + PropertyDescriptor classpath = new PropertyDescriptor( "classpath", PMDOptionsSettings.class, "getClasspath", "setClasspath" ); + classpath.setDisplayName( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "PROP_classpath" ) ); + classpath.setShortDescription( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "HINT_classpath" ) ); + descriptor[1] = classpath; + + PropertyDescriptor rulesets = new PropertyDescriptor( "rulesets", PMDOptionsSettings.class, "getRulesets", "setRulesets" ); + rulesets.setDisplayName( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "PROP_rulesets" ) ); + rulesets.setShortDescription( NbBundle.getMessage( PMDOptionsSettingsBeanInfo.class, "HINT_rulesets" ) ); + rulesets.setPropertyEditorClass( RuleSetChooserEditor.class ); + descriptor[2] = rulesets; } catch( IntrospectionException ie ) { ErrorManager.getDefault().notify( ie ); diff --git a/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.form b/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.form new file mode 100644 index 0000000000..284a11e94f --- /dev/null +++ b/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.form @@ -0,0 +1,112 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.java b/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.java new file mode 100644 index 0000000000..d6173ac1c8 --- /dev/null +++ b/pmd-netbeans/src/pmd/config/ui/RuleSetChooser.java @@ -0,0 +1,162 @@ +/* + * RuleSetChooser.java + * + * Created on 20. februar 2003, 21:16 + */ + +package pmd.config.ui; + +import java.beans.PropertyEditorSupport; +import javax.swing.DefaultListModel; +import javax.swing.JFileChooser; +import javax.swing.JPanel; + +/** + * + * @author ole martin mørk + */ +public class RuleSetChooser extends JPanel { + private final PropertyEditorSupport editor; + private final JFileChooser chooser = new JFileChooser(); + /** Creates new form RuleSetChooser */ + public RuleSetChooser(PropertyEditorSupport editor) { + this.editor = editor; + RuleSetFilter filter = new RuleSetFilter(); + chooser.setFileFilter( filter ); + initComponents(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + private void initComponents() {//GEN-BEGIN:initComponents + java.awt.GridBagConstraints gridBagConstraints; + + jScrollPane1 = new javax.swing.JScrollPane(); + rulesetList = new javax.swing.JList(); + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + remove = new javax.swing.JButton(); + add = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + stdRules = new javax.swing.JCheckBox(); + + setLayout(new java.awt.GridBagLayout()); + + setPreferredSize(new java.awt.Dimension(355, 200)); + jScrollPane1.setPreferredSize(new java.awt.Dimension(300, 131)); + rulesetList.setModel(new DefaultListModel()); + rulesetList.setMinimumSize(new java.awt.Dimension(200, 200)); + jScrollPane1.setViewportView(rulesetList); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 1, 0); + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.weighty = 1.0; + add(jScrollPane1, gridBagConstraints); + + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel2.setLayout(new java.awt.BorderLayout(0, 5)); + + remove.setText("Remove"); + remove.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + removeActionPerformed(evt); + } + }); + + jPanel2.add(remove, java.awt.BorderLayout.CENTER); + + add.setText("Add"); + add.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addActionPerformed(evt); + } + }); + + jPanel2.add(add, java.awt.BorderLayout.NORTH); + + jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; + add(jPanel1, gridBagConstraints); + + jLabel1.setText("Choose the rulesets to use."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + add(jLabel1, gridBagConstraints); + + stdRules.setText("Include PMD standard rules."); + stdRules.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + stdRulesActionPerformed(evt); + } + }); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + add(stdRules, gridBagConstraints); + + }//GEN-END:initComponents + + private void stdRulesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stdRulesActionPerformed + editor.firePropertyChange(); + }//GEN-LAST:event_stdRulesActionPerformed + + private void removeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeActionPerformed + int index = rulesetList.getSelectedIndex(); + getListModel().removeElementAt( index ); + editor.firePropertyChange(); + }//GEN-LAST:event_removeActionPerformed + + private void addActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addActionPerformed + int returnValue = chooser.showOpenDialog( this ); + if(returnValue == JFileChooser.APPROVE_OPTION) { + if( !getListModel().contains( chooser.getSelectedFile().getAbsolutePath() ) ) { + getListModel().addElement( + chooser.getSelectedFile().getAbsolutePath() ); + } + } + chooser.cancelSelection(); + editor.firePropertyChange(); + }//GEN-LAST:event_addActionPerformed + + public DefaultListModel getListModel() { + return (DefaultListModel)rulesetList.getModel(); + } + + public boolean includeStandardRules() { + return stdRules.isSelected(); + } + + public void setIncludeStandardRules( boolean selected ) { + stdRules.setSelected( selected ); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JList rulesetList; + private javax.swing.JButton remove; + private javax.swing.JButton add; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel jLabel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel1; + private javax.swing.JCheckBox stdRules; + // End of variables declaration//GEN-END:variables + +} diff --git a/pmd-netbeans/src/pmd/config/ui/RuleSetChooserEditor.java b/pmd-netbeans/src/pmd/config/ui/RuleSetChooserEditor.java new file mode 100644 index 0000000000..ea4b0b3932 --- /dev/null +++ b/pmd-netbeans/src/pmd/config/ui/RuleSetChooserEditor.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2002-2003, Ole-Martin Mørk + * 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.config.ui; + +import java.awt.Component; +import java.beans.PropertyEditorSupport; +import java.util.StringTokenizer; +import javax.swing.DefaultListModel; +import javax.swing.ListModel; + +/** The PropertyEditor of the Rule property + * @author ole martin mørk + * @created 18. november 2002 + */ +public class RuleSetChooserEditor extends PropertyEditorSupport { + RuleSetChooser chooser = new RuleSetChooser( this ); + + /** + * Returns the custom editor of the Rule property + * @return the editor + */ + public Component getCustomEditor() { + return chooser; + } + + + /** + * Returns true + * @return true + */ + public boolean supportsCustomEditor() { + return true; + } + + + /** + * Returns the selected rules + * @return the selected rules + */ + public Object getValue() { + ListModel model = chooser.getListModel(); + StringBuffer buffer = new StringBuffer(); + for( int i = 0; i < model.getSize(); i++ ) { + buffer.append( model.getElementAt( i ) ).append( ", " ); + } + if( buffer.length() > 2 ) { + buffer.delete( buffer.length() - 2, buffer.length() ); + } + buffer.append( ", " ).append( chooser.includeStandardRules() ); + return buffer.toString(); + } + + + /** + * Returns a string representation of the property value + * @return the property as text + */ + public String getAsText() { + return getValue().toString(); + } + + + /** + * Sets the value to be edited in the editor + * @param obj The new value + */ + public void setValue( Object obj ) { + if( obj != null ) { + DefaultListModel model = chooser.getListModel(); + StringTokenizer tokenizer = new StringTokenizer( obj.toString(), "," ); + int tokens = tokenizer.countTokens(); + for( int i = 0; i < tokens - 1 && tokenizer.hasMoreTokens(); i++ ) { + model.addElement( tokenizer.nextToken().trim() ); + } + if( tokenizer.hasMoreTokens() ) { + chooser.setIncludeStandardRules( + Boolean.valueOf( tokenizer.nextToken().trim() ).equals( Boolean.TRUE ) ); + } + + } + } + + + /** + * Not implemented + * @param string the text + * @exception IllegalArgumentException never + */ + public void setAsText( String string ) throws IllegalArgumentException { } +} \ No newline at end of file diff --git a/pmd-netbeans/src/pmd/config/ui/RuleSetFilter.java b/pmd-netbeans/src/pmd/config/ui/RuleSetFilter.java new file mode 100644 index 0000000000..ae49f461d4 --- /dev/null +++ b/pmd-netbeans/src/pmd/config/ui/RuleSetFilter.java @@ -0,0 +1,25 @@ +/* + * RulesetFilter.java + * + * Created on 20. februar 2003, 22:52 + */ + +package pmd.config.ui; + +import javax.swing.filechooser.FileFilter; + +/** + * + * @author ole martin mørk + */ +public class RuleSetFilter extends FileFilter { + + public boolean accept(java.io.File file) { + return file.getName().toLowerCase().endsWith( "xml" ) || file.isDirectory(); + } + + public String getDescription() { + return "RuleSet(*.xml)"; + } + +} diff --git a/pmd-netbeans/src/pmd/custom/RuleClassLoader.java b/pmd-netbeans/src/pmd/custom/RuleClassLoader.java new file mode 100644 index 0000000000..fe023b6054 --- /dev/null +++ b/pmd-netbeans/src/pmd/custom/RuleClassLoader.java @@ -0,0 +1,80 @@ +/* + * RuleClassLoader.java + * + * Created on 21. februar 2003, 00:31 + */ +package pmd.custom; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.StringTokenizer; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import pmd.config.PMDOptionsSettings; + +/** + * @author ole martin mørk + * @created 21. februar 2003 + */ +public class RuleClassLoader extends ClassLoader { + + /** + * Creates a new instance of RuleClassLoader + * + * @param parent Description of the Parameter + */ + public RuleClassLoader( ClassLoader parent ) { + super( parent ); + } + + + /** + * Description of the Method + * + * @param name Description of the Parameter + * @return Description of the Return Value + */ + protected Class findClass( String name ) { + System.out.println( "Loading class " + name ); + + String className = name.replace( '.', '/' ); + className += ".class"; + + String classPath = PMDOptionsSettings.getDefault().getClasspath(); + StringTokenizer tokens = new StringTokenizer( classPath, ";" ); + try { + while( tokens.hasMoreTokens() ) { + File jar = new File( tokens.nextToken() ); + JarFile jarFile = new JarFile( jar, false ); + JarEntry entry = jarFile.getJarEntry( className ); + System.out.println( entry ); + if( entry != null ) { + BufferedInputStream stream = new BufferedInputStream( jarFile.getInputStream( entry ) ); + byte buffer[] = new byte[stream.available()]; + stream.read( buffer, 0, buffer.length ); + return defineClass( name, buffer, 0, buffer.length ); + } + } + } + catch( IOException e ) { + return null; + } + return null; + } + + + /** + * Description of the Method + * + * @param args Description of the Parameter + * @exception Exception Description of the Exception + */ + public static void main( String args[] ) throws Exception { + Class clazz = Class.forName( "net.sourceforge.pmd.Report", true, new RuleClassLoader( RuleClassLoader.class.getClassLoader() ) ); + Object o = clazz.newInstance(); + Method method = clazz.getMethod( "hasMetrics", null ); + System.out.println( method.invoke( o, null ) ); + } +}