From 5c07effa9618014fbcfc7358b1486663d68448e9 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Wed, 8 Feb 2012 19:59:29 +0400 Subject: [PATCH] Reduce number of static fields in CheckstyleSquidBridge --- .../sonar/java/ast/CheckstyleSquidBridge.java | 54 +++--------- .../ast/CheckstyleSquidBridgeContext.java | 87 +++++++++++++++++++ .../org/sonar/java/ast/JavaAstScanner.java | 19 ++-- 3 files changed, 114 insertions(+), 46 deletions(-) create mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridgeContext.java diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridge.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridge.java index 2bdeb423c70..901753b4ebc 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridge.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridge.java @@ -19,63 +19,33 @@ */ package org.sonar.java.ast; -import com.google.common.collect.Maps; import com.puppycrawl.tools.checkstyle.api.Check; import com.puppycrawl.tools.checkstyle.api.DetailAST; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.resources.InputFile; import org.sonar.java.ast.visitor.JavaAstVisitor; -import org.sonar.java.recognizer.JavaFootprint; -import org.sonar.java.squid.JavaSquidConfiguration; -import org.sonar.squid.recognizer.CodeRecognizer; import org.sonar.squid.text.Source; -import java.io.File; -import java.util.*; - /** * Delegate from Checkstyle {@link Check} to {@link JavaAstVisitor}s. */ public class CheckstyleSquidBridge extends Check { private static Logger logger = LoggerFactory.getLogger(CheckstyleSquidBridge.class); - private static JavaAstVisitor[] visitors; - private static int[] allTokens; - private static CodeRecognizer codeRecognizer; - private static Map inputFilesByPath = Maps.newHashMap(); - static void setASTVisitors(List visitors) { - CheckstyleSquidBridge.visitors = visitors.toArray(new JavaAstVisitor[visitors.size()]); - SortedSet sorter = new TreeSet(); - for (JavaAstVisitor visitor : visitors) { - sorter.addAll(visitor.getWantedTokens()); - allTokens = new int[sorter.size()]; - int i = 0; - for (Integer itSorted : sorter) { - allTokens[i++] = itSorted; - } - } - } + private static CheckstyleSquidBridgeContext bridgeContext; - static void setSquidConfiguration(JavaSquidConfiguration conf) { - codeRecognizer = new CodeRecognizer(conf.getCommentedCodeThreshold(), new JavaFootprint()); + /** + * @see CheckstyleSquidBridgeContext + */ + static void setContext(CheckstyleSquidBridgeContext context) { + bridgeContext = context; } @Override public int[] getDefaultTokens() { - return allTokens; //NOSONAR returning directly the array is not a security flaw here - } - - public static InputFile getInputFile(File path) { - return inputFilesByPath.get(path); - } - - public static void setInputFiles(Collection inputFiles) { - inputFilesByPath.clear(); - for (InputFile inputFile : inputFiles) { - inputFilesByPath.put(inputFile.getFile().getAbsoluteFile(), inputFile); - } + return bridgeContext.getAllTokens(); } @Override @@ -83,8 +53,8 @@ public class CheckstyleSquidBridge extends Check { try { String filename = getFileContents().getFilename(); Source source = createSource(); - InputFile inputFile = getInputFile(new java.io.File(filename)); - for (JavaAstVisitor visitor : visitors) { + InputFile inputFile = bridgeContext.getInputFile(new java.io.File(filename)); + for (JavaAstVisitor visitor : bridgeContext.getVisitors()) { visitor.setFileContents(getFileContents()); visitor.setSource(source); visitor.setInputFile(inputFile); @@ -96,13 +66,13 @@ public class CheckstyleSquidBridge extends Check { } private Source createSource() { - return new Source(getFileContents().getLines(), codeRecognizer); + return new Source(getFileContents().getLines(), bridgeContext.getCodeRecognizer()); } @Override public void visitToken(DetailAST ast) { try { - for (JavaAstVisitor visitor : visitors) { + for (JavaAstVisitor visitor : bridgeContext.getVisitors()) { if (visitor.getWantedTokens().contains(ast.getType())) { visitor.visitToken(ast); } @@ -114,6 +84,7 @@ public class CheckstyleSquidBridge extends Check { @Override public void leaveToken(DetailAST ast) { + JavaAstVisitor[] visitors = bridgeContext.getVisitors(); try { for (int i = visitors.length - 1; i >= 0; i--) { JavaAstVisitor visitor = visitors[i]; @@ -128,6 +99,7 @@ public class CheckstyleSquidBridge extends Check { @Override public void finishTree(DetailAST ast) { + JavaAstVisitor[] visitors = bridgeContext.getVisitors(); try { for (int i = visitors.length - 1; i >= 0; i--) { JavaAstVisitor visitor = visitors[i]; diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridgeContext.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridgeContext.java new file mode 100644 index 00000000000..b550887374d --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/CheckstyleSquidBridgeContext.java @@ -0,0 +1,87 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.java.ast; + +import com.google.common.collect.Maps; +import org.sonar.api.resources.InputFile; +import org.sonar.java.ast.visitor.JavaAstVisitor; +import org.sonar.java.recognizer.JavaFootprint; +import org.sonar.java.squid.JavaSquidConfiguration; +import org.sonar.squid.recognizer.CodeRecognizer; + +import java.io.File; +import java.util.*; + +/** + * This class helps to transfer additional information into {@link CheckstyleSquidBridge}. + * We forced to use static fields in {@link CheckstyleSquidBridge}, + * because it will be instantiated by Checkstyle, so there is no other way of communication. + */ +class CheckstyleSquidBridgeContext { + + private int[] allTokens; + private JavaAstVisitor[] visitors; + private CodeRecognizer codeRecognizer; + private Map inputFilesByPath = Maps.newHashMap(); + + public CheckstyleSquidBridgeContext setASTVisitors(List visitors) { + this.visitors = visitors.toArray(new JavaAstVisitor[visitors.size()]); + SortedSet sorter = new TreeSet(); + for (JavaAstVisitor visitor : visitors) { + sorter.addAll(visitor.getWantedTokens()); + allTokens = new int[sorter.size()]; + int i = 0; + for (Integer itSorted : sorter) { + allTokens[i++] = itSorted; + } + } + return this; + } + + public CheckstyleSquidBridgeContext setSquidConfiguration(JavaSquidConfiguration conf) { + codeRecognizer = new CodeRecognizer(conf.getCommentedCodeThreshold(), new JavaFootprint()); + return this; + } + + public CheckstyleSquidBridgeContext setInputFiles(Collection inputFiles) { + inputFilesByPath.clear(); + for (InputFile inputFile : inputFiles) { + inputFilesByPath.put(inputFile.getFile().getAbsoluteFile(), inputFile); + } + return this; + } + + public int[] getAllTokens() { + return allTokens; + } + + public InputFile getInputFile(File path) { + return inputFilesByPath.get(path); + } + + public CodeRecognizer getCodeRecognizer() { + return codeRecognizer; + } + + public JavaAstVisitor[] getVisitors() { + return visitors; + } + +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java index 32d3b9c38b4..761cbe88dfb 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java @@ -91,10 +91,19 @@ public class JavaAstScanner extends CodeScanner { for (JavaAstVisitor visitor : getVisitors()) { visitor.setSourceCodeStack(resourcesStack); } - CheckstyleSquidBridge.setASTVisitors(getVisitors()); - CheckstyleSquidBridge.setSquidConfiguration(conf); - CheckstyleSquidBridge.setInputFiles(inputFiles); - launchCheckstyle(InputFileUtils.toFiles(inputFiles), conf.getCharset()); + + CheckstyleSquidBridgeContext bridgeContext = new CheckstyleSquidBridgeContext() + .setASTVisitors(getVisitors()) + .setSquidConfiguration(conf) + .setInputFiles(inputFiles); + + CheckstyleSquidBridge.setContext(bridgeContext); + try { + launchCheckstyle(InputFileUtils.toFiles(inputFiles), conf.getCharset()); + } finally { + // Garbage collector should be able to do his job, so we must clean context after execution + CheckstyleSquidBridge.setContext(null); + } return this; } @@ -105,7 +114,7 @@ public class JavaAstScanner extends CodeScanner { try { c.setClassloader(getClass().getClassLoader()); c.setModuleClassLoader(getClass().getClassLoader()); - c.process(Lists.newArrayList(files)); + c.process(Lists. newArrayList(files)); c.destroy(); } finally { Thread.currentThread().setContextClassLoader(initialClassLoader); -- 2.39.5