66
77import java .util .ArrayList ;
88import java .util .Collection ;
9+ import java .util .Collections ;
910import java .util .HashMap ;
1011import java .util .HashSet ;
1112import java .util .List ;
@@ -176,7 +177,14 @@ public void execute() {
176177 ruleCount = 0 ;
177178 pmdDuration = 0 ;
178179
179- beginTask ("PMD checking..." , getStepCount ());
180+ String projectList = determineProjectList ();
181+ int totalWork = determineTotalWork ();
182+ LOG .info ("Found {} resources in projects {}" , totalWork , projectList );
183+ setStepCount (totalWork ); // mostly for unit tests
184+
185+ StringBuilder mainTaskName = new StringBuilder (projectList .length () + 20 );
186+ mainTaskName .append ("Executing PMD for " ).append (projectList ).append (" ..." );
187+ beginTask (mainTaskName .toString (), totalWork );
180188
181189 // Lancer PMD
182190 // PMDPlugin fills resources if it's a full build and
@@ -257,6 +265,114 @@ public void run() {
257265 PMDPlugin .getDefault ().changedFiles (markedFiles ());
258266 }
259267
268+ private int determineTotalWork () {
269+ boolean useFileExtensions = PMDPlugin .getDefault ().loadPreferences ().isDetermineFiletypesAutomatically ();
270+ Map <IProject , Set <String >> fileExtensionsPerProject = new HashMap <>();
271+ CountVisitor2 visitor = new CountVisitor2 (useFileExtensions , fileExtensionsPerProject );
272+
273+ for (IResource resource : resources ) {
274+ determineFileExtensions (fileExtensionsPerProject , resource );
275+
276+ try {
277+ if (resource instanceof IProject && ((IProject ) resource ).hasNature (JavaCore .NATURE_ID )) {
278+ for (IResource sourceFolder : getJavaProjectSourceFolders ((IProject ) resource )) {
279+ sourceFolder .accept (visitor );
280+ }
281+ } else {
282+ resource .accept (visitor );
283+ }
284+ } catch (CoreException e ) {
285+ LOG .warn ("Error while counting resources for {}" , resource , e );
286+ }
287+ }
288+ if (resourceDelta != null ) {
289+ IResource resource = resourceDelta .getResource ();
290+ determineFileExtensions (fileExtensionsPerProject , resource );
291+ try {
292+ resource .accept (visitor );
293+ } catch (CoreException e ) {
294+ LOG .warn ("Error while counting resources for {} (delta)" , resource , e );
295+ }
296+ }
297+ return visitor .getCount ();
298+ }
299+
300+ private void determineFileExtensions (Map <IProject , Set <String >> fileExtensionsPerProject , IResource resource ) {
301+ IProject project = resource .getProject ();
302+ if (project != null && !fileExtensionsPerProject .containsKey (project )) {
303+ try {
304+ RuleSets rulesets = rulesetsFrom (resource );
305+ Set <String > fileExtensions = determineFileExtensions (rulesets );
306+ fileExtensionsPerProject .put (project , fileExtensions );
307+ } catch (PropertiesException e ) {
308+ LOG .warn ("Error while determining file extensions for project {}" , project , e );
309+ fileExtensionsPerProject .put (project , Collections .<String >emptySet ());
310+ }
311+ }
312+ }
313+
314+ private static class CountVisitor2 implements IResourceVisitor {
315+ private final boolean useFileExtensions ;
316+ private final Map <IProject , Set <String >> fileExtensionsPerProject ;
317+ private int count ;
318+
319+ CountVisitor2 (boolean useFileExtensions , Map <IProject , Set <String >> fileExtensionsPerProject ) {
320+ this .useFileExtensions = useFileExtensions ;
321+ this .fileExtensionsPerProject = fileExtensionsPerProject ;
322+ }
323+
324+ CountVisitor2 (boolean useFileExtensions , IProject project , Set <String > fileExtensions ) {
325+ this .useFileExtensions = useFileExtensions ;
326+ this .fileExtensionsPerProject = new HashMap <>();
327+ this .fileExtensionsPerProject .put (project , fileExtensions );
328+ }
329+
330+ @ Override
331+ public boolean visit (IResource resource ) throws CoreException {
332+ if (resource instanceof IFile ) {
333+ if (useFileExtensions ) {
334+ Set <String > extensions = fileExtensionsPerProject .get (resource .getProject ());
335+ if (extensions != null && extensions .contains (resource .getFileExtension ().toLowerCase (Locale .ROOT ))) {
336+ count ++;
337+ }
338+ } else {
339+ // count all files
340+ count ++;
341+ }
342+ }
343+ return true ;
344+ }
345+
346+ public int getCount () {
347+ return count ;
348+ }
349+ }
350+
351+ private String determineProjectList () {
352+ Set <IProject > projects = new HashSet <>();
353+ for (IResource resource : resources ) {
354+ IProject project = resource .getProject ();
355+ if (project != null ) {
356+ projects .add (project );
357+ }
358+ }
359+ if (resourceDelta != null ) {
360+ IProject project = resourceDelta .getResource ().getProject ();
361+ if (project != null ) {
362+ projects .add (project );
363+ }
364+ }
365+ StringBuilder projectList = new StringBuilder (projects .size () * 20 );
366+ projectList .append ('[' );
367+ for (IProject project : projects ) {
368+ projectList .append (project .getName ());
369+ projectList .append (", " );
370+ }
371+ projectList .delete (projectList .length () - 2 , projectList .length ());
372+ projectList .append (']' );
373+ return projectList .toString ();
374+ }
375+
260376 public Map <IFile , Set <MarkerInfo2 >> getMarkers () {
261377 return markersByFile ;
262378 }
@@ -365,18 +481,14 @@ private ISchedulingRule getSchedulingRule() {
365481 * Process the list of workbench resources
366482 */
367483 private void processResources () {
368- Set <String > projects = new HashSet <String >();
369484 for (IResource resource : resources ) {
370- projects .add (resource .getProject ().getName ());
371- }
372- LOG .info ("ReviewCodeCmd started with {} selected resources on project {}" , resources .size (), projects );
373-
374- for (IResource resource : resources ) {
375- // if resource is a project, visit only its source folders
376- if (resource instanceof IProject ) {
377- processProject ((IProject ) resource );
378- } else {
379- processResource (resource );
485+ if (!isCanceled ()) {
486+ // if resource is a project, visit only its source folders
487+ if (resource instanceof IProject ) {
488+ processProject ((IProject ) resource );
489+ } else {
490+ processResource (resource );
491+ }
380492 }
381493 }
382494 }
@@ -396,7 +508,7 @@ private RuleSets rulesetsFrom(IResource resource) throws PropertiesException {
396508 }
397509
398510 /**
399- * Review a single resource.
511+ * Review a single resource. The given resource might be a directory, though.
400512 */
401513 private void processResource (IResource resource ) {
402514 try {
@@ -412,7 +524,7 @@ private void processResource(IResource resource) {
412524 // final PMDEngine pmdEngine = getPmdEngineForProject(project);
413525 int targetCount = 0 ;
414526 if (resource .exists ()) {
415- targetCount = countResourceElement (resource );
527+ targetCount = countResourceElement (resource , fileExtensions );
416528 }
417529 // Could add a property that lets us set the max number to analyze
418530 if (properties .isFullBuildEnabled () || isUserInitiated () || targetCount <= MAXIMUM_RESOURCE_COUNT ) {
@@ -441,7 +553,6 @@ private void processResource(IResource resource) {
441553 + "If you want to execute PMD, please check \" Full build enabled\" in the project settings." ,
442554 resource .getName (), targetCount , MAXIMUM_RESOURCE_COUNT );
443555 }
444- worked (1 ); // TODO - temp fix? BR
445556
446557 } catch (PropertiesException e ) {
447558 throw new RuntimeException (e );
@@ -461,7 +572,7 @@ private Set<String> determineFileExtensions(RuleSets ruleSets) {
461572 fileExtensions .add (extension .toLowerCase (Locale .ROOT ));
462573 }
463574 }
464- LOG .info ("Determined applicable file extensions: {}" , fileExtensions );
575+ LOG .debug ("Determined applicable file extensions: {}" , fileExtensions );
465576 return fileExtensions ;
466577 }
467578
@@ -470,8 +581,7 @@ private Set<String> determineFileExtensions(RuleSets ruleSets) {
470581 */
471582 private void processProject (IProject project ) {
472583 try {
473- setStepCount (countResourceElement (project ));
474- LOG .info ("ReviewCodeCmd: visiting {}: {} resources found." , project , getStepCount ());
584+ subTask ("Review " + project );
475585
476586 if (project .hasNature (JavaCore .NATURE_ID )) {
477587 processJavaProject (project );
@@ -485,6 +595,13 @@ private void processProject(IProject project) {
485595 }
486596
487597 private void processJavaProject (IProject project ) throws CoreException {
598+ for (IResource sourceFolder : getJavaProjectSourceFolders (project )) {
599+ processResource (sourceFolder );
600+ }
601+ }
602+
603+ private List <IResource > getJavaProjectSourceFolders (IProject project ) throws CoreException {
604+ List <IResource > sourceFolders = new ArrayList <>();
488605 final IJavaProject javaProject = JavaCore .create (project );
489606 final IClasspathEntry [] entries = javaProject .getRawClasspath ();
490607 final IWorkspaceRoot root = ResourcesPlugin .getWorkspace ().getRoot ();
@@ -507,10 +624,11 @@ private void processJavaProject(IProject project) throws CoreException {
507624 if (sourceContainer == null ) {
508625 LOG .warn ("Source container {} for project {} is not valid" , entrie .getPath (), project );
509626 } else {
510- processResource (sourceContainer );
627+ sourceFolders . add (sourceContainer );
511628 }
512629 }
513630 }
631+ return sourceFolders ;
514632 }
515633
516634 private void taskScope (int activeRuleCount , int totalRuleCount ) {
@@ -650,25 +768,33 @@ private void applyMarkers() {
650768 /**
651769 * Count the number of sub-resources of a resource.
652770 *
653- * @param resource
654- * a project
771+ * @param resource a project
772+ * @param fileExtensions the file extensions that should match
655773 * @return the element count
656774 */
657- private int countResourceElement (IResource resource ) {
775+ private int countResourceElement (IResource resource , Set <String > fileExtensions ) {
776+ boolean checkFileExtensions = PMDPlugin .getDefault ().loadPreferences ().isDetermineFiletypesAutomatically ();
658777
659778 if (resource instanceof IFile ) {
779+ if (checkFileExtensions && fileExtensions != null ) {
780+ if (fileExtensions .contains (resource .getFileExtension ().toLowerCase (Locale .ROOT ))) {
781+ return 1 ;
782+ } else {
783+ return 0 ;
784+ }
785+ }
660786 return 1 ;
661787 }
662788
663- final CountVisitor visitor = new CountVisitor ( );
789+ final CountVisitor2 visitor = new CountVisitor2 ( checkFileExtensions , resource . getProject (), fileExtensions );
664790
665791 try {
666792 resource .accept (visitor );
667793 } catch (CoreException e ) {
668794 LOG .error ("Exception when counting elements of a project: {}" , e .toString (), e );
669795 }
670796
671- return visitor .count ;
797+ return visitor .getCount () ;
672798 }
673799
674800 /**
0 commit comments