diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-27 14:02:58 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-28 08:37:33 +0200 |
commit | bbee5baf5579ae037ef9ccae69fc93ca85bfc1cd (patch) | |
tree | 6ea90107d097c30f3e2ad824af556e9a95dda80d /sonar-runner-api/src/main/java | |
parent | 149e5920791741c9af8ec9e277576988cb1ee949 (diff) | |
download | sonar-scanner-cli-bbee5baf5579ae037ef9ccae69fc93ca85bfc1cd.tar.gz sonar-scanner-cli-bbee5baf5579ae037ef9ccae69fc93ca85bfc1cd.zip |
Back compatibility with SQ 4.5
Diffstat (limited to 'sonar-runner-api/src/main/java')
10 files changed, 382 insertions, 127 deletions
diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/api/EmbeddedRunner.java b/sonar-runner-api/src/main/java/org/sonar/runner/api/EmbeddedRunner.java index 5c50fa9..2a22a05 100644 --- a/sonar-runner-api/src/main/java/org/sonar/runner/api/EmbeddedRunner.java +++ b/sonar-runner-api/src/main/java/org/sonar/runner/api/EmbeddedRunner.java @@ -19,13 +19,17 @@ */ package org.sonar.runner.api; -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; +import org.sonar.runner.impl.ClassloadRules; + import java.nio.charset.Charset; import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; import java.util.Locale; import java.util.Properties; +import java.util.Set; import javax.annotation.Nullable; @@ -44,12 +48,16 @@ public class EmbeddedRunner { private IsolatedLauncher launcher; private final LogOutput logOutput; private final Properties globalProperties = new Properties(); + private final List<Object> extensions = new ArrayList<>(); private final Logger logger; + private final Set<String> classloaderMask = new HashSet<>(); + private final Set<String> classloaderUnmask = new HashSet<>(); EmbeddedRunner(IsolatedLauncherFactory bl, Logger logger, LogOutput logOutput) { this.logger = logger; this.launcherFactory = bl; this.logOutput = logOutput; + this.classloaderUnmask.add("org.sonar.runner.batch."); } public static EmbeddedRunner create(final LogOutput logOutput) { @@ -63,8 +71,22 @@ public class EmbeddedRunner { return clone; } + public EmbeddedRunner unmask(String fqcnPrefix) { + checkLauncherDoesntExist(); + classloaderUnmask.add(fqcnPrefix); + return this; + } + + public EmbeddedRunner mask(String fqcnPrefix) { + checkLauncherDoesntExist(); + classloaderMask.add(fqcnPrefix); + return this; + } + /** * Declare Sonar properties, for example sonar.projectKey=>foo. + * These might be used at different stages (on {@link #start() or #runAnalysis(Properties)}, depending on the + * property and SQ version. * * @see #setProperty(String, String) */ @@ -75,6 +97,8 @@ public class EmbeddedRunner { /** * Declare a SonarQube property. + * These might be used at different stages (on {@link #start() or #runAnalysis(Properties)}, depending on the + * property and SQ version. * * @see RunnerProperties * @see ScanProperties @@ -101,30 +125,51 @@ public class EmbeddedRunner { return globalProperty(InternalProperties.RUNNER_APP, null); } + /** + * Add extensions to the batch's object container. + * Only supported until SQ 5.1. For more recent versions, an exception is thrown + * @param objs + */ + public EmbeddedRunner addExtensions(Object... objs) { + checkLauncherExists(); + if (VersionUtils.isAtLeast52(launcher.getVersion())) { + throw new IllegalStateException("not supported in current SonarQube version: " + launcher.getVersion()); + } + + extensions.addAll(Arrays.asList(objs)); + return this; + } + public String appVersion() { return globalProperty(InternalProperties.RUNNER_APP_VERSION, null); } + /** + * Launch an analysis. + * Runner must have been started - see {@link #start()}. + */ public void runAnalysis(Properties analysisProperties) { runAnalysis(analysisProperties, null); } + /** + * Launch an analysis, providing optionally a issue listener. + * Runner must have been started - see {@link #start()}. + * Issue listener is supported starting in SQ 5.2. If a non-null listener is given for older versions, an exception is thrown + */ public void runAnalysis(Properties analysisProperties, @Nullable IssueListener issueListener) { checkLauncherExists(); Properties copy = new Properties(); copy.putAll(analysisProperties); initAnalysisProperties(copy); - - String dumpToFile = copy.getProperty(InternalProperties.RUNNER_DUMP_TO_FILE); - if (dumpToFile != null) { - File dumpFile = new File(dumpToFile); - Utils.writeProperties(dumpFile, copy); - logger.info("Simulation mode. Configuration written to " + dumpFile.getAbsolutePath()); - } else { - doExecute(copy, issueListener); - } + doExecute(copy, issueListener); } + /** + * Synchronizes the project's data in the local cache with the server, allowing analysis of the project to be done offline. + * Runner must have been started - see {@link #start()}. + * Only supported starting in SQ 5.2. For older versions, an exception is thrown + */ public void syncProject(String projectKey) { checkLauncherExists(); if (!VersionUtils.isAtLeast52(launcher.getVersion())) { @@ -142,16 +187,19 @@ public class EmbeddedRunner { doStart(forceSync); } + /** + * Stops the batch. + * Only supported starting in SQ 5.2. For older versions, this is a no-op. + */ public void stop() { checkLauncherExists(); doStop(); } - + public String serverVersion() { checkLauncherExists(); return launcher.getVersion(); } - /** * @deprecated since 2.5 use {@link #start()}, {@link #runAnalysis(Properties)} and then {@link #stop()} @@ -196,7 +244,9 @@ public class EmbeddedRunner { } protected void doStart(boolean forceSync) { - launcher = launcherFactory.createLauncher(globalProperties()); + checkLauncherDoesntExist(); + ClassloadRules rules = new ClassloadRules(classloaderMask, classloaderUnmask); + launcher = launcherFactory.createLauncher(globalProperties(), rules); if (VersionUtils.isAtLeast52(launcher.getVersion())) { launcher.start(globalProperties(), new org.sonar.runner.batch.LogOutput() { @@ -212,6 +262,7 @@ public class EmbeddedRunner { protected void doStop() { if (VersionUtils.isAtLeast52(launcher.getVersion())) { launcher.stop(); + launcher = null; } } @@ -229,80 +280,19 @@ public class EmbeddedRunner { Properties prop = new Properties(); prop.putAll(globalProperties()); prop.putAll(analysisProperties); - launcher.executeOldVersion(prop); + launcher.executeOldVersion(prop, extensions); } } - + private void checkLauncherExists() { - if(launcher == null) { + if (launcher == null) { throw new IllegalStateException("not started"); } } - static class IssueListenerAdapter implements org.sonar.runner.batch.IssueListener { - private IssueListener apiIssueListener; - - public IssueListenerAdapter(IssueListener apiIssueListener) { - this.apiIssueListener = apiIssueListener; - } - - @Override - public void handle(org.sonar.runner.batch.IssueListener.Issue issue) { - apiIssueListener.handle(transformIssue(issue)); - } - - private static org.sonar.runner.api.Issue transformIssue(org.sonar.runner.batch.IssueListener.Issue batchIssue) { - org.sonar.runner.api.Issue.Builder issueBuilder = org.sonar.runner.api.Issue.builder(); - - issueBuilder.setAssigneeLogin(batchIssue.getAssigneeLogin()); - issueBuilder.setAssigneeName(batchIssue.getAssigneeName()); - issueBuilder.setComponentKey(batchIssue.getComponentKey()); - issueBuilder.setKey(batchIssue.getKey()); - issueBuilder.setLine(batchIssue.getLine()); - issueBuilder.setMessage(batchIssue.getMessage()); - issueBuilder.setNew(batchIssue.isNew()); - issueBuilder.setResolution(batchIssue.getResolution()); - issueBuilder.setRuleKey(batchIssue.getRuleKey()); - issueBuilder.setRuleName(batchIssue.getRuleName()); - issueBuilder.setSeverity(batchIssue.getSeverity()); - issueBuilder.setStatus(batchIssue.getStatus()); - - return issueBuilder.build(); - } - } - - private static class LoggerAdapter implements Logger { - private LogOutput logOutput; - - LoggerAdapter(LogOutput logOutput) { - this.logOutput = logOutput; - } - - @Override - public void warn(String msg) { - logOutput.log(msg, LogOutput.Level.WARN); - } - - @Override - public void info(String msg) { - logOutput.log(msg, LogOutput.Level.INFO); - } - - @Override - public void error(String msg, Throwable t) { - StringWriter errors = new StringWriter(); - t.printStackTrace(new PrintWriter(errors)); - logOutput.log(msg + "\n" + errors.toString(), LogOutput.Level.ERROR); - } - - @Override - public void error(String msg) { - logOutput.log(msg, LogOutput.Level.ERROR); - } - - @Override - public void debug(String msg) { - logOutput.log(msg, LogOutput.Level.DEBUG); + private void checkLauncherDoesntExist() { + if (launcher != null) { + throw new IllegalStateException("already started"); } } } diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/api/IssueListenerAdapter.java b/sonar-runner-api/src/main/java/org/sonar/runner/api/IssueListenerAdapter.java new file mode 100644 index 0000000..88b1879 --- /dev/null +++ b/sonar-runner-api/src/main/java/org/sonar/runner/api/IssueListenerAdapter.java @@ -0,0 +1,52 @@ +/* + * SonarQube Runner - API + * Copyright (C) 2011 SonarSource + * sonarqube@googlegroups.com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.runner.api; + +class IssueListenerAdapter implements org.sonar.runner.batch.IssueListener { + private IssueListener apiIssueListener; + + public IssueListenerAdapter(IssueListener apiIssueListener) { + this.apiIssueListener = apiIssueListener; + } + + @Override + public void handle(org.sonar.runner.batch.IssueListener.Issue issue) { + apiIssueListener.handle(transformIssue(issue)); + } + + private static org.sonar.runner.api.Issue transformIssue(org.sonar.runner.batch.IssueListener.Issue batchIssue) { + org.sonar.runner.api.Issue.Builder issueBuilder = org.sonar.runner.api.Issue.builder(); + + issueBuilder.setAssigneeLogin(batchIssue.getAssigneeLogin()); + issueBuilder.setAssigneeName(batchIssue.getAssigneeName()); + issueBuilder.setComponentKey(batchIssue.getComponentKey()); + issueBuilder.setKey(batchIssue.getKey()); + issueBuilder.setLine(batchIssue.getLine()); + issueBuilder.setMessage(batchIssue.getMessage()); + issueBuilder.setNew(batchIssue.isNew()); + issueBuilder.setResolution(batchIssue.getResolution()); + issueBuilder.setRuleKey(batchIssue.getRuleKey()); + issueBuilder.setRuleName(batchIssue.getRuleName()); + issueBuilder.setSeverity(batchIssue.getSeverity()); + issueBuilder.setStatus(batchIssue.getStatus()); + + return issueBuilder.build(); + } +} diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/api/LoggerAdapter.java b/sonar-runner-api/src/main/java/org/sonar/runner/api/LoggerAdapter.java new file mode 100644 index 0000000..c3b7007 --- /dev/null +++ b/sonar-runner-api/src/main/java/org/sonar/runner/api/LoggerAdapter.java @@ -0,0 +1,60 @@ +/* + * SonarQube Runner - API + * Copyright (C) 2011 SonarSource + * sonarqube@googlegroups.com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.runner.api; + +import org.sonar.home.cache.Logger; + +import java.io.PrintWriter; +import java.io.StringWriter; + +class LoggerAdapter implements Logger { + private LogOutput logOutput; + + LoggerAdapter(LogOutput logOutput) { + this.logOutput = logOutput; + } + + @Override + public void warn(String msg) { + logOutput.log(msg, LogOutput.Level.WARN); + } + + @Override + public void info(String msg) { + logOutput.log(msg, LogOutput.Level.INFO); + } + + @Override + public void error(String msg, Throwable t) { + StringWriter errors = new StringWriter(); + t.printStackTrace(new PrintWriter(errors)); + logOutput.log(msg + "\n" + errors.toString(), LogOutput.Level.ERROR); + } + + @Override + public void error(String msg) { + logOutput.log(msg, LogOutput.Level.ERROR); + } + + @Override + public void debug(String msg) { + logOutput.log(msg, LogOutput.Level.DEBUG); + } +} diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/api/ProcessMonitor.java b/sonar-runner-api/src/main/java/org/sonar/runner/api/ProcessMonitor.java deleted file mode 100644 index cc1bcef..0000000 --- a/sonar-runner-api/src/main/java/org/sonar/runner/api/ProcessMonitor.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube Runner - API - * Copyright (C) 2011 SonarSource - * sonarqube@googlegroups.com - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.runner.api; - -/** - * To be used with {@link ForkedRunner} - * @since 2.3 - */ -public interface ProcessMonitor { - - /** - * {@link ForkedRunner} will poll this method periodically and if true is returned - * then forked SonarQube Runner process will be killed. - */ - boolean stop(); -} diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/api/Utils.java b/sonar-runner-api/src/main/java/org/sonar/runner/api/Utils.java index 29ea62e..ce855c5 100644 --- a/sonar-runner-api/src/main/java/org/sonar/runner/api/Utils.java +++ b/sonar-runner-api/src/main/java/org/sonar/runner/api/Utils.java @@ -32,6 +32,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.Iterator; import java.util.Properties; + import javax.annotation.Nullable; class Utils { diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/ClassloadRules.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/ClassloadRules.java new file mode 100644 index 0000000..ccae3ec --- /dev/null +++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/ClassloadRules.java @@ -0,0 +1,62 @@ +/* + * SonarQube Runner - API + * Copyright (C) 2011 SonarSource + * sonarqube@googlegroups.com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.runner.impl; + +import javax.annotation.concurrent.Immutable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Immutable +public class ClassloadRules { + private final List<String> mask; + private final List<String> unmask; + + public ClassloadRules(Set<String> maskRules, Set<String> unmaskRules) { + this.mask = new ArrayList<>(maskRules); + this.unmask = new ArrayList<>(unmaskRules); + } + + public boolean canLoad(String className) { + // if there is a tie -> block it + return unmaskSize(className) > maskSize(className); + } + + private int maskSize(String className) { + return findBestMatch(mask, className); + } + + private int unmaskSize(String className) { + return findBestMatch(unmask, className); + } + + private static int findBestMatch(List<String> list, String name) { + // there can be a match of 0 ("") + int bestMatch = -1; + for (String s : list) { + if (name.startsWith(s) && s.length() > bestMatch) { + bestMatch = s.length(); + } + } + + return bestMatch; + } +} diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/InternalProperties.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/InternalProperties.java index 03e7f22..08ec7bb 100644 --- a/sonar-runner-api/src/main/java/org/sonar/runner/impl/InternalProperties.java +++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/InternalProperties.java @@ -23,4 +23,6 @@ public interface InternalProperties { String RUNNER_APP = "sonarRunner.app"; String RUNNER_APP_VERSION = "sonarRunner.appVersion"; String RUNNER_DUMP_TO_FILE = "sonarRunner.dumpToFile"; + String RUNNER_VERSION_SIMULATION = "sonarRunner.versionSimulation"; + String RUNNER_MASK_RULES = "sonarRunner.maskRules"; } diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedClassloader.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedClassloader.java index c469fd1..d273eb0 100644 --- a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedClassloader.java +++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedClassloader.java @@ -31,12 +31,14 @@ import java.util.List; * Special {@link java.net.URLClassLoader} to execute batch, which restricts loading from parent. */ class IsolatedClassloader extends URLClassLoader { + private final ClassloadRules rules; /** * The parent classloader is used only for loading classes and resources in unmasked packages */ - IsolatedClassloader(ClassLoader parent) { + IsolatedClassloader(ClassLoader parent, ClassloadRules rules) { super(new URL[0], parent); + this.rules = rules; } void addFiles(List<File> files) { @@ -59,7 +61,7 @@ class IsolatedClassloader extends URLClassLoader { if (c == null) { try { // Load from parent - if (getParent() != null && fromSonarBatchPackage(name)) { + if (getParent() != null && rules.canLoad(name)) { c = getParent().loadClass(name); } else { @@ -86,10 +88,6 @@ class IsolatedClassloader extends URLClassLoader { return c; } - private static boolean fromSonarBatchPackage(String name) { - return name.startsWith("org.sonar.runner.batch"); - } - /** * Unlike {@link java.net.URLClassLoader#getResource(String)} don't return resource from parent. * See http://jira.codehaus.org/browse/SONAR-2276 diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java index c56b72d..3fa467e 100644 --- a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java +++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java @@ -24,6 +24,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.List; import java.util.Properties; + import org.sonar.home.cache.Logger; import org.sonar.home.cache.PersistentCache; import org.sonar.home.cache.PersistentCacheBuilder; @@ -53,28 +54,35 @@ public class IsolatedLauncherFactory { return builder.build(); } - private ClassLoader createClassLoader(List<File> jarFiles) { - IsolatedClassloader classloader = new IsolatedClassloader(getClass().getClassLoader()); + private ClassLoader createClassLoader(List<File> jarFiles, ClassloadRules maskRules) { + IsolatedClassloader classloader = new IsolatedClassloader(getClass().getClassLoader(), maskRules); classloader.addFiles(jarFiles); return classloader; } - public IsolatedLauncher createLauncher(Properties props) { + public IsolatedLauncher createLauncher(Properties props, ClassloadRules rules) { + if (props.containsKey(InternalProperties.RUNNER_DUMP_TO_FILE)) { + String version = props.getProperty(InternalProperties.RUNNER_VERSION_SIMULATION); + if (version == null) { + version = "5.2"; + } + return new SimulatedLauncher(version, logger); + } ServerConnection serverConnection = ServerConnection.create(props, getCache(props), logger); JarDownloader jarDownloader = new JarDownloader(serverConnection, logger); - return createLauncher(jarDownloader); + return createLauncher(jarDownloader, rules); } - IsolatedLauncher createLauncher(final JarDownloader jarDownloader) { + IsolatedLauncher createLauncher(final JarDownloader jarDownloader, final ClassloadRules rules) { return AccessController.doPrivileged(new PrivilegedAction<IsolatedLauncher>() { @Override public IsolatedLauncher run() { try { List<File> jarFiles = jarDownloader.download(); logger.debug("Create isolated classloader..."); - ClassLoader cl = createClassLoader(jarFiles); + ClassLoader cl = createClassLoader(jarFiles, rules); IsolatedLauncher objProxy = IsolatedLauncherProxy.create(cl, IsolatedLauncher.class, launcherImplClassName, logger); tempCleaning.clean(); diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/SimulatedLauncher.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/SimulatedLauncher.java new file mode 100644 index 0000000..b4cc365 --- /dev/null +++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/SimulatedLauncher.java @@ -0,0 +1,115 @@ +/* + * SonarQube Runner - API + * Copyright (C) 2011 SonarSource + * sonarqube@googlegroups.com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.runner.impl; + +import org.sonar.home.cache.Logger; + +import javax.annotation.Nullable; + +import org.sonar.runner.batch.IssueListener; +import org.sonar.runner.batch.LogOutput; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Properties; + +import org.sonar.runner.batch.IsolatedLauncher; + +public class SimulatedLauncher implements IsolatedLauncher { + private final String version; + private final Logger logger; + private Properties globalProperties; + + SimulatedLauncher(String version, Logger logger) { + this.version = version; + this.logger = logger; + } + + @Override + public void start(Properties properties, LogOutput logOutput, boolean forceSync) { + globalProperties = properties; + } + + @Override + public void stop() { + globalProperties = null; + } + + @Override + public void execute(Properties properties) { + dumpProperties(globalProperties, properties); + } + + @Override + public void execute(Properties properties, IssueListener listener) { + dumpProperties(globalProperties, properties); + } + + private void dumpProperties(@Nullable Properties global, Properties analysis) { + // for old versions, analysis will have global properties merged in it + String filePath; + String filePathGlobal = null; + if (global != null) { + filePath = global.getProperty(InternalProperties.RUNNER_DUMP_TO_FILE); + filePathGlobal = filePath + ".global"; + } else { + filePath = analysis.getProperty(InternalProperties.RUNNER_DUMP_TO_FILE); + } + + if (filePath == null) { + throw new IllegalStateException("No file to dump properties"); + } + + if (global != null) { + File dumpFileGlobal = new File(filePathGlobal); + writeProperties(dumpFileGlobal, global, "global properties"); + } + + File dumpFile = new File(filePath); + writeProperties(dumpFile, analysis, "analysis properties"); + logger.info("Simulation mode. Configuration written to " + dumpFile.getAbsolutePath()); + } + + private static void writeProperties(File outputFile, Properties p, String comment) { + try (OutputStream output = new FileOutputStream(outputFile)) { + p.store(output, "Generated by sonar-runner - " + comment); + } catch (Exception e) { + throw new IllegalStateException("Fail to export sonar-runner properties", e); + } + } + + @Override + public void syncProject(String projectKey) { + // no op + } + + @Override + public void executeOldVersion(Properties properties, List<Object> extensions) { + dumpProperties(null, properties); + } + + @Override + public String getVersion() { + return version; + } + +} |