View Javadoc

    1   package net.sourceforge.pmd.processor;
    2
    3   import java.io.BufferedInputStream;
    4   import java.io.IOException;
    5   import java.io.InputStream;
    6   import java.util.List;
    7   import java.util.concurrent.Callable;
    8   import java.util.concurrent.ExecutorService;
    9   import java.util.logging.Level;
    10  import java.util.logging.Logger;
    11
    12  import net.sourceforge.pmd.PMDConfiguration;
    13  import net.sourceforge.pmd.PMD;
    14  import net.sourceforge.pmd.PMDException;
    15  import net.sourceforge.pmd.Report;
    16  import net.sourceforge.pmd.RuleContext;
    17  import net.sourceforge.pmd.RuleSetFactory;
    18  import net.sourceforge.pmd.RuleSets;
    19  import net.sourceforge.pmd.renderers.Renderer;
    20  import net.sourceforge.pmd.util.datasource.DataSource;
    21
    22  public class PmdRunnable extends PMD implements Callable<Report> {
    23
    24  	private static final Logger LOG = Logger.getLogger(PmdRunnable.class.getName());
    25
    26  	private final ExecutorService executor;
    27  	private final DataSource dataSource;
    28  	private final String fileName;
    29  	private final List<Renderer> renderers;
    30
    31  	public PmdRunnable(ExecutorService executor,
    32  			PMDConfiguration configuration, DataSource dataSource,
    33  			String fileName, List<Renderer> renderers) {
    34  		super(configuration);
    35  		this.executor = executor;
    36  		this.dataSource = dataSource;
    37  		this.fileName = fileName;
    38  		this.renderers = renderers;
    39  	}
    40
    41  	// If we ever end up having a ReportUtil class, this method should be moved there...
    42  	private static void addError(Report report, Exception ex, String fileName) {
    43  		report.addError(
    44  				new Report.ProcessingError(ex.getMessage(),
    45  				fileName)
    46  				);
    47  	}
    48
    49  	private void addErrorAndShutdown(Report report, Exception e, String errorMessage) {
    50  		// unexpected exception: log and stop executor service
    51  		LOG.log(Level.FINE, errorMessage, e);
    52  		addError(report, e, fileName);
    53  		executor.shutdownNow();
    54  	}
    55
    56  	public Report call() {
    57  		PmdThread thread = (PmdThread) Thread.currentThread();
    58
    59  		RuleContext ctx = thread.getRuleContext();
    60  		RuleSets rs = thread.getRuleSets(configuration.getRuleSets());
    61
    62  		Report report = setupReport(rs, ctx, fileName);
    63
    64  		if (LOG.isLoggable(Level.FINE)) {
    65  			LOG.fine("Processing " + ctx.getSourceCodeFilename());
    66  		}
    67  		for (Renderer r : renderers) {
    68  			r.startFileAnalysis(dataSource);
    69  		}
    70
    71  		try {
    72  			InputStream stream = new BufferedInputStream(
    73  					dataSource.getInputStream());
    74  			ctx.setLanguageVersion(null);
    75  			this.getSourceCodeProcessor().processSourceCode(stream, rs, ctx);
    76  		} catch (PMDException pmde) {
    77  			LOG.log(Level.FINE, "Error while processing file", pmde.getCause());
    78  			addError(report, pmde, fileName);
    79  		} catch (IOException ioe) {
    80  			addErrorAndShutdown(report, ioe, "IOException during processing");
    81
    82  		} catch (RuntimeException re) {
    83  			addErrorAndShutdown(report, re,"RuntimeException during processing");
    84  		}
    85  		return report;
    86  	}
    87
    88  	private static class PmdThread extends Thread {
    89
    90  		public PmdThread(int id, Runnable r, RuleSetFactory ruleSetFactory,
    91  				RuleContext ctx) {
    92  			super(r, "PmdThread " + id);
    93  			this.id = id;
    94  			context = new RuleContext(ctx);
    95  			this.ruleSetFactory = ruleSetFactory;
    96  		}
    97
    98  		private final int id;
    99  		private RuleContext context;
    100 		private RuleSets rulesets;
    101 		private final RuleSetFactory ruleSetFactory;
    102
    103 		public RuleContext getRuleContext() {
    104 			return context;
    105 		}
    106
    107 		public RuleSets getRuleSets(String rsList) {
    108 			if (rulesets == null) {
    109 				try {
    110 					rulesets = ruleSetFactory.createRuleSets(rsList);
    111 				} catch (Exception e) {
    112 					e.printStackTrace();
    113 				}
    114 			}
    115 			return rulesets;
    116 		}
    117
    118 		@Override
    119 		public String toString() {
    120 			return "PmdThread " + id;
    121 		}
    122 	}
    123
    124 	public static Thread createThread(int id, Runnable r,
    125 			RuleSetFactory ruleSetFactory, RuleContext ctx) {
    126 		return new PmdThread(id, r,ruleSetFactory, ctx);
    127 	}
    128 }