Finished first implementation of CPD

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@669 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
David Craine
2002-08-09 15:50:04 +00:00
parent 7fe9bb55ee
commit 6857f69373
5 changed files with 192 additions and 15 deletions

Binary file not shown.

View File

@ -0,0 +1,7 @@
<HTML>
<BODY>
CPD stands for "Cut and Paste Tool". The function of CPD is to find duplicate code across all the files in a particular<BR>
project. You can specify the minimum number of tokens that constitute a legitimate CPD find. A token represents the smallest<BR>
parseable unit in the Java language. For example, all java keywords, variable names, method names, etc are considered tokens.
</BODY>
</HTML>

View File

@ -0,0 +1,37 @@
package net.sourceforge.pmd.jbuilder;
import com.borland.primetime.properties.PropertyGroup;
import com.borland.primetime.properties.PropertyPageFactory;
import com.borland.primetime.properties.PropertyPage;
import com.borland.primetime.ide.MessageCategory;
import com.borland.primetime.properties.GlobalIntegerProperty;
/**
* <p>Title: JBuilder OpenTool for PMD</p>
* <p>Description: Provides an environemnt for using the PMD aplication from within JBuilder</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: InfoEther</p>
* @author David Craine
* @version 1.0
*/
public class CPDPropertyGroup implements PropertyGroup {
static GlobalIntegerProperty PROP_MIN_TOKEN_COUNT = new GlobalIntegerProperty(Constants.RULESETS, "mintokencount", 30);
public CPDPropertyGroup() {
}
public void initializeProperties() {
}
public PropertyPageFactory getPageFactory(Object topic) {
if (topic == Constants.RULESETS_TOPIC) {
return new PropertyPageFactory("CPD Properties", "Configure the CPD RuleSets") {
public PropertyPage createPropertyPage () {
return new CPDPropertyPage();
}
};
}
return null;
}
}

View File

@ -0,0 +1,96 @@
package net.sourceforge.pmd.jbuilder;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import com.borland.primetime.help.*;
import com.borland.primetime.ide.*;
import com.borland.primetime.properties.*;
import net.sourceforge.pmd.*;
import com.borland.jbcl.layout.*;
/**
* <p>Title: JBuilder OpenTool for PMD</p>
* <p>Description: Provides an environemnt for using the PMD aplication from within JBuilder</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: InfoEther</p>
* @author David Craine
* @version 1.0
*/
public class CPDPropertyPage extends PropertyPage {
static CPDPropertyPage currentInstance = null;
private JPanel jPanel1 = new JPanel();
private VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
private JLabel jLabel1 = new JLabel();
private JTextField jTextField1 = new JTextField();
public CPDPropertyPage() {
currentInstance = this;
try {
jbInit();
init2();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**
* This methiod is called by JBuilder when the user presses "OK" in the property dialog
*/
public void writeProperties() {
try {
int minTokenCount = Integer.parseInt(jTextField1.getText());
CPDPropertyGroup.PROP_MIN_TOKEN_COUNT.setInteger(minTokenCount);
}
catch (Exception ex) {
}
}
/**
* This methiod is called by JBuilder
*/
public HelpTopic getHelpTopic() {
return new ZipHelpTopic(
null,
getClass().getResource("/html/cpd-props.html").toString());
}
/**
* This methiod is called by JBuilder
*/
public void readProperties() {
}
/**
* JBuilder-constructed initialization
* @throws Exception
*/
private void jbInit() throws Exception {
this.setLayout(verticalFlowLayout1);
jLabel1.setText("Minimum Token Count");
jTextField1.setPreferredSize(new Dimension(40, 21));
this.add(jPanel1, null);
jPanel1.add(jLabel1, null);
jPanel1.add(jTextField1, null);
}
/**
* additional intiialzation
*/
private void init2() {
jTextField1.setText(String.valueOf(CPDPropertyGroup.PROP_MIN_TOKEN_COUNT.getInteger()));
}
}

View File

@ -43,6 +43,7 @@ public class PMDOpenTool {
static MessageCategory msgCat = new MessageCategory("PMD Results");
static MessageCategory cpdCat = new MessageCategory("CPD Results");
public static ActionGroup GROUP_PMD = new ActionGroup("PMD", 'p', true);
public static ActionGroup GROUP_TOOLBAR_PMD = new ActionGroup("PMD", 'P', true);
static Font fileNameMsgFont = new Font("Dialog", Font.BOLD, 12);
static Font stdMsgFont = new Font("Dialog", Font.PLAIN, 12);
@ -65,11 +66,14 @@ public class PMDOpenTool {
GROUP_PMD.add(B_ACTION_PMDCheck);
GROUP_PMD.add(B_ACTION_PMDProjectCheck);
GROUP_PMD.add(B_ACTION_CPDProjectCheck);
GROUP_PMD.add(B_ACTION_PMDConfig);
JBuilderMenu.GROUP_Tools.add(GROUP_PMD);
JBuilderToolBar.GROUP_RunBar.add(B_ACTION_PMDCheck);
JBuilderToolBar.GROUP_RunBar.add(B_ACTION_PMDProjectCheck);
JBuilderToolBar.GROUP_RunBar.add(B_ACTION_CPDProjectCheck);
GROUP_TOOLBAR_PMD.add(B_ACTION_PMDCheck);
GROUP_TOOLBAR_PMD.add(B_ACTION_PMDProjectCheck);
GROUP_TOOLBAR_PMD.add(B_ACTION_CPDProjectCheck);
Browser.addToolBarGroup(GROUP_TOOLBAR_PMD);
registerWithContentManager();
registerWithProjectView();
@ -82,6 +86,7 @@ public class PMDOpenTool {
ActiveRuleSetPropertyGroup apropGrp = new ActiveRuleSetPropertyGroup();
ConfigureRuleSetPropertyGroup cpropGrp = new ConfigureRuleSetPropertyGroup();
AcceleratorPropertyGroup accpropGrp = new AcceleratorPropertyGroup();
CPDPropertyGroup cpdPropGrp = new CPDPropertyGroup();
//register the Keymap shortcuts if they are enabled
if (AcceleratorPropertyGroup.PROP_KEYS_ENABLED.getBoolean()) {
@ -92,6 +97,7 @@ public class PMDOpenTool {
PropertyManager.registerPropertyGroup(cpropGrp);
PropertyManager.registerPropertyGroup(ipropGrp);
PropertyManager.registerPropertyGroup(accpropGrp);
PropertyManager.registerPropertyGroup(cpdPropGrp);
}
}
@ -332,7 +338,7 @@ public class PMDOpenTool {
try {
Browser.getActiveBrowser().getMessageView().clearMessages(cpdCat); //clear the message window
CPD cpd = new CPD();
cpd.setMinimumTileSize(25);
cpd.setMinimumTileSize(CPDPropertyGroup.PROP_MIN_TOKEN_COUNT.getInteger());
Node[] nodes = Browser.getActiveBrowser().getActiveProject().getDisplayChildren();
CPDDialog cpdd = new CPDDialog(cpd);
for (int i=0; i<nodes.length; i++ ) {
@ -357,10 +363,11 @@ public class PMDOpenTool {
for (Iterator iter = results.getTiles(); iter.hasNext(); ) {
Tile t = (Tile)iter.next();
resultCount++;
CPDMessage msg = CPDMessage.createMessage("Duplicate code set: " + resultCount);
int tileLineCount = cpd.getLineCountFor(t);
CPDMessage msg = CPDMessage.createMessage("Duplicate code set: " + resultCount, t.getImage());
for (Iterator iter2 = results.getOccurrences(t); iter2.hasNext(); ) {
TokenEntry te = (TokenEntry)iter2.next();
msg.addChildMessage(te.getTokenSrcID(), te.getBeginLine(), 0, te.getTokenSrcID());
msg.addChildMessage(te.getBeginLine(), tileLineCount, te.getTokenSrcID());
}
Browser.getActiveBrowser().getMessageView().addMessage(cpdCat, msg);
}
@ -451,14 +458,15 @@ class PMDMessage extends Message {
* Wrapper for the OpenTools message object
*/
class CPDMessage extends Message {
final LineMark MARK = new HighlightMark();
final static LineMark MARK = new HighlightMark(true);
String filename;
FileNode javaNode = null;
int startline = 0;
int endline = 0;
int lineCount = 0;
int column = 0;
boolean isParent = true;
ArrayList childMessages = new ArrayList();
String codeBlock = null;
/**
* Constructor
@ -467,15 +475,16 @@ class CPDMessage extends Message {
* @param node the node that the code belongs to
*/
private CPDMessage(String msg) {
private CPDMessage(String msg, String codeBlock) {
super(msg);
this.codeBlock = codeBlock;
this.setLazyFetchChildren(true);
}
private CPDMessage (String msg, int startline, int endline, String fileName) {
private CPDMessage (String msg, int startline, int lineCount, String fileName) {
super(msg);
this.startline = startline;
this.endline = endline;
this.lineCount = lineCount;
this.filename = fileName;
try {
File javaFile = new File(fileName);
@ -486,15 +495,17 @@ class CPDMessage extends Message {
}
}
public static CPDMessage createMessage(String msg) {
CPDMessage cpdm = new CPDMessage(msg);
public static CPDMessage createMessage(String msg, String codeBlock) {
CPDMessage cpdm = new CPDMessage(msg, codeBlock);
cpdm.isParent = true;
return cpdm;
}
public void addChildMessage (String msg, int startline, int endline, String fileName) {
public void addChildMessage (int startline, int endline, String fileName) {
this.lazyFetchChildren = true;
String sep = System.getProperty("file.separator");
String msg = fileName.substring(fileName.lastIndexOf(sep.charAt(0))+1)+": line: " + String.valueOf(startline);
CPDMessage cpdmsg = new CPDMessage(msg, startline, endline, fileName);
cpdmsg.isParent = false;
childMessages.add(cpdmsg);
@ -502,6 +513,8 @@ class CPDMessage extends Message {
}
public void fetchChildren(Browser browser) {
CodeFragmentMessage cfm = new CodeFragmentMessage(this.codeBlock);
browser.getMessageView().addMessage(PMDOpenTool.cpdCat, this, cfm);
for (Iterator iter = childMessages.iterator(); iter.hasNext(); ) {
browser.getMessageView().addMessage(PMDOpenTool.cpdCat, this, (CPDMessage)iter.next());
}
@ -529,6 +542,7 @@ class CPDMessage extends Message {
* @param requestFocus whether or not the code window should receive focus
*/
private void displayResult (Browser browser, boolean requestFocus) {
MARK.removeEditor();
if (!isParent) {
try {
if (requestFocus || browser.isOpenNode(javaNode)) {
@ -537,10 +551,15 @@ class CPDMessage extends Message {
TextNodeViewer.class);
browser.setActiveViewer(javaNode, viewer, requestFocus);
EditorPane editor = viewer.getEditor();
editor.gotoPosition(startline, column, false, EditorPane.CENTER_IF_NEAR_EDGE);
editor.gotoPosition(startline, 0, false, EditorPane.CENTER_IF_NEAR_EDGE);
if (requestFocus) {
editor.requestFocus();
}
/*EditorDocument ed = (EditorDocument)editor.getDocument();
int[] lines = new int[lineCount];
for (int i=0; i<lineCount; i++)
lines[i] = startline+i-1;
ed.setLightweightLineMarks(lines, MARK);*/
editor.setTemporaryMark(startline, MARK);
}
@ -551,6 +570,20 @@ class CPDMessage extends Message {
}
}
class CodeFragmentMessage extends Message {
String codeFragment = null;
public CodeFragmentMessage(String codeFragment) {
super("View Code");
this.setLazyFetchChildren(true);
this.codeFragment = codeFragment;
}
public void fetchChildren(Browser browser) {
browser.getMessageView().addMessage(PMDOpenTool.cpdCat, this, new Message(codeFragment));
}
}
/**
* Used to highlite a line of code within a source file
*/
@ -570,4 +603,8 @@ class HighlightMark extends LineMark {
public HighlightMark () {
super(highlightStyle);
}
public HighlightMark(boolean isLightWeight) {
super(isLightWeight, highlightStyle);
}
}