From eca1f7c8efeb9ea05a4b7de6de123e650ab1bce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Mon, 14 Nov 2016 00:10:33 -0300 Subject: [PATCH] Remove synchronization from RuleContext --- .../java/net/sourceforge/pmd/RuleContext.java | 188 ++++++++++-------- 1 file changed, 104 insertions(+), 84 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java index 424a7e8244..529204454b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java @@ -4,27 +4,27 @@ package net.sourceforge.pmd; import java.io.File; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import net.sourceforge.pmd.lang.LanguageVersion; /** - * The RuleContext provides access to Rule processing state. This information + * The RuleContext provides access to Rule processing state. This information * includes the following global information: * * As well as the following source file specific information: * - * It is required that all source file specific options - * be set between calls to difference source files. Failure to do so, may - * result in undefined behavior. + * It is required that all source file specific options be set + * between calls to difference source files. Failure to do so, may result in + * undefined behavior. */ public class RuleContext { @@ -32,175 +32,193 @@ public class RuleContext { private File sourceCodeFile; private String sourceCodeFilename; private LanguageVersion languageVersion; - private final Map attributes; + private final ConcurrentMap attributes; private boolean ignoreExceptions = true; /** * Default constructor. */ public RuleContext() { - attributes = new ConcurrentHashMap<>(); + attributes = new ConcurrentHashMap<>(); } /** - * Constructor which shares attributes and report listeners with the given RuleContext. - * @param ruleContext the context from which the values are shared + * Constructor which shares attributes and report listeners with the given + * RuleContext. + * + * @param ruleContext + * the context from which the values are shared */ public RuleContext(RuleContext ruleContext) { - this.attributes = ruleContext.attributes; - this.report.addSynchronizedListeners(ruleContext.getReport().getSynchronizedListeners()); + this.attributes = ruleContext.attributes; + this.report.addSynchronizedListeners(ruleContext.getReport().getSynchronizedListeners()); } /** * Get the Report to which Rule Violations are sent. + * * @return The Report. */ public Report getReport() { - return report; + return report; } /** * Set the Report to which Rule Violations are sent. - * @param report The Report. + * + * @param report + * The Report. */ public void setReport(Report report) { - this.report = report; + this.report = report; } /** * Get the File associated with the current source file. + * * @return The File. */ public File getSourceCodeFile() { - return sourceCodeFile; + return sourceCodeFile; } /** - * Set the File associated with the current source file. - * While this may be set to null, the exclude/include - * facilities will not work properly without a File. - * @param sourceCodeFile The File. + * Set the File associated with the current source file. While this may be + * set to null, the exclude/include facilities will not work + * properly without a File. + * + * @param sourceCodeFile + * The File. */ public void setSourceCodeFile(File sourceCodeFile) { - this.sourceCodeFile = sourceCodeFile; + this.sourceCodeFile = sourceCodeFile; } /** * Get the file name associated with the current source file. + * * @return The file name. */ public String getSourceCodeFilename() { - return sourceCodeFilename; + return sourceCodeFilename; } /** * Set the file name associated with the current source file. - * @param filename The file name. + * + * @param filename + * The file name. */ public void setSourceCodeFilename(String filename) { - this.sourceCodeFilename = filename; + this.sourceCodeFilename = filename; } /** * Get the LanguageVersion associated with the current source file. + * * @return The LanguageVersion, null if unknown. */ public LanguageVersion getLanguageVersion() { - return this.languageVersion; + return this.languageVersion; } /** - * Set the LanguageVersion associated with the current source file. - * This may be set to null to indicate the version is - * unknown and should be automatically determined. + * Set the LanguageVersion associated with the current source file. This may + * be set to null to indicate the version is unknown and should + * be automatically determined. * - * @param languageVersion The LanguageVersion. + * @param languageVersion + * The LanguageVersion. */ public void setLanguageVersion(LanguageVersion languageVersion) { - this.languageVersion = languageVersion; + this.languageVersion = languageVersion; } /** * Set an attribute value on the RuleContext, if it does not already exist. *

- * Attributes can be shared between RuleContext instances. This operation - * is thread-safe. + * Attributes can be shared between RuleContext instances. This operation is + * thread-safe. *

* Attribute values should be modified directly via the reference provided. * It is not necessary to call setAttribute(String, Object) to - * update an attribute value. Modifications made to the attribute value - * will automatically be seen by other threads. Because of this, you must - * ensure the attribute values are themselves thread safe. + * update an attribute value. Modifications made to the attribute value will + * automatically be seen by other threads. Because of this, you must ensure + * the attribute values are themselves thread safe. * - * @param name The attribute name. - * @param value The attribute value. - * @exception IllegalArgumentException if name or value are null - * @return true if the attribute was set, false otherwise. + * @param name + * The attribute name. + * @param value + * The attribute value. + * @exception IllegalArgumentException + * if name or value are + * null + * @return true if the attribute was set, false + * otherwise. */ public boolean setAttribute(String name, Object value) { - if (name == null) { - throw new IllegalArgumentException("Parameter 'name' cannot be null."); - } - if (value == null) { - throw new IllegalArgumentException("Parameter 'value' cannot be null."); - } - synchronized (this.attributes) { - if (!this.attributes.containsKey(name)) { - this.attributes.put(name, value); - return true; - } else { - return false; - } - } + if (name == null) { + throw new IllegalArgumentException("Parameter 'name' cannot be null."); + } + if (value == null) { + throw new IllegalArgumentException("Parameter 'value' cannot be null."); + } + return this.attributes.putIfAbsent(name, value) == null; } /** * Get an attribute value on the RuleContext. *

- * Attributes can be shared between RuleContext instances. This operation - * is thread-safe. + * Attributes can be shared between RuleContext instances. This operation is + * thread-safe. *

* Attribute values should be modified directly via the reference provided. * It is not necessary to call setAttribute(String, Object) to - * update an attribute value. Modifications made to the attribute value - * will automatically be seen by other threads. Because of this, you must - * ensure the attribute values are themselves thread safe. + * update an attribute value. Modifications made to the attribute value will + * automatically be seen by other threads. Because of this, you must ensure + * the attribute values are themselves thread safe. * - * @param name The attribute name. - * @return The current attribute value, or null if the attribute does not exist. + * @param name + * The attribute name. + * @return The current attribute value, or null if the + * attribute does not exist. */ public Object getAttribute(String name) { - return this.attributes.get(name); + return this.attributes.get(name); } /** * Remove an attribute value on the RuleContext. *

- * Attributes can be shared between RuleContext instances. This operation - * is thread-safe. + * Attributes can be shared between RuleContext instances. This operation is + * thread-safe. *

* Attribute values should be modified directly via the reference provided. * It is not necessary to call setAttribute(String, Object) to - * update an attribute value. Modifications made to the attribute value - * will automatically be seen by other threads. Because of this, you must - * ensure the attribute values are themselves thread safe. + * update an attribute value. Modifications made to the attribute value will + * automatically be seen by other threads. Because of this, you must ensure + * the attribute values are themselves thread safe. * - * @param name The attribute name. - * @return The current attribute value, or null if the attribute does not exist. + * @param name + * The attribute name. + * @return The current attribute value, or null if the + * attribute does not exist. */ public Object removeAttribute(String name) { - return this.attributes.remove(name); + return this.attributes.remove(name); } /** - * Configure whether exceptions during applying a rule should be ignored or not. - * If set to true then such exceptions are logged as warnings and - * the processing is continued with the next rule - the failing rule is simply skipped. - * This is the default behavior. - *
- * If set to false then the processing will be aborted with the exception. - * This is especially useful during unit tests, in order to not oversee any exceptions. - * @param ignoreExceptions if true simply skip failing rules (default). + * Configure whether exceptions during applying a rule should be ignored or + * not. If set to true then such exceptions are logged as + * warnings and the processing is continued with the next rule - the failing + * rule is simply skipped. This is the default behavior.
+ * If set to false then the processing will be aborted with the + * exception. This is especially useful during unit tests, in order to not + * oversee any exceptions. + * + * @param ignoreExceptions + * if true simply skip failing rules (default). */ public void setIgnoreExceptions(boolean ignoreExceptions) { this.ignoreExceptions = ignoreExceptions; @@ -208,9 +226,11 @@ public class RuleContext { /** * Gets the configuration whether to skip failing rules (true) - * or whether to throw a a RuntimeException and abort the processing for the first - * failing rule. - * @return true when failing rules are skipped, false otherwise. + * or whether to throw a a RuntimeException and abort the processing for the + * first failing rule. + * + * @return true when failing rules are skipped, + * false otherwise. */ public boolean isIgnoreExceptions() { return ignoreExceptions;