diff --git a/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDConstants.java b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDConstants.java new file mode 100644 index 0000000000..dfaa1365b5 --- /dev/null +++ b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDConstants.java @@ -0,0 +1,28 @@ +package net.sourceforge.pmd.eclipse; + +/** + * Convenient class to hold PMD Constants + * @author phherlin + * @version $Revision$ + * + * $Log$ + * Revision 1.1 2003/03/17 23:35:25 phherlin + * first version + * + */ +public interface PMDConstants { + public static final String MSGKEY_ENABLE_BUTTON_LABEL = "property.pmd.enable"; + public static final String MSGKEY_PMD_PROCESSING = "monitor.begintask"; + + public static final String MSGKEY_PREF_GENERAL_TITLE = "preference.pmd.title"; + public static final String MSGKEY_PREF_RULESET_TITLE = "preference.ruleset.title"; + public static final String MSGKEY_PREF_RULESET_LIST = "preference.ruleset.list"; + public static final String MSGKEY_PREF_RULESET_ADD = "preference.ruleset.add"; + public static final String MSGKEY_PREF_RULESET_REMOVE = "preference.ruleset.remove"; + public static final String MSGKEY_PREF_CPD_TITLE = "preference.cpd.title"; + public static final String MSGKEY_PREF_CPD_TILESIZE = "preference.cpd.tilesize"; + + public static final String MSGKEY_ERROR_TITLE = "message.error.title"; + public static final String MSGKEY_ERROR_CORE_EXCEPTION = "message.error.core_exception"; + public static final String MSGKEY_ERROR_PMD_EXCEPTION = "message.error.pmd_exception"; +} diff --git a/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDDeltaVisitor.java b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDDeltaVisitor.java new file mode 100644 index 0000000000..76cb937469 --- /dev/null +++ b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDDeltaVisitor.java @@ -0,0 +1,118 @@ +package net.sourceforge.pmd.eclipse; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * A PMD visitor for processing resource deltas + * + * @author Philippe Herlin + * @version $Revision$ + * $Log$ + * Revision 1.1 2003/03/17 23:35:24 phherlin + * first version + * + */ +public class PMDDeltaVisitor implements IResourceDeltaVisitor { + private IProgressMonitor monitor; + private boolean useTaskMarker = false; + + /** + * Default construtor + */ + public PMDDeltaVisitor() { + } + + /** + * Constructor with monitor + */ + public PMDDeltaVisitor(IProgressMonitor monitor) { + this.monitor = monitor; + } + + /** + * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(IResourceDelta) + */ + public boolean visit(IResourceDelta delta) throws CoreException { + boolean fProcessChildren = true; + + if ((monitor == null) || ((monitor != null) && (!monitor.isCanceled()))) { + if (delta.getKind() == IResourceDelta.ADDED) { + visitAdded(delta.getResource()); + } else if (delta.getKind() == IResourceDelta.CHANGED) { + visitChanged(delta.getResource()); + } // other kinds are not visited + } else { + fProcessChildren = false; + } + + return fProcessChildren; + } + + /** + * Visit added resource + * @param resource a new resource + */ + private void visitAdded(IResource resource) { + processResource(resource); + } + + /** + * Visit changed resource + * @param resource a changed resource + */ + private void visitChanged(IResource resource) { + processResource(resource); + } + + /** + * Process a targeted resource + * @param resource the resource to process + */ + private void processResource(IResource resource) { + if ((resource instanceof IFile) + && (((IFile) resource).getFileExtension() != null) + && ((IFile) resource).getFileExtension().equals("java")) { + if (monitor != null) monitor.subTask(((IFile) resource).getName()); + PMDProcessor.getInstance().run((IFile) resource, useTaskMarker); + if (monitor != null) monitor.worked(1); + } + } + + /** + * Returns the monitor. + * @return IProgressMonitor + */ + public IProgressMonitor getMonitor() { + return monitor; + } + + /** + * Sets the monitor. + * @param monitor The monitor to set + */ + public void setMonitor(IProgressMonitor monitor) { + this.monitor = monitor; + } + + /** + * Returns the useTaskMarker. + * @return boolean + */ + public boolean isUseTaskMarker() { + return useTaskMarker; + } + + /** + * Sets the useTaskMarker. + * @param useTaskMarker The useTaskMarker to set + */ + public void setUseTaskMarker(boolean useTaskMarker) { + this.useTaskMarker = useTaskMarker; + } + +} \ No newline at end of file diff --git a/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDProcessor.java b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDProcessor.java new file mode 100644 index 0000000000..2bd99e638d --- /dev/null +++ b/pmd-eclipse/src/net/sourceforge/pmd/eclipse/PMDProcessor.java @@ -0,0 +1,149 @@ +package net.sourceforge.pmd.eclipse; + +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Iterator; + +import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.PMDException; +import net.sourceforge.pmd.Report; +import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.RuleSet; +import net.sourceforge.pmd.RuleSetFactory; +import net.sourceforge.pmd.RuleViolation; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.MessageDialog; + +/** + * A class to process IFile resource against PMD + * + * @author phherlin + * @version $Revision$ + * + * $Log$ + * Revision 1.1 2003/03/17 23:35:25 phherlin + * first version + * + */ +public class PMDProcessor { + private static final PMDProcessor SELF = new PMDProcessor(); + private PMD pmdEngine; + + /** + * Default construtor + */ + private PMDProcessor() { + initialize(); + } + + /** + * Return the processor instance + */ + public static PMDProcessor getInstance() { + return SELF; + } + + /** + * Process an IFile resource + * @param file the IFile to process + * @param fTask indicate if a task marker should be created + */ + public void run(IFile file, boolean fTask) { + try { + Reader input = new InputStreamReader(file.getContents()); + RuleContext context = new RuleContext(); + context.setSourceCodeFilename(file.getName()); + context.setReport(new Report()); + + pmdEngine.processFile(input, getRuleSet(), context); + + updateMarkers(file, context, fTask); + + } catch (CoreException e) { + MessageDialog.openError( + null, + getMessage(PMDConstants.MSGKEY_ERROR_TITLE), + getMessage(PMDConstants.MSGKEY_ERROR_CORE_EXCEPTION) + e.toString()); + } catch (PMDException e) { + MessageDialog.openError( + null, + getMessage(PMDConstants.MSGKEY_ERROR_TITLE), + getMessage(PMDConstants.MSGKEY_ERROR_PMD_EXCEPTION) + e.toString()); + } + } + + /** + * Update markers list for the specified file + * @param file the file for which markes are to be updated + * @param context a PMD context + * @param fTask indicate if a task marker should be created + */ + private void updateMarkers(IFile file, RuleContext context, boolean fTask) throws CoreException { + file.deleteMarkers(PMDPlugin.PMD_MARKER, true, IResource.DEPTH_INFINITE); + + Iterator iter = context.getReport().iterator(); + while (iter.hasNext()) { + RuleViolation violation = (RuleViolation) iter.next(); + + IMarker marker = file.createMarker(fTask ? PMDPlugin.PMD_TASKMARKER : PMDPlugin.PMD_MARKER); + marker.setAttribute(IMarker.MESSAGE, violation.getDescription()); + marker.setAttribute(IMarker.LINE_NUMBER, violation.getLine()); + marker.setAttribute("description", violation.getRule().getMessage()); + marker.setAttribute("example", violation.getRule().getExample()); + + switch (violation.getRule().getPriority()) { + case 1 : + marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); + case 2 : + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + break; + + case 5 : + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); + break; + + case 3 : + marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); + case 4 : + default : + marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); + break; + } + } + } + + /** + * Initialize the processor + */ + private void initialize() { + pmdEngine = new PMD(); + } + + /** + * Get the rule set from preferences + */ + private RuleSet getRuleSet() { + RuleSetFactory factory = new RuleSetFactory(); + String[] ruleSetFiles = PMDPlugin.getDefault().getRuleSetsPreference(); + + RuleSet ruleSet = factory.createRuleSet(getClass().getClassLoader().getResourceAsStream(ruleSetFiles[0])); + for (int i = 1; i < ruleSetFiles.length; i++) { + RuleSet tmpRuleSet = factory.createRuleSet(getClass().getClassLoader().getResourceAsStream(ruleSetFiles[i])); + ruleSet.addRuleSet(tmpRuleSet); + } + + return ruleSet; + } + + /** + * Helper method to shorten message access + * @param key a message key + * @return requested message + */ + private String getMessage(String key) { + return PMDPlugin.getDefault().getMessage(key); + } +}