View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.processor;
5   
6   import java.util.LinkedList;
7   import java.util.List;
8   import java.util.concurrent.ExecutionException;
9   import java.util.concurrent.ExecutorService;
10  import java.util.concurrent.Executors;
11  import java.util.concurrent.Future;
12  
13  import net.sourceforge.pmd.PMDConfiguration;
14  import net.sourceforge.pmd.Report;
15  import net.sourceforge.pmd.RuleContext;
16  import net.sourceforge.pmd.RuleSetFactory;
17  import net.sourceforge.pmd.RuleSets;
18  import net.sourceforge.pmd.renderers.Renderer;
19  import net.sourceforge.pmd.util.datasource.DataSource;
20  
21  /**
22   * @author Romain Pelisse <belaran@gmail.com>
23   *
24   */
25  public class MultiThreadProcessor extends AbstractPMDProcessor {
26  
27  
28  	public MultiThreadProcessor(final PMDConfiguration configuration) {
29  		super(configuration);
30  	}
31  
32  	/**
33  	 * Run PMD on a list of files using multiple threads.
34  	 */
35  	public void processFiles(final RuleSetFactory ruleSetFactory, final List<DataSource> files,
36  			final RuleContext ctx, final List<Renderer> renderers) {
37  
38  		RuleSets rs = createRuleSets(ruleSetFactory);
39  		rs.start(ctx);
40  
41  		PmdThreadFactory factory = new PmdThreadFactory(ruleSetFactory, ctx);
42  		ExecutorService executor = Executors.newFixedThreadPool(
43  				configuration.getThreads(), factory);
44  		List<Future<Report>> tasks = new LinkedList<Future<Report>>();
45  
46  		for (DataSource dataSource : files) {
47  			String niceFileName = filenameFrom(dataSource);
48  
49  			PmdRunnable r = new PmdRunnable(executor, configuration,
50  					dataSource, niceFileName, renderers);
51  			Future<Report> future = executor.submit(r);
52  			tasks.add(future);
53  		}
54  		executor.shutdown();
55  
56  		processReports(renderers, tasks);
57  		
58  		rs.end(ctx);
59  		super.renderReports(renderers, ctx.getReport());
60  
61  	}
62  
63  	private void processReports(final List<Renderer> renderers, List<Future<Report>> tasks) throws Error {
64  		
65  		while (!tasks.isEmpty()) {
66  			Future<Report> future = tasks.remove(0);
67  			Report report = null;
68  			try {
69  				report = future.get();
70  			} catch (InterruptedException ie) {
71  				Thread.currentThread().interrupt();
72  				future.cancel(true);
73  			} catch (ExecutionException ee) {
74  				Throwable t = ee.getCause();
75  				if (t instanceof RuntimeException) {
76  					throw (RuntimeException) t;
77  				} else if (t instanceof Error) {
78  					throw (Error) t;
79  				} else {
80  					throw new IllegalStateException(
81  							"PmdRunnable exception", t);
82  				}
83  			}
84  
85  			super.renderReports(renderers, report);
86  		}
87  	}
88  
89  }