Applied patch from Brian Remedios to clean up CPD display a bit; thanks Brian!

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4512 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2006-09-20 03:45:06 +00:00
parent 341923aa48
commit 937245f9b6
4 changed files with 129 additions and 28 deletions

View File

@ -8,3 +8,12 @@ Thanks,
Tom
Using PMD? Get the book - http://pmdapplied.com/
if (trimLeadingWhitespace) {
try {
splitterPattern = (new Perl5Compiler()).compile("\n");
} catch (MalformedPatternException mpe) {
mpe.printStackTrace();
}
}

View File

@ -14,6 +14,8 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -29,27 +31,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelListener;
@ -249,6 +231,7 @@ public class GUI implements CPDListener {
private JButton cancelButton;
private JPanel progressPanel;
private JFrame frame;
private boolean trimLeadingWhitespace;
private List matches = new ArrayList();
@ -277,8 +260,19 @@ public class GUI implements CPDListener {
exitItem.setMnemonic('x');
exitItem.addActionListener(new CancelListener());
fileMenu.add(exitItem);
JMenu viewMenu = new JMenu("View");
fileMenu.setMnemonic('v');
JMenuItem trimItem = new JCheckBoxMenuItem("Trim leading whitespace");
trimItem.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
AbstractButton button = (AbstractButton)e.getItem();
trimLeadingWhitespace = button.isSelected();
}
});
viewMenu.add(trimItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(viewMenu);
frame.setJMenuBar(menuBar);
// first make all the buttons
@ -392,7 +386,7 @@ public class GUI implements CPDListener {
for (int i=0; i<selectionIndices.length; i++) {
selections.add(model.getValueAt(selectionIndices[i], 99));
}
String report = new SimpleRenderer().render(selections.iterator());
String report = new SimpleRenderer(trimLeadingWhitespace).render(selections.iterator());
resultsTextArea.setText(report);
resultsTextArea.setCaretPosition(0); // move to the top
}
@ -680,9 +674,8 @@ public class GUI implements CPDListener {
public static void main(String[] args) {
//this should prevent the disk not found popup
System.setSecurityManager(null);
// System.setSecurityManager(null);
new GUI();
}

View File

@ -3,18 +3,33 @@
*/
package net.sourceforge.pmd.cpd;
import net.sourceforge.pmd.PMD;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.util.StringUtil;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.perl.Perl5Util;
public class SimpleRenderer implements Renderer {
private String separator;
private Perl5Util perl5Util;
public static final String defaultSeparator = "=====================================================================";
public SimpleRenderer() {
this(false);
}
public SimpleRenderer(boolean trimLeadingWhitespace) {
this(defaultSeparator);
if (trimLeadingWhitespace) {
perl5Util = new Perl5Util();
}
}
public SimpleRenderer(String theSeparator) {
@ -31,7 +46,25 @@ public class SimpleRenderer implements Renderer {
rpt.append("Starting at line ").append(mark.getBeginLine()).append(" of ").append(mark.getTokenSrcID()).append(PMD.EOL);
}
rpt.append(match.getSourceCodeSlice()).append(PMD.EOL);
rpt.append(PMD.EOL); // add a line to separate the source from the desc above
String source = match.getSourceCodeSlice();
if (perl5Util != null) { // trimming wanted?
List list = new ArrayList();
perl5Util.split(list, PMD.EOL, source, 0);
String[] lines = (String[])list.toArray(new String[] {});
int trimDepth = StringUtil.maxCommonLeadingWhitespaceForAll(lines);
if (trimDepth > 0) {
lines = StringUtil.trimStartOn(lines, trimDepth);
}
for (int i=0; i<lines.length; i++) {
rpt.append(lines[i]).append(PMD.EOL);
}
return;
}
rpt.append(source).append(PMD.EOL);
}

View File

@ -182,4 +182,70 @@ public class StringUtil {
sb.append(iter.next());
}
}
/**
* Return the length of the shortest string in the array.
* If any one of them is null then it returns 0.
*
* @param strings String[]
* @return int
*/
public static int lengthOfShortestIn(String[] strings) {
int minLength = Integer.MAX_VALUE;
for (int i=0; i<strings.length; i++) {
if (strings[i] == null) return 0;
minLength = Math.min(minLength, strings[i].length());
}
return minLength;
}
/**
* Determine the maximum number of common leading whitespace characters
* the strings share in the same sequence. Useful for determining how
* many leading characters can be removed to shift all the text in the
* strings to the left without misaligning them.
*
* @param strings String[]
* @return int
*/
public static int maxCommonLeadingWhitespaceForAll(String[] strings) {
int shortest = lengthOfShortestIn(strings);
if (shortest == 0) return 0;
char[] matches = new char[shortest];
String str;
for (int m=0; m<matches.length; m++) {
matches[m] = strings[0].charAt(m);
if (!Character.isWhitespace(matches[m])) return m;
for (int i=0; i<strings.length; i++) {
str = strings[i];
if (str.charAt(m) != matches[m]) return m;
}
}
return shortest;
}
/**
* Trims off the leading characters off the strings up to the trimDepth
* specified. Returns the same strings if trimDepth = 0
*
* @param strings
* @param trimDepth
* @return String[]
*/
public static String[] trimStartOn(String[] strings, int trimDepth) {
if (trimDepth == 0) return strings;
String[] results = new String[strings.length];
for (int i=0; i<strings.length; i++) {
results[i] = strings[i].substring(trimDepth);
}
return results;
}
}