diff options
Diffstat (limited to 'sonar-server')
39 files changed, 704 insertions, 683 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/charts/ChartsServlet.java b/sonar-server/src/main/java/org/sonar/server/charts/ChartsServlet.java index f54967ee5a7..c4e2fda39bb 100644 --- a/sonar-server/src/main/java/org/sonar/server/charts/ChartsServlet.java +++ b/sonar-server/src/main/java/org/sonar/server/charts/ChartsServlet.java @@ -50,7 +50,7 @@ public class ChartsServlet extends HttpServlet { deprecatedDoGet(request, response); } else { - ChartFactory chartFactory = Platform.getInstance().getContainer().getComponent(ChartFactory.class); + ChartFactory chartFactory = Platform.getInstance().getContainer().getComponentByType(ChartFactory.class); Chart chart = chartFactory.getChart(request.getParameter("ck")); if (chart != null) { BufferedImage image = chart.generateImage(getParams(request)); diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationException.java b/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationException.java deleted file mode 100644 index 827f77cbc85..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 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.server.configuration; - -public class ConfigurationException extends RuntimeException { - public ConfigurationException() { - } - - public ConfigurationException(String s) { - super(s); - } - - public ConfigurationException(String s, Throwable throwable) { - super(s, throwable); - } - - public ConfigurationException(Throwable throwable) { - super(throwable); - } -} diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationFactory.java b/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationFactory.java deleted file mode 100644 index bc7f086ec6d..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 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.server.configuration; - -import org.apache.commons.configuration.*; -import org.apache.commons.configuration.interpol.ConfigurationInterpolator; -import org.apache.commons.lang.text.StrLookup; - -import javax.servlet.ServletContextEvent; -import java.io.File; -import java.util.HashMap; - -public final class ConfigurationFactory { - - public ConfigurationFactory() { - allowUsingEnvironmentVariables(); - } - - public Configuration getConfiguration(ServletContextEvent sce) { - CoreConfiguration configuration = new CoreConfiguration(); - configuration.addConfiguration(getConfigurationFromPropertiesFile()); - configuration.addConfiguration(new SystemConfiguration()); - configuration.addConfiguration(new EnvironmentConfiguration()); - configuration.addConfiguration(getDirectoriesConfiguration(sce)); - return configuration; - } - - private void allowUsingEnvironmentVariables() { - ConfigurationInterpolator.registerGlobalLookup("env", new StrLookup() { - @Override - public String lookup(String varName) { - return System.getenv(varName); - } - }); - } - - private Configuration getDirectoriesConfiguration(ServletContextEvent sce) { - MapConfiguration result = new MapConfiguration(new HashMap()); - String webAppDir = autodetectWebappDeployDirectory(sce); - result.setProperty(CoreConfiguration.DEPLOY_DIR, webAppDir); - return result; - } - - protected PropertiesConfiguration getConfigurationFromPropertiesFile(String filename) { - try { - return new PropertiesConfiguration(ConfigurationFactory.class.getResource(filename)); - - } catch (org.apache.commons.configuration.ConfigurationException e) { - throw new ConfigurationException("can not load the file " + filename + " from classpath", e); - } - } - - public PropertiesConfiguration getConfigurationFromPropertiesFile() { - return getConfigurationFromPropertiesFile("/conf/sonar.properties"); - } - - protected String autodetectWebappDeployDirectory(ServletContextEvent sce) { - String webAppPublicDirPath = sce.getServletContext().getRealPath("/deploy/"); - if (webAppPublicDirPath == null) { - throw new ConfigurationException("Web app directory not found : /deploy/"); - } - File file = new File(webAppPublicDirPath); - if (!file.exists()) { - throw new ConfigurationException("Web app directory not found : " + file); - } - return file.toString(); - } - -} diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationLogger.java b/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationLogger.java deleted file mode 100644 index b63d156e787..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/configuration/ConfigurationLogger.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 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.server.configuration; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; - -public final class ConfigurationLogger { - - private ConfigurationLogger() { - // only static methods - } - - public static void log(Configuration configuration) { - Logger log = LoggerFactory.getLogger(ConfigurationLogger.class); - if (log.isDebugEnabled()) { - Iterator<String> keys = configuration.getKeys(); - while (keys.hasNext()) { - String key = keys.next(); - String property = getTruncatedProperty(configuration, key); - log.debug("Property: " + key + " is: '" + property + "'"); - } - } - } - - static String getTruncatedProperty(Configuration configuration, String key) { - String property = StringUtils.join(configuration.getStringArray(key), ","); - return StringUtils.abbreviate(property, 100); - } - -} diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/CoreConfiguration.java b/sonar-server/src/main/java/org/sonar/server/configuration/CoreConfiguration.java deleted file mode 100644 index 8e018e52af0..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/configuration/CoreConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 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.server.configuration; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.sonar.api.database.configuration.DatabaseConfiguration; - -public class CoreConfiguration extends CompositeConfiguration { - public static final String DEPLOY_DIR = "sonar.web.deployDir"; - - public DatabaseConfiguration getDatabaseConfiguration() { - int total = getNumberOfConfigurations(); - for (int i = 0; i < total; i++) { - if (getConfiguration(i) instanceof DatabaseConfiguration) { - return (DatabaseConfiguration) getConfiguration(i); - } - } - return null; - } - - public void reload() { - DatabaseConfiguration dbConfig = getDatabaseConfiguration(); - if (dbConfig != null) { - dbConfig.load(); - } - } -} diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ServerSettings.java b/sonar-server/src/main/java/org/sonar/server/configuration/ServerSettings.java new file mode 100644 index 00000000000..72b0afb6a8d --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/configuration/ServerSettings.java @@ -0,0 +1,156 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 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.server.configuration; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.CoreProperties; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.Settings; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.configuration.Property; +import org.sonar.core.config.ConfigurationUtils; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.servlet.ServletContext; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Properties; + +/** + * Load settings from environment, conf/sonar.properties and database + * + * @since 2.12 + */ +public class ServerSettings extends Settings { + + public static final String DEPLOY_DIR = "sonar.web.deployDir"; + + private DatabaseSessionFactory sessionFactory; + private Configuration deprecatedConfiguration; + private File sonarHome; + private File deployDir; + + public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext) { + super(definitions); + this.deprecatedConfiguration = deprecatedConfiguration; + this.sonarHome = getSonarHome(); + this.deployDir = getDeployDir(servletContext); + load(); + } + + public ServerSettings setSessionFactory(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + return this; + } + + public ServerSettings load() { + clear(); + setProperty(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath()); + setProperty(DEPLOY_DIR, deployDir.getAbsolutePath()); + + // order is important + loadDatabaseSettings(); + addEnvironmentVariables(); + addSystemProperties(); + loadPropertiesFile(); + + // update deprecated configuration + ConfigurationUtils.copyToCommonsConfiguration(properties, deprecatedConfiguration); + + return this; + } + + private void loadDatabaseSettings() { + if (sessionFactory != null) { + DatabaseSession session = sessionFactory.getSession(); + + // Ugly workaround before the move to myBatis + // Session is not up-to-date when Ruby on Rails inserts new rows in its own transaction. Seems like + // Hibernate keeps a cache... + session.commit(); + List<Property> properties = session.createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId is null and p.userId is null").getResultList(); + + for (Property property : properties) { + setProperty(property.getKey(), property.getValue()); + } + } + } + + private void loadPropertiesFile() { + File propertiesFile = new File(sonarHome, "conf/sonar.properties"); + if (!propertiesFile.isFile() || !propertiesFile.exists()) { + throw new IllegalStateException("Properties file does not exist: " + propertiesFile); + } + + try { + Properties p = ConfigurationUtils.openProperties(propertiesFile); + p = ConfigurationUtils.interpolateEnvVariables(p); + addProperties(p); + + } catch (Exception e) { + throw new IllegalStateException("Fail to load configuration file: " + propertiesFile, e); + } + } + + static File getDeployDir(ServletContext servletContext) { + String dirname = servletContext.getRealPath("/deploy/"); + if (dirname == null) { + throw new IllegalArgumentException("Web app directory not found : /deploy/"); + } + File dir = new File(dirname); + if (!dir.exists()) { + throw new IllegalArgumentException("Web app directory does not exist: " + dir); + } + return dir; + } + + static File getSonarHome() { + String home = System.getProperty("sonar.home"); + if (StringUtils.isBlank(home)) { + home = System.getenv("SONAR_HOME"); + if (StringUtils.isBlank(home)) { + Properties warProps = openWarProperties(); + home = warProps.getProperty("sonar.home"); + } + } + + if (StringUtils.isBlank(home)) { + throw new IllegalStateException("Please set location to SONAR_HOME"); + } + + File dir = new File(home); + if (!dir.isDirectory() || !dir.exists()) { + throw new IllegalStateException("SONAR_HOME is not valid: " + home); + } + return dir; + } + + private static Properties openWarProperties() { + try { + InputStream input = ServerSettings.class.getResourceAsStream("/sonar-war.properties"); + return ConfigurationUtils.openInputStream(input); + } catch (IOException e) { + throw new IllegalStateException("Fail to load the file sonar-war.properties", e); + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabase.java b/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabase.java index 0543528de6b..cf08eb23786 100644 --- a/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabase.java +++ b/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabase.java @@ -19,10 +19,11 @@ */ package org.sonar.server.database; -import org.apache.commons.configuration.Configuration; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.derby.drda.NetworkServerControl; import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; import org.sonar.api.utils.Logs; import org.sonar.api.utils.SonarException; @@ -33,6 +34,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.InetAddress; +import java.sql.SQLOutput; import java.util.Properties; public class EmbeddedDatabase { @@ -46,9 +48,9 @@ public class EmbeddedDatabase { private Properties dbProps; private PrintWriter dbLog; - public EmbeddedDatabase(Configuration configuration) { - this.dbHome = autodetectDataDirectory(configuration); - this.dbProps = getDefaultProperties(configuration); + public EmbeddedDatabase(Settings settings) { + this.dbHome = getDataDirectory(settings); + this.dbProps = getDefaultProperties(settings); } public EmbeddedDatabase(File dbHome, Properties dbProps) { @@ -60,10 +62,10 @@ public class EmbeddedDatabase { return dbHome; } - protected File autodetectDataDirectory(Configuration configuration) { - String dirName = configuration.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR); - if (dirName == null) { - File sonarHome = new File(configuration.getString(CoreProperties.SONAR_HOME)); + protected File getDataDirectory(Settings settings) { + String dirName = settings.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR); + if (StringUtils.isBlank(dirName)) { + File sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME)); if (!sonarHome.isDirectory() || !sonarHome.exists()) { throw new ServerStartException("Sonar home directory does not exist"); } @@ -171,15 +173,15 @@ public class EmbeddedDatabase { } } - public static Properties getDefaultProperties(Configuration configuration) { + public static Properties getDefaultProperties(Settings settings) { Properties props = new Properties(); props.setProperty("derby.drda.startNetworkServer", "true"); - props.setProperty("derby.drda.host", configuration.getString("sonar.derby.drda.host", "localhost")); - props.setProperty("derby.drda.portNumber", configuration.getString("sonar.derby.drda.portNumber", "1527")); - props.setProperty("derby.drda.maxThreads", configuration.getString("sonar.derby.drda.maxThreads", "20")); - props.setProperty("derby.drda.minThreads", configuration.getString("sonar.derby.drda.minThreads", "2")); - props.setProperty("derby.drda.logConnections", configuration.getString("sonar.derby.drda.logConnections", "false")); - props.setProperty("derby.stream.error.logSeverityLevel", configuration.getString("sonar.derby.stream.error.logSeverityLevel", "20000")); + props.setProperty("derby.drda.host", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.host"), "localhost")); + props.setProperty("derby.drda.portNumber", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.portNumber"), "1527")); + props.setProperty("derby.drda.maxThreads", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.maxThreads"), "20")); + props.setProperty("derby.drda.minThreads", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.minThreads"), "2")); + props.setProperty("derby.drda.logConnections", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.logConnections"), "false")); + props.setProperty("derby.stream.error.logSeverityLevel", StringUtils.defaultIfBlank(settings.getString("sonar.derby.stream.error.logSeverityLevel"), "20000")); props.setProperty("derby.connection.requireAuthentication", "true"); props.setProperty("derby.user." + DEFAULT_USER, DEFAULT_PWD); return props; diff --git a/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabaseFactory.java b/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabaseFactory.java index 92787dee792..b60dd4f7b09 100644 --- a/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabaseFactory.java +++ b/sonar-server/src/main/java/org/sonar/server/database/EmbeddedDatabaseFactory.java @@ -19,21 +19,21 @@ */ package org.sonar.server.database; -import org.apache.commons.configuration.Configuration; +import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; public class EmbeddedDatabaseFactory { - private Configuration configuration; + private Settings settings; private EmbeddedDatabase embeddedDatabase; - public EmbeddedDatabaseFactory(Configuration configuration) { - this.configuration = configuration; + public EmbeddedDatabaseFactory(Settings settings) { + this.settings = settings; } public void start() { - String jdbcUrl = configuration.getString(DatabaseProperties.PROP_URL); - if ((jdbcUrl!=null) && jdbcUrl.startsWith("jdbc:derby://") && jdbcUrl.contains("create=true") && embeddedDatabase==null) { - embeddedDatabase = new EmbeddedDatabase(configuration); + String jdbcUrl = settings.getString(DatabaseProperties.PROP_URL); + if (jdbcUrl != null && jdbcUrl.startsWith("jdbc:derby://") && jdbcUrl.contains("create=true") && embeddedDatabase == null) { + embeddedDatabase = new EmbeddedDatabase(settings); embeddedDatabase.start(); } } diff --git a/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java b/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java index abcb18f9a4c..52d016c0b0e 100644 --- a/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java +++ b/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java @@ -21,7 +21,9 @@ package org.sonar.server.database; import org.apache.commons.configuration.Configuration; import org.apache.commons.dbcp.BasicDataSourceFactory; +import org.apache.commons.lang.StringUtils; import org.hibernate.cfg.Environment; +import org.sonar.api.config.Settings; import org.sonar.api.utils.Logs; import org.sonar.api.utils.SonarException; import org.sonar.jpa.entity.SchemaMigration; @@ -31,13 +33,14 @@ import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; +import java.util.List; import java.util.Properties; public class JndiDatabaseConnector extends AbstractDatabaseConnector { private DataSource datasource = null; - public JndiDatabaseConnector(Configuration configuration) { + public JndiDatabaseConnector(Settings configuration) { super(configuration, false); } @@ -72,10 +75,9 @@ public class JndiDatabaseConnector extends AbstractDatabaseConnector { try { Logs.INFO.info("Creating JDBC datasource"); Properties properties = new Properties(); - Configuration dsConfig = getConfiguration().subset("sonar.jdbc"); - for (Iterator<String> it = dsConfig.getKeys(); it.hasNext(); ) { - String key = it.next(); - properties.setProperty(key, dsConfig.getString(key)); + List<String> jdbcKeys = configuration.getKeysStartingWith("sonar.jdbc."); + for (String jdbcKey : jdbcKeys) { + properties.setProperty(StringUtils.removeStart(jdbcKey, "sonar.jdbc."), configuration.getString(jdbcKey)); } // This property is required by the Ruby Oracle enhanced adapter. @@ -92,9 +94,6 @@ public class JndiDatabaseConnector extends AbstractDatabaseConnector { public Connection getConnection() throws SQLException { if (datasource != null) { Connection connection = datasource.getConnection(); - if (getTransactionIsolation() != null) { - connection.setTransactionIsolation(getTransactionIsolation()); - } return connection; } return null; diff --git a/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java b/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java index 22455c1a057..bf956a5949e 100644 --- a/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java +++ b/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java @@ -19,10 +19,10 @@ */ package org.sonar.server.mavendeployer; -import org.apache.commons.configuration.Configuration; import org.apache.commons.io.FileUtils; +import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; -import org.sonar.server.configuration.CoreConfiguration; +import org.sonar.server.configuration.ServerSettings; import org.sonar.server.platform.DefaultServerFileSystem; import java.io.File; @@ -34,10 +34,10 @@ public class MavenRepository { private final String serverId; private File rootDir; - public MavenRepository(Configuration configuration, DefaultServerFileSystem fileSystem, Server server) throws IOException { + public MavenRepository(Settings settings, DefaultServerFileSystem fileSystem, Server server) throws IOException { this.installation = fileSystem; this.serverId = server.getId(); - initRootDir(configuration); + initRootDir(settings); } /** @@ -60,8 +60,8 @@ public class MavenRepository { } - private void initRootDir(Configuration configuration) throws IOException { - this.rootDir = new File(configuration.getString(CoreConfiguration.DEPLOY_DIR), "maven"); + private void initRootDir(Settings settings) throws IOException { + this.rootDir = new File(settings.getString(ServerSettings.DEPLOY_DIR), "maven"); File orgDir = new File(rootDir, "/org/"); if (orgDir.exists()) { FileUtils.forceDelete(orgDir); diff --git a/sonar-server/src/main/java/org/sonar/server/notifications/NotificationService.java b/sonar-server/src/main/java/org/sonar/server/notifications/NotificationService.java index ae4f45f507a..523ec15aa44 100644 --- a/sonar-server/src/main/java/org/sonar/server/notifications/NotificationService.java +++ b/sonar-server/src/main/java/org/sonar/server/notifications/NotificationService.java @@ -19,17 +19,11 @@ */ package org.sonar.server.notifications; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.configuration.Configuration; -import org.sonar.api.ServerComponent; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; +import org.sonar.api.*; +import org.sonar.api.config.Settings; import org.sonar.api.notifications.Notification; import org.sonar.api.notifications.NotificationChannel; import org.sonar.api.notifications.NotificationDispatcher; @@ -38,22 +32,30 @@ import org.sonar.api.utils.TimeProfiler; import org.sonar.core.notifications.DefaultNotificationManager; import org.sonar.jpa.entity.NotificationQueueElement; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * @since 2.10 */ +@org.sonar.api.Properties({ + @Property( + key = NotificationService.PROPERTY_DELAY, + defaultValue = "60", + name = "Delay of notifications, in seconds", + project = false, + global = false) +}) public class NotificationService implements ServerComponent { private static final TimeProfiler TIME_PROFILER = new TimeProfiler(Logs.INFO).setLevelToDebug(); - private static final String DELAY = "sonar.notifications.delay"; - private static final long DELAY_DEFAULT = 60; + public static final String PROPERTY_DELAY = "sonar.notifications.delay"; private ScheduledExecutorService executorService; - private long delay; + private long delayInSeconds; private DefaultNotificationManager manager; private NotificationChannel[] channels; @@ -64,13 +66,13 @@ public class NotificationService implements ServerComponent { /** * Default constructor when no channels. */ - public NotificationService(Configuration configuration, DefaultNotificationManager manager, NotificationDispatcher[] dispatchers) { - this(configuration, manager, dispatchers, new NotificationChannel[0]); + public NotificationService(Settings settings, DefaultNotificationManager manager, NotificationDispatcher[] dispatchers) { + this(settings, manager, dispatchers, new NotificationChannel[0]); Logs.INFO.warn("There is no channels - all notifications would be ignored!"); } - public NotificationService(Configuration configuration, DefaultNotificationManager manager, NotificationDispatcher[] dispatchers, NotificationChannel[] channels) { - delay = configuration.getLong(DELAY, DELAY_DEFAULT); + public NotificationService(Settings settings, DefaultNotificationManager manager, NotificationDispatcher[] dispatchers, NotificationChannel[] channels) { + delayInSeconds = settings.getLong(PROPERTY_DELAY); this.manager = manager; this.channels = channels; this.dispatchers = dispatchers; @@ -82,8 +84,8 @@ public class NotificationService implements ServerComponent { public void run() { processQueue(); } - }, 0, delay, TimeUnit.SECONDS); - Logs.INFO.info("Notification service started (delay {} sec.)", delay); + }, 0, delayInSeconds, TimeUnit.SECONDS); + Logs.INFO.info("Notification service started (delay {} sec.)", delayInSeconds); } public void stop() { diff --git a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java index 919217b72e0..a3ea2935404 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java @@ -19,14 +19,14 @@ */ package org.sonar.server.platform; -import org.apache.commons.configuration.Configuration; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; import org.sonar.api.platform.ServerFileSystem; import org.sonar.api.utils.Logs; import org.sonar.jpa.session.DatabaseConnector; -import org.sonar.server.configuration.CoreConfiguration; +import org.sonar.server.configuration.ServerSettings; import java.io.File; import java.io.IOException; @@ -45,11 +45,11 @@ public class DefaultServerFileSystem implements ServerFileSystem { private File deployDir; private File homeDir; - public DefaultServerFileSystem(DatabaseConnector databaseConnector, Configuration configuration) { + public DefaultServerFileSystem(DatabaseConnector databaseConnector, Settings settings) { this.databaseConnector = databaseConnector; - this.homeDir = new File(configuration.getString(CoreProperties.SONAR_HOME)); + this.homeDir = new File(settings.getString(CoreProperties.SONAR_HOME)); - String deployPath = configuration.getString(CoreConfiguration.DEPLOY_DIR); + String deployPath = settings.getString(ServerSettings.DEPLOY_DIR); if (StringUtils.isNotBlank(deployPath)) { this.deployDir = new File(deployPath); } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index c733a991588..8f65905de3e 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -19,13 +19,10 @@ */ package org.sonar.server.platform; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.picocontainer.Characteristics; -import org.picocontainer.MutablePicoContainer; +import org.apache.commons.configuration.BaseConfiguration; import org.slf4j.LoggerFactory; import org.sonar.api.Plugins; -import org.sonar.api.database.configuration.DatabaseConfiguration; +import org.sonar.api.platform.ComponentContainer; import org.sonar.api.platform.Server; import org.sonar.api.profiles.AnnotationProfileParser; import org.sonar.api.profiles.XMLProfileParser; @@ -53,8 +50,8 @@ import org.sonar.jpa.session.DatabaseSessionFactory; import org.sonar.jpa.session.DatabaseSessionProvider; import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; import org.sonar.server.charts.ChartFactory; +import org.sonar.server.configuration.ServerSettings; import org.sonar.server.configuration.Backup; -import org.sonar.server.configuration.ConfigurationLogger; import org.sonar.server.configuration.ProfilesManager; import org.sonar.server.database.EmbeddedDatabaseFactory; import org.sonar.server.database.JndiDatabaseConnector; @@ -72,6 +69,8 @@ import org.sonar.server.ui.CodeColorizers; import org.sonar.server.ui.JRubyI18n; import org.sonar.server.ui.Views; +import javax.servlet.ServletContext; + /** * @since 2.2 */ @@ -79,9 +78,9 @@ public final class Platform { private static final Platform INSTANCE = new Platform(); - private MutablePicoContainer rootContainer;// level 1 : only database connectors - private MutablePicoContainer coreContainer;// level 2 : level 1 + core components - private MutablePicoContainer servicesContainer;// level 3 : level 2 + plugin extensions + core components that depend on plugin extensions + private ComponentContainer rootContainer;// level 1 : only database connectors + private ComponentContainer coreContainer;// level 2 : level 1 + core components + private ComponentContainer servicesContainer;// level 3 : level 2 + plugin extensions + core components that depend on plugin extensions private boolean connected = false; private boolean started = false; @@ -93,10 +92,10 @@ public final class Platform { private Platform() { } - public void init(Configuration conf) { + public void init(ServletContext servletContext) { if (!connected) { try { - startDatabaseConnectors(conf); + startDatabaseConnectors(servletContext); connected = true; } catch (Exception e) { @@ -116,117 +115,117 @@ public final class Platform { } } - private void startDatabaseConnectors(Configuration configuration) { - rootContainer = IocContainer.buildPicoContainer(); - ConfigurationLogger.log(configuration); - - rootContainer.as(Characteristics.CACHE).addComponent(configuration); - rootContainer.as(Characteristics.CACHE).addComponent(EmbeddedDatabaseFactory.class); - rootContainer.as(Characteristics.CACHE).addComponent(JndiDatabaseConnector.class); - rootContainer.as(Characteristics.CACHE).addComponent(DefaultServerUpgradeStatus.class); - rootContainer.start(); - - // Platform is already starting, so it's registered after the container startup + private void startDatabaseConnectors(ServletContext servletContext) { + rootContainer = new ComponentContainer(); + rootContainer.addSingleton(servletContext); + rootContainer.addSingleton(IocContainer.class); // for backward compatibility + rootContainer.addSingleton(new BaseConfiguration()); + rootContainer.addSingleton(ServerSettings.class); + rootContainer.addSingleton(EmbeddedDatabaseFactory.class); + rootContainer.addSingleton(JndiDatabaseConnector.class); + rootContainer.addSingleton(DefaultServerUpgradeStatus.class); + rootContainer.startComponents(); } private boolean isUpToDateDatabase() { - JndiDatabaseConnector databaseConnector = getContainer().getComponent(JndiDatabaseConnector.class); + JndiDatabaseConnector databaseConnector = getContainer().getComponentByType(JndiDatabaseConnector.class); return databaseConnector.isOperational(); } private void startCoreComponents() { - coreContainer = rootContainer.makeChildContainer(); - coreContainer.as(Characteristics.CACHE).addComponent(PluginDeployer.class); - coreContainer.as(Characteristics.CACHE).addComponent(DefaultServerPluginRepository.class); - coreContainer.as(Characteristics.CACHE).addComponent(DefaultServerFileSystem.class); - coreContainer.as(Characteristics.CACHE).addComponent(ThreadLocalDatabaseSessionFactory.class); - coreContainer.as(Characteristics.CACHE).addComponent(HttpDownloader.class); - coreContainer.as(Characteristics.CACHE).addComponent(UpdateCenterClient.class); - coreContainer.as(Characteristics.CACHE).addComponent(UpdateCenterMatrixFactory.class); - coreContainer.as(Characteristics.CACHE).addComponent(PluginDownloader.class); - coreContainer.as(Characteristics.CACHE).addComponent(ServerIdGenerator.class); - coreContainer.as(Characteristics.CACHE).addComponent(ServerImpl.class); - coreContainer.as(Characteristics.NO_CACHE).addComponent(FilterExecutor.class); - coreContainer.as(Characteristics.NO_CACHE).addAdapter(new DatabaseSessionProvider()); - coreContainer.start(); + coreContainer = rootContainer.createChild(); + coreContainer.addSingleton(PluginDeployer.class); + coreContainer.addSingleton(DefaultServerPluginRepository.class); + coreContainer.addSingleton(ServerExtensionInstaller.class); + coreContainer.addSingleton(DefaultServerFileSystem.class); + coreContainer.addSingleton(ThreadLocalDatabaseSessionFactory.class); + coreContainer.addPicoAdapter(new DatabaseSessionProvider()); + coreContainer.startComponents(); - DatabaseConfiguration dbConfiguration = new DatabaseConfiguration(coreContainer.getComponent(DatabaseSessionFactory.class)); - coreContainer.getComponent(CompositeConfiguration.class).addConfiguration(dbConfiguration); + DatabaseSessionFactory sessionFactory = coreContainer.getComponentByType(DatabaseSessionFactory.class); + ServerSettings serverSettings = coreContainer.getComponentByType(ServerSettings.class); + serverSettings.setSessionFactory(sessionFactory); + serverSettings.load(); } /** * plugin extensions + all the components that depend on plugin extensions */ private void startServiceComponents() { - servicesContainer = coreContainer.makeChildContainer(); - - DefaultServerPluginRepository pluginRepository = servicesContainer.getComponent(DefaultServerPluginRepository.class); - pluginRepository.registerExtensions(servicesContainer); + servicesContainer = coreContainer.createChild(); + ServerExtensionInstaller extensionRegistrar = servicesContainer.getComponentByType(ServerExtensionInstaller.class); + extensionRegistrar.registerExtensions(servicesContainer); - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultModelFinder.class); // depends on plugins - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultModelManager.class); - servicesContainer.as(Characteristics.CACHE).addComponent(Plugins.class); - servicesContainer.as(Characteristics.CACHE).addComponent(ChartFactory.class); - servicesContainer.as(Characteristics.CACHE).addComponent(Languages.class); - servicesContainer.as(Characteristics.CACHE).addComponent(Views.class); - servicesContainer.as(Characteristics.CACHE).addComponent(CodeColorizers.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(RulesDao.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(MeasuresDao.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(org.sonar.api.database.daos.MeasuresDao.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(ProfilesDao.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(DaoFacade.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(DefaultRulesManager.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(ProfilesManager.class); - servicesContainer.as(Characteristics.NO_CACHE).addComponent(Backup.class); - servicesContainer.as(Characteristics.CACHE).addComponent(AuthenticatorFactory.class); - servicesContainer.as(Characteristics.CACHE).addComponent(ServerLifecycleNotifier.class); - servicesContainer.as(Characteristics.CACHE).addComponent(AnnotationProfileParser.class); - servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileParser.class); - servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileSerializer.class); - servicesContainer.as(Characteristics.CACHE).addComponent(AnnotationRuleParser.class); - servicesContainer.as(Characteristics.CACHE).addComponent(XMLRuleParser.class); - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultRuleFinder.class); - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultMetricFinder.class); - servicesContainer.as(Characteristics.CACHE).addComponent(ProfilesConsole.class); - servicesContainer.as(Characteristics.CACHE).addComponent(RulesConsole.class); - servicesContainer.as(Characteristics.CACHE).addComponent(JRubyI18n.class); - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultUserFinder.class); - servicesContainer.as(Characteristics.CACHE).addComponent(I18nManager.class); - servicesContainer.as(Characteristics.CACHE).addComponent(RuleI18nManager.class); - servicesContainer.as(Characteristics.CACHE).addComponent(GwtI18n.class); + servicesContainer.addSingleton(HttpDownloader.class); + servicesContainer.addSingleton(UpdateCenterClient.class); + servicesContainer.addSingleton(UpdateCenterMatrixFactory.class); + servicesContainer.addSingleton(PluginDownloader.class); + servicesContainer.addSingleton(ServerIdGenerator.class); + servicesContainer.addSingleton(ServerImpl.class); + servicesContainer.addComponent(FilterExecutor.class, false); + servicesContainer.addSingleton(DefaultModelFinder.class); // depends on plugins + servicesContainer.addSingleton(DefaultModelManager.class); + servicesContainer.addSingleton(Plugins.class); + servicesContainer.addSingleton(ChartFactory.class); + servicesContainer.addSingleton(Languages.class); + servicesContainer.addSingleton(Views.class); + servicesContainer.addSingleton(CodeColorizers.class); + servicesContainer.addComponent(RulesDao.class, false); + servicesContainer.addComponent(MeasuresDao.class, false); + servicesContainer.addComponent(org.sonar.api.database.daos.MeasuresDao.class, false); + servicesContainer.addComponent(ProfilesDao.class, false); + servicesContainer.addComponent(DaoFacade.class, false); + servicesContainer.addComponent(DefaultRulesManager.class, false); + servicesContainer.addComponent(ProfilesManager.class, false); + servicesContainer.addComponent(Backup.class, false); + servicesContainer.addSingleton(AuthenticatorFactory.class); + servicesContainer.addSingleton(ServerLifecycleNotifier.class); + servicesContainer.addSingleton(AnnotationProfileParser.class); + servicesContainer.addSingleton(XMLProfileParser.class); + servicesContainer.addSingleton(XMLProfileSerializer.class); + servicesContainer.addSingleton(AnnotationRuleParser.class); + servicesContainer.addSingleton(XMLRuleParser.class); + servicesContainer.addSingleton(DefaultRuleFinder.class); + servicesContainer.addSingleton(DefaultMetricFinder.class); + servicesContainer.addSingleton(ProfilesConsole.class); + servicesContainer.addSingleton(RulesConsole.class); + servicesContainer.addSingleton(JRubyI18n.class); + servicesContainer.addSingleton(DefaultUserFinder.class); + servicesContainer.addSingleton(I18nManager.class); + servicesContainer.addSingleton(RuleI18nManager.class); + servicesContainer.addSingleton(GwtI18n.class); // Notifications - servicesContainer.as(Characteristics.CACHE).addComponent(NotificationService.class); - servicesContainer.as(Characteristics.CACHE).addComponent(DefaultNotificationManager.class); - servicesContainer.as(Characteristics.CACHE).addComponent(ReviewsNotificationManager.class); + servicesContainer.addSingleton(NotificationService.class); + servicesContainer.addSingleton(DefaultNotificationManager.class); + servicesContainer.addSingleton(ReviewsNotificationManager.class); - servicesContainer.start(); + servicesContainer.startComponents(); } private void executeStartupTasks() { - MutablePicoContainer startupContainer = servicesContainer.makeChildContainer(); + ComponentContainer startupContainer = servicesContainer.createChild(); try { - startupContainer.as(Characteristics.CACHE).addComponent(MavenRepository.class); - startupContainer.as(Characteristics.CACHE).addComponent(GwtPublisher.class); - startupContainer.as(Characteristics.CACHE).addComponent(RegisterMetrics.class); - startupContainer.as(Characteristics.CACHE).addComponent(RegisterRules.class); - startupContainer.as(Characteristics.CACHE).addComponent(RegisterProvidedProfiles.class); - startupContainer.as(Characteristics.CACHE).addComponent(EnableProfiles.class); - startupContainer.as(Characteristics.CACHE).addComponent(ActivateDefaultProfiles.class); - startupContainer.as(Characteristics.CACHE).addComponent(JdbcDriverDeployer.class); - startupContainer.as(Characteristics.CACHE).addComponent(ServerMetadataPersister.class); - startupContainer.as(Characteristics.CACHE).addComponent(RegisterQualityModels.class); - startupContainer.as(Characteristics.CACHE).addComponent(DeleteDeprecatedMeasures.class); - startupContainer.as(Characteristics.CACHE).addComponent(GeneratePluginIndex.class); - startupContainer.start(); + startupContainer.addSingleton(MavenRepository.class); + startupContainer.addSingleton(GwtPublisher.class); + startupContainer.addSingleton(RegisterMetrics.class); + startupContainer.addSingleton(RegisterRules.class); + startupContainer.addSingleton(RegisterProvidedProfiles.class); + startupContainer.addSingleton(EnableProfiles.class); + startupContainer.addSingleton(ActivateDefaultProfiles.class); + startupContainer.addSingleton(JdbcDriverDeployer.class); + startupContainer.addSingleton(ServerMetadataPersister.class); + startupContainer.addSingleton(RegisterQualityModels.class); + startupContainer.addSingleton(DeleteDeprecatedMeasures.class); + startupContainer.addSingleton(GeneratePluginIndex.class); + startupContainer.startComponents(); - startupContainer.getComponent(ServerLifecycleNotifier.class).notifyStart(); + startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart(); } finally { - startupContainer.stop(); - servicesContainer.removeChildContainer(startupContainer); - startupContainer = null; - servicesContainer.getComponent(DatabaseSessionFactory.class).clear(); + startupContainer.stopComponents(); + servicesContainer.removeChild(); + servicesContainer.getComponentByType(DatabaseSessionFactory.class).clear(); } } @@ -234,7 +233,7 @@ public final class Platform { if (rootContainer != null) { try { TimeProfiler profiler = new TimeProfiler().start("Stop sonar"); - rootContainer.stop(); + rootContainer.stopComponents(); rootContainer = null; connected = false; started = false; @@ -245,7 +244,7 @@ public final class Platform { } } - public MutablePicoContainer getContainer() { + public ComponentContainer getContainer() { if (servicesContainer != null) { return servicesContainer; } @@ -256,7 +255,7 @@ public final class Platform { } public Object getComponent(Object key) { - return getContainer().getComponent(key); + return getContainer().getComponentByKey(key); } /** diff --git a/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java b/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java index 22d798048c1..526e4f68239 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java @@ -19,17 +19,13 @@ */ package org.sonar.server.platform; -import org.apache.commons.configuration.Configuration; -import org.sonar.server.configuration.ConfigurationFactory; - import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public final class PlatformLifecycleListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { - Configuration configuration = new ConfigurationFactory().getConfiguration(event); - Platform.getInstance().init(configuration); + Platform.getInstance().init(event.getServletContext()); Platform.getInstance().start(); } diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/DefaultServerPluginRepository.java b/sonar-server/src/main/java/org/sonar/server/plugins/DefaultServerPluginRepository.java index 73defaa30d4..864b8a06a0b 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/DefaultServerPluginRepository.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/DefaultServerPluginRepository.java @@ -20,16 +20,15 @@ package org.sonar.server.plugins; import com.google.common.collect.Sets; -import org.picocontainer.Characteristics; -import org.picocontainer.MutablePicoContainer; import org.slf4j.LoggerFactory; -import org.sonar.api.*; +import org.sonar.api.Plugin; +import org.sonar.api.Properties; +import org.sonar.api.Property; import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.ServerPluginRepository; import org.sonar.core.plugins.PluginClassloaders; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Set; @@ -49,7 +48,8 @@ public class DefaultServerPluginRepository implements ServerPluginRepository { } public void start() { - pluginsByKey = classloaders.init(deployer.getMetadata()); + Collection<PluginMetadata> metadata = deployer.getMetadata(); + pluginsByKey = classloaders.init(metadata); } public void stop() { @@ -117,55 +117,4 @@ public class DefaultServerPluginRepository implements ServerPluginRepository { return deployer.getMetadata(pluginKey); } - public void registerExtensions(MutablePicoContainer container) { - registerExtensions(container, getPlugins()); - } - - void registerExtensions(MutablePicoContainer container, Collection<Plugin> plugins) { - for (Plugin plugin : plugins) { - container.as(Characteristics.CACHE).addComponent(plugin); - for (Object extension : plugin.getExtensions()) { - installExtension(container, extension, true); - } - } - installExtensionProviders(container); - } - - void installExtensionProviders(MutablePicoContainer container) { - List<ExtensionProvider> providers = container.getComponents(ExtensionProvider.class); - for (ExtensionProvider provider : providers) { - Object obj = provider.provide(); - if (obj != null) { - if (obj instanceof Iterable) { - for (Object extension : (Iterable) obj) { - installExtension(container, extension, false); - } - } else { - installExtension(container, obj, false); - } - } - } - } - - void installExtension(MutablePicoContainer container, Object extension, boolean acceptProvider) { - if (isType(extension, ServerExtension.class)) { - if (!acceptProvider && (isType(extension, ExtensionProvider.class) || extension instanceof ExtensionProvider)) { - LoggerFactory.getLogger(getClass()).error("ExtensionProvider can not include providers itself: " + extension); - } else { - container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension); - } - } - } - - static boolean isType(Object extension, Class<? extends Extension> extensionClass) { - Class clazz = (extension instanceof Class ? (Class) extension : extension.getClass()); - return extensionClass.isAssignableFrom(clazz); - } - - static Object getExtensionKey(Object component) { - if (component instanceof Class) { - return component; - } - return component.getClass().getCanonicalName() + "-" + component.toString(); - } } diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java b/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java new file mode 100644 index 00000000000..cf672d08c04 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java @@ -0,0 +1,101 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 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.server.plugins; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; +import org.slf4j.LoggerFactory; +import org.sonar.api.Extension; +import org.sonar.api.ExtensionProvider; +import org.sonar.api.Plugin; +import org.sonar.api.ServerExtension; +import org.sonar.api.platform.ComponentContainer; +import org.sonar.api.platform.PluginMetadata; +import org.sonar.api.platform.PluginRepository; + +import java.util.Map; + +public class ServerExtensionInstaller { + private PluginRepository pluginRepository; + + public ServerExtensionInstaller(PluginRepository pluginRepository) { + this.pluginRepository = pluginRepository; + } + + public void registerExtensions(ComponentContainer container) { + ListMultimap<PluginMetadata, Object> installedExtensionsByPlugin = ArrayListMultimap.create(); + + for (PluginMetadata pluginMetadata : pluginRepository.getMetadata()) { + Plugin plugin = pluginRepository.getPlugin(pluginMetadata.getKey()); + container.addExtension(pluginMetadata, plugin); + + for (Object extension : plugin.getExtensions()) { + if (installExtension(container, pluginMetadata, extension, true) != null) { + installedExtensionsByPlugin.put(pluginMetadata, extension); + } else { + container.declareExtension(pluginMetadata, extension); + } + } + } + for (Map.Entry<PluginMetadata, Object> entry : installedExtensionsByPlugin.entries()) { + PluginMetadata plugin = entry.getKey(); + Object extension = entry.getValue(); + if (isExtensionProvider(extension)) { + ExtensionProvider provider = (ExtensionProvider) container.getComponentByKey(extension); + installProvider(container, plugin, provider); + } + } + } + + private void installProvider(ComponentContainer container, PluginMetadata plugin, ExtensionProvider provider) { + Object obj = provider.provide(); + if (obj != null) { + if (obj instanceof Iterable) { + for (Object ext : (Iterable) obj) { + installExtension(container, plugin, ext, false); + } + } else { + installExtension(container, plugin, obj, false); + } + } + } + + Object installExtension(ComponentContainer container, PluginMetadata pluginMetadata, Object extension, boolean acceptProvider) { + if (isType(extension, ServerExtension.class)) { + if (!acceptProvider && isExtensionProvider(extension)) { + LoggerFactory.getLogger(getClass()).error("ExtensionProvider can not include providers itself: " + extension); + } else { + container.addExtension(pluginMetadata, extension); + return extension; + } + } + return null; + } + + static boolean isExtensionProvider(Object extension) { + return isType(extension, ExtensionProvider.class) || extension instanceof ExtensionProvider; + } + + static boolean isType(Object extension, Class<? extends Extension> extensionClass) { + Class clazz = (extension instanceof Class ? (Class) extension : extension.getClass()); + return extensionClass.isAssignableFrom(clazz); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java b/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java index 1dca1b380ea..83068721c6c 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java @@ -44,7 +44,7 @@ public class StaticResourcesServlet extends HttpServlet { String pluginKey = getPluginKey(request); String resource = getResourcePath(request); - DefaultServerPluginRepository pluginRepository = Platform.getInstance().getContainer().getComponent(DefaultServerPluginRepository.class); + DefaultServerPluginRepository pluginRepository = Platform.getInstance().getContainer().getComponentByType(DefaultServerPluginRepository.class); ClassLoader classLoader = pluginRepository.getClassloader(pluginKey); if (classLoader == null) { LOG.error("Plugin not found: " + pluginKey); diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java b/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java index 7dbcc8543d1..32a7ae076b3 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java @@ -19,10 +19,12 @@ */ package org.sonar.server.plugins; -import org.apache.commons.configuration.Configuration; import org.apache.commons.io.IOUtils; import org.slf4j.LoggerFactory; +import org.sonar.api.Properties; +import org.sonar.api.Property; import org.sonar.api.ServerComponent; +import org.sonar.api.config.Settings; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.Logs; import org.sonar.updatecenter.common.UpdateCenter; @@ -32,17 +34,32 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.Date; -import java.util.Properties; + /** * HTTP client to load data from the remote update center hosted at http://update.sonarsource.org. * * @since 2.4 */ +@Properties({ + @Property( + key = "sonar.updatecenter.activate", + defaultValue = "true", + name = "Enable Update Center", + project = false, + global = false, // hidden from UI + category = "Update Center"), + @Property( + key = UpdateCenterClient.URL_PROPERTY, + defaultValue = "http://update.sonarsource.org/update-center.properties", + name = "Update Center URL", + project = false, + global = false, // hidden from UI + category = "Update Center") +}) public class UpdateCenterClient implements ServerComponent { public static final String URL_PROPERTY = "sonar.updatecenter.url"; - public static final String DEFAULT_URL = "http://update.sonarsource.org/update-center.properties"; public static final int PERIOD_IN_MILLISECONDS = 60 * 60 * 1000; private URI uri; @@ -59,8 +76,8 @@ public class UpdateCenterClient implements ServerComponent { Logs.INFO.info("Update center: " + uri + " (" + downloader.getProxySynthesis(uri) + ")"); } - public UpdateCenterClient(HttpDownloader downloader, Configuration configuration) throws URISyntaxException { - this(downloader, new URI(configuration.getString(URL_PROPERTY, DEFAULT_URL))); + public UpdateCenterClient(HttpDownloader downloader, Settings configuration) throws URISyntaxException { + this(downloader, new URI(configuration.getString(URL_PROPERTY))); } public UpdateCenter getCenter() { @@ -88,7 +105,7 @@ public class UpdateCenterClient implements ServerComponent { try { input = downloader.openStream(uri); if (input != null) { - Properties properties = new Properties(); + java.util.Properties properties = new java.util.Properties(); properties.load(input); return UpdateCenterDeserializer.fromProperties(properties); } diff --git a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java index fd7fb4a501d..f61f2bc1b73 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java @@ -19,17 +19,17 @@ */ package org.sonar.server.startup; -import org.apache.commons.configuration.Configuration; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.config.Settings; import org.sonar.api.utils.Logs; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.TimeProfiler; import org.sonar.api.utils.ZipUtils; import org.sonar.api.web.GwtExtension; -import org.sonar.server.configuration.CoreConfiguration; +import org.sonar.server.configuration.ServerSettings; import java.io.File; import java.io.IOException; @@ -41,13 +41,13 @@ import java.util.zip.ZipEntry; public class GwtPublisher { private static final Logger LOG = LoggerFactory.getLogger(GwtPublisher.class); - private Configuration configuration; + private Settings settings; private GwtExtension[] extensions = null; private File outputDir = null; - public GwtPublisher(GwtExtension[] extensions, Configuration configuration) { + public GwtPublisher(GwtExtension[] extensions, Settings settings) { this.extensions = extensions; - this.configuration = configuration; + this.settings = settings; } protected GwtPublisher(GwtExtension[] extensions, File outputDir) { @@ -62,7 +62,7 @@ public class GwtPublisher { TimeProfiler profiler = new TimeProfiler().start("Deploy GWT plugins"); try { cleanDirectory(); - this.outputDir = new File(configuration.getString(CoreConfiguration.DEPLOY_DIR), "gwt"); + this.outputDir = new File(settings.getString(ServerSettings.DEPLOY_DIR), "gwt"); Logs.INFO.debug("publish {} GWT extensions to {}", extensions.length, outputDir); publish(); diff --git a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java index ed42799fd97..17038c09756 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java @@ -19,12 +19,12 @@ */ package org.sonar.server.ui; -import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.ServerComponent; +import org.sonar.api.config.Settings; import org.sonar.api.security.LoginPasswordAuthenticator; public class AuthenticatorFactory implements ServerComponent { @@ -37,17 +37,17 @@ public class AuthenticatorFactory implements ServerComponent { private boolean ignoreStartupFailure; private LoginPasswordAuthenticator[] authenticators; - public AuthenticatorFactory(Configuration configuration, LoginPasswordAuthenticator[] authenticators) { - classname = configuration.getString(CoreProperties.CORE_AUTHENTICATOR_CLASS); - ignoreStartupFailure = configuration.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, false); + public AuthenticatorFactory(Settings settings, LoginPasswordAuthenticator[] authenticators) { + classname = settings.getString(CoreProperties.CORE_AUTHENTICATOR_CLASS); + ignoreStartupFailure = settings.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE); this.authenticators = authenticators; } /** * This constructor is used when there aren't any authentication plugins. */ - public AuthenticatorFactory(Configuration configuration) { - this(configuration, null); + public AuthenticatorFactory(Settings settings) { + this(settings, null); } /** diff --git a/sonar-server/src/main/java/org/sonar/server/ui/DatabaseSessionFilter.java b/sonar-server/src/main/java/org/sonar/server/ui/DatabaseSessionFilter.java index 1c7d6f43123..7b8db246bce 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/DatabaseSessionFilter.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/DatabaseSessionFilter.java @@ -33,7 +33,7 @@ public class DatabaseSessionFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); - DatabaseSessionFactory sessionFactory = Platform.getInstance().getContainer().getComponent(DatabaseSessionFactory.class); + DatabaseSessionFactory sessionFactory = Platform.getInstance().getContainer().getComponentByType(DatabaseSessionFactory.class); if (sessionFactory != null) { sessionFactory.clear(); } diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index bb8d0d3b99b..59598488060 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -20,9 +20,10 @@ package org.sonar.server.ui; import org.apache.commons.configuration.Configuration; -import org.picocontainer.PicoContainer; import org.slf4j.LoggerFactory; -import org.sonar.api.Property; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.Settings; +import org.sonar.api.platform.ComponentContainer; import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.PluginRepository; import org.sonar.api.profiles.ProfileExporter; @@ -36,8 +37,8 @@ import org.sonar.core.i18n.RuleI18nManager; import org.sonar.jpa.dialect.Dialect; import org.sonar.jpa.session.DatabaseConnector; import org.sonar.markdown.Markdown; +import org.sonar.server.configuration.ServerSettings; import org.sonar.server.configuration.Backup; -import org.sonar.server.configuration.CoreConfiguration; import org.sonar.server.configuration.ProfilesManager; import org.sonar.server.filters.Filter; import org.sonar.server.filters.FilterExecutor; @@ -66,52 +67,51 @@ public final class JRubyFacade { } public FilterResult executeFilter(Filter filter) { - return getContainer().getComponent(FilterExecutor.class).execute(filter); + return getContainer().getComponentByType(FilterExecutor.class).execute(filter); } // UPDATE CENTER ------------------------------------------------------------ public void downloadPlugin(String pluginKey, String pluginVersion) { - getContainer().getComponent(PluginDownloader.class).download(pluginKey, Version.create(pluginVersion)); + getContainer().getComponentByType(PluginDownloader.class).download(pluginKey, Version.create(pluginVersion)); } public void cancelPluginDownloads() { - getContainer().getComponent(PluginDownloader.class).cancelDownloads(); + getContainer().getComponentByType(PluginDownloader.class).cancelDownloads(); } public List<String> getPluginDownloads() { - return getContainer().getComponent(PluginDownloader.class).getDownloads(); + return getContainer().getComponentByType(PluginDownloader.class).getDownloads(); } public void uninstallPlugin(String pluginKey) { - getContainer().getComponent(PluginDeployer.class).uninstall(pluginKey); + getContainer().getComponentByType(PluginDeployer.class).uninstall(pluginKey); } public void cancelPluginUninstalls() { - getContainer().getComponent(PluginDeployer.class).cancelUninstalls(); + getContainer().getComponentByType(PluginDeployer.class).cancelUninstalls(); } public List<String> getPluginUninstalls() { - return getContainer().getComponent(PluginDeployer.class).getUninstalls(); + return getContainer().getComponentByType(PluginDeployer.class).getUninstalls(); } public UpdateCenterMatrix getUpdateCenterMatrix(boolean forceReload) { - return getContainer().getComponent(UpdateCenterMatrixFactory.class).getMatrix(forceReload); + return getContainer().getComponentByType(UpdateCenterMatrixFactory.class).getMatrix(forceReload); } // PLUGINS ------------------------------------------------------------------ - public Property[] getPluginProperties(PluginMetadata metadata) { - PluginRepository repository = getContainer().getComponent(PluginRepository.class); - return repository.getProperties(repository.getPlugin(metadata.getKey())); + public PropertyDefinitions getPropertyDefinitions() { + return getContainer().getComponentByType(PropertyDefinitions.class); } public boolean hasPlugin(String key) { - return getContainer().getComponent(PluginRepository.class).getPlugin(key) != null; + return getContainer().getComponentByType(PluginRepository.class).getPlugin(key) != null; } public Collection<PluginMetadata> getPluginsMetadata() { - return getContainer().getComponent(PluginRepository.class).getMetadata(); + return getContainer().getComponentByType(PluginRepository.class).getMetadata(); } @@ -119,7 +119,7 @@ public final class JRubyFacade { public String colorizeCode(String code, String language) { try { - return getContainer().getComponent(CodeColorizers.class).toHtml(code, language); + return getContainer().getComponentByType(CodeColorizers.class).toHtml(code, language); } catch (Exception e) { LoggerFactory.getLogger(getClass()).error("Can not highlight the code, language= " + language, e); @@ -133,89 +133,89 @@ public final class JRubyFacade { public List<ViewProxy<Widget>> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage) { - return getContainer().getComponent(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage); + return getContainer().getComponentByType(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage); } public List<ViewProxy<Widget>> getWidgets() { - return getContainer().getComponent(Views.class).getWidgets(); + return getContainer().getComponentByType(Views.class).getWidgets(); } public ViewProxy<Widget> getWidget(String id) { - return getContainer().getComponent(Views.class).getWidget(id); + return getContainer().getComponentByType(Views.class).getWidget(id); } public List<ViewProxy<Page>> getPages(String section, String resourceScope, String resourceQualifier, String resourceLanguage) { - return getContainer().getComponent(Views.class).getPages(section, resourceScope, resourceQualifier, resourceLanguage); + return getContainer().getComponentByType(Views.class).getPages(section, resourceScope, resourceQualifier, resourceLanguage); } public List<ViewProxy<Page>> getResourceTabs() { - return getContainer().getComponent(Views.class).getPages(NavigationSection.RESOURCE_TAB, null, null, null); + return getContainer().getComponentByType(Views.class).getPages(NavigationSection.RESOURCE_TAB, null, null, null); } public List<ViewProxy<Page>> getResourceTabs(String scope, String qualifier, String language) { - return getContainer().getComponent(Views.class).getPages(NavigationSection.RESOURCE_TAB, scope, qualifier, language); + return getContainer().getComponentByType(Views.class).getPages(NavigationSection.RESOURCE_TAB, scope, qualifier, language); } public List<ViewProxy<Page>> getResourceTabsForMetric(String scope, String qualifier, String language, String metric) { - return getContainer().getComponent(Views.class).getPagesForMetric(NavigationSection.RESOURCE_TAB, scope, qualifier, language, metric); + return getContainer().getComponentByType(Views.class).getPagesForMetric(NavigationSection.RESOURCE_TAB, scope, qualifier, language, metric); } public ViewProxy<Page> getPage(String id) { - return getContainer().getComponent(Views.class).getPage(id); + return getContainer().getComponentByType(Views.class).getPage(id); } public Collection<RubyRailsWebservice> getRubyRailsWebservices() { - return getContainer().getComponents(RubyRailsWebservice.class); + return getContainer().getComponentsByType(RubyRailsWebservice.class); } public Collection<Language> getLanguages() { - return getContainer().getComponents(Language.class); + return getContainer().getComponentsByType(Language.class); } public Dialect getDialect() { - return getContainer().getComponent(DatabaseConnector.class).getDialect(); + return getContainer().getComponentByType(DatabaseConnector.class).getDialect(); } /* PROFILES CONSOLE : RULES AND METRIC THRESHOLDS */ public List<RuleRepository> getRuleRepositories() { - return getContainer().getComponent(RulesConsole.class).getRepositories(); + return getContainer().getComponentByType(RulesConsole.class).getRepositories(); } public RuleRepository getRuleRepository(String repositoryKey) { - return getContainer().getComponent(RulesConsole.class).getRepository(repositoryKey); + return getContainer().getComponentByType(RulesConsole.class).getRepository(repositoryKey); } public Set<RuleRepository> getRuleRepositoriesByLanguage(String languageKey) { - return getContainer().getComponent(RulesConsole.class).getRepositoriesByLanguage(languageKey); + return getContainer().getComponentByType(RulesConsole.class).getRepositoriesByLanguage(languageKey); } public String backupProfile(int profileId) { - return getContainer().getComponent(ProfilesConsole.class).backupProfile(profileId); + return getContainer().getComponentByType(ProfilesConsole.class).backupProfile(profileId); } public ValidationMessages restoreProfile(String xmlBackup) { - return getContainer().getComponent(ProfilesConsole.class).restoreProfile(xmlBackup); + return getContainer().getComponentByType(ProfilesConsole.class).restoreProfile(xmlBackup); } public List<ProfileExporter> getProfileExportersForLanguage(String language) { - return getContainer().getComponent(ProfilesConsole.class).getProfileExportersForLanguage(language); + return getContainer().getComponentByType(ProfilesConsole.class).getProfileExportersForLanguage(language); } public List<ProfileImporter> getProfileImportersForLanguage(String language) { - return getContainer().getComponent(ProfilesConsole.class).getProfileImportersForLanguage(language); + return getContainer().getComponentByType(ProfilesConsole.class).getProfileImportersForLanguage(language); } public String exportProfile(int profileId, String exporterKey) { - return getContainer().getComponent(ProfilesConsole.class).exportProfile(profileId, exporterKey); + return getContainer().getComponentByType(ProfilesConsole.class).exportProfile(profileId, exporterKey); } public ValidationMessages importProfile(String profileName, String language, String importerKey, String fileContent) { - return getContainer().getComponent(ProfilesConsole.class).importProfile(profileName, language, importerKey, fileContent); + return getContainer().getComponentByType(ProfilesConsole.class).importProfile(profileName, language, importerKey, fileContent); } public String getProfileExporterMimeType(String exporterKey) { - return getContainer().getComponent(ProfilesConsole.class).getProfileExporter(exporterKey).getMimeType(); + return getContainer().getComponentByType(ProfilesConsole.class).getProfileExporter(exporterKey).getMimeType(); } public void renameProfile(int profileId, String newProfileName) { @@ -256,36 +256,40 @@ public final class JRubyFacade { } public List<Footer> getWebFooters() { - return getContainer().getComponents(Footer.class); + return getContainer().getComponentsByType(Footer.class); } public Backup getBackup() { - return getContainer().getComponent(Backup.class); + return getContainer().getComponentByType(Backup.class); } private ProfilesManager getProfilesManager() { - return getContainer().getComponent(ProfilesManager.class); + return getContainer().getComponentByType(ProfilesManager.class); } public void reloadConfiguration() { - getContainer().getComponent(CoreConfiguration.class).reload(); + getContainer().getComponentByType(ServerSettings.class).load(); + } + + public Settings getSettings() { + return getContainer().getComponentByType(Settings.class); } public String getConfigurationValue(String key) { - return getContainer().getComponent(Configuration.class).getString(key, null); + return getContainer().getComponentByType(Configuration.class).getString(key, null); } public List<InetAddress> getValidInetAddressesForServerId() { - return getContainer().getComponent(ServerIdGenerator.class).getAvailableAddresses(); + return getContainer().getComponentByType(ServerIdGenerator.class).getAvailableAddresses(); } public String generateServerId(String organisation, String ipAddress) { - return getContainer().getComponent(ServerIdGenerator.class).generate(organisation, ipAddress); + return getContainer().getComponentByType(ServerIdGenerator.class).generate(organisation, ipAddress); } public Connection getConnection() { try { - return getContainer().getComponent(DatabaseConnector.class).getConnection(); + return getContainer().getComponentByType(DatabaseConnector.class).getConnection(); } catch (Exception e) { /* activerecord does not correctly manage exceptions when connection can not be opened. */ return null; @@ -299,7 +303,7 @@ public final class JRubyFacade { try { Class aClass = Class.forName(className); - return getContainer().getComponent(aClass); + return getContainer().getComponentByType(aClass); } catch (ClassNotFoundException e) { LoggerFactory.getLogger(getClass()).error("Component not found: " + className, e); @@ -309,61 +313,61 @@ public final class JRubyFacade { public Object getComponentByClassname(String pluginKey, String className) { Object component = null; - PicoContainer container = getContainer(); - Class componentClass = container.getComponent(DefaultServerPluginRepository.class).getClass(pluginKey, className); + ComponentContainer container = getContainer(); + Class componentClass = container.getComponentByType(DefaultServerPluginRepository.class).getClass(pluginKey, className); if (componentClass != null) { - component = container.getComponent(componentClass); + component = container.getComponentByType(componentClass); } return component; } public String getMessage(String rubyLocale, String key, String defaultValue, Object... parameters) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.message(rubyLocale, key, defaultValue, parameters); } public String getRuleName(String rubyLocale, String repositoryKey, String key) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.getRuleName(rubyLocale, repositoryKey, key); } public String getRuleDescription(String rubyLocale, String repositoryKey, String key) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.getRuleDescription(rubyLocale, repositoryKey, key); } public String getRuleParamDescription(String rubyLocale, String repositoryKey, String key, String paramKey) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.getRuleParamDescription(rubyLocale, repositoryKey, key, paramKey); } public List<RuleI18nManager.RuleKey> searchRuleName(String rubyLocale, String searchText) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.searchRuleName(rubyLocale, searchText); } public String getJsL10nDictionnary(String rubyLocale) { if (i18n == null) { - i18n = getContainer().getComponent(JRubyI18n.class); + i18n = getContainer().getComponentByType(JRubyI18n.class); } return i18n.getJsDictionnary(rubyLocale); } public ReviewsNotificationManager getReviewsNotificationManager() { - return getContainer().getComponent(ReviewsNotificationManager.class); + return getContainer().getComponentByType(ReviewsNotificationManager.class); } - public PicoContainer getContainer() { + public ComponentContainer getContainer() { return Platform.getInstance().getContainer(); } } diff --git a/sonar-server/src/main/resources/sonar-war.properties b/sonar-server/src/main/resources/sonar-war.properties new file mode 100644 index 00000000000..f0787339955 --- /dev/null +++ b/sonar-server/src/main/resources/sonar-war.properties @@ -0,0 +1,9 @@ +# This file is used only when deploying the webapp to an application server. +# It is ignored when using the standalone mode shipped by default. + +# The path to the Sonar home directory must be defined : +# - by setting the environment variable SONAR_HOME in the app server +# - or by setting the system property sonar.home in the app server +# - or by uncommenting and setting the following property before deploying the webapp + +#sonar.home=
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb index c9097ef560d..f62514c0a9e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb @@ -121,15 +121,12 @@ class ProjectController < ApplicationController @category=params[:category] ||= 'general' @properties_per_category={} - java_facade.getPluginsMetadata().each do |plugin| - properties=java_facade.getPluginProperties(plugin).select { |property| - (@project.module? && property.module()) || (@project.project? && property.project()) - } - properties.each do |property| - category = (property.category().present? ? property.category() : plugin.name()) - @properties_per_category[category]||=[] - @properties_per_category[category]<<property - end + definitions = java_facade.getPropertyDefinitions() + properties = definitions.getProperties().select {|property| (@project.module? && property.module()) || (@project.project? && property.project())} + properties.each do |property| + category = definitions.getCategory(property.key()) + @properties_per_category[category]||=[] + @properties_per_category[category]<<property end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb index d3d27285c9e..76a404306d6 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb @@ -75,13 +75,13 @@ class SettingsController < ApplicationController def load_properties(all=true) @category=params[:category] @properties_per_category={} - java_facade.getPluginsMetadata().each do |plugin| - java_facade.getPluginProperties(plugin).select { |property| all || property.global }.each do |property| - category = (property.category().present? ? property.category() : plugin.name()) - @properties_per_category[category]||=[] - @properties_per_category[category]<<property - end + definitions = java_facade.getPropertyDefinitions() + definitions.getProperties().select {|property| property.global}.each do |property| + category = definitions.getCategory(property.key()) + @properties_per_category[category]||=[] + @properties_per_category[category]<<property end + SPECIAL_CATEGORIES.each do |category| @properties_per_category[category]=[] end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/updatecenter_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/updatecenter_controller.rb index e74eb71b56d..c6deb1c0f86 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/updatecenter_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/updatecenter_controller.rb @@ -137,8 +137,8 @@ class UpdatecenterController < ApplicationController end def updatecenter_activated - update_center_activated = java_facade.getConfigurationValue('sonar.updatecenter.activate') || 'true'; - if update_center_activated!='true' + update_center_activated = java_facade.getSettings().getBoolean('sonar.updatecenter.activate') + unless update_center_activated redirect_to home_url end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb index d39d7fda380..7c54458f96c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb @@ -143,7 +143,7 @@ class UsersController < ApplicationController def prepare_user user = User.new(params[:user]) - default_group_name=java_facade.getConfigurationValue('sonar.defaultGroup') || 'sonar-users'; + default_group_name=java_facade.getSettings().getString('sonar.defaultGroup') default_group=Group.find_by_name(default_group_name) user.groups<<default_group if default_group user diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb index 81df96f4895..659920e9c2e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb @@ -154,7 +154,7 @@ module ApplicationHelper end def configuration(key, default = nil) - prop_value = Java::OrgSonarServerUi::JRubyFacade.getInstance().getContainer().getComponent(Java::OrgApacheCommonsConfiguration::Configuration.java_class).getProperty(key) + prop_value = Java::OrgSonarServerUi::JRubyFacade.getInstance().getContainer().getComponentByType(Java::OrgApacheCommonsConfiguration::Configuration.java_class).getProperty(key) prop_value.nil? ? default : prop_value end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb index 0e2aaad99bb..0e620caf9b2 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb @@ -123,7 +123,7 @@ class Server end def sonar_property(key) - Java::OrgSonarServerUi::JRubyFacade.getInstance().getContainer().getComponent(Java::OrgApacheCommonsConfiguration::Configuration.java_class).getProperty(key) + Java::OrgSonarServerUi::JRubyFacade.getInstance().getContainer().getComponentByType(Java::OrgApacheCommonsConfiguration::Configuration.java_class).getProperty(key) end def jdbc_metadata diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 8832d05aec2..d60a9f3719f 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -94,8 +94,8 @@ <li class="<%= 'selected' if request.request_uri.include?('/settings') -%>"><a href="<%= ApplicationController.root_context -%>/settings/index"><%= message('settings.page') -%></a></li> <li class="<%= 'selected' if controller.controller_path=='backup' -%>"><a href="<%= ApplicationController.root_context -%>/backup"><%= message('backup.page') -%></a></li> <li class="<%= 'selected' if controller.controller_path=='system' -%>"><a href="<%= ApplicationController.root_context -%>/system"><%= message('system_info.page') -%></a></li> - <% update_center_activated = controller.java_facade.getConfigurationValue('sonar.updatecenter.activate') || 'true'; - if update_center_activated=='true' %> + <% update_center_activated = controller.java_facade.getSettings().getBoolean('sonar.updatecenter.activate') + if update_center_activated %> <li class="<%= 'selected' if controller.controller_path=='updatecenter' -%>"><a href="<%= ApplicationController.root_context -%>/updatecenter"><%= message('update_center.page') -%></a></li> <% end %> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb index b4f518ec9c4..03d54ac198a 100644 --- a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb +++ b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb @@ -119,8 +119,10 @@ class DatabaseVersion end def self.use_structure_dump? - # default value is true - ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.useStructureDump')!='false' + # Important : default value is not loaded at this time by org.sonar.api.config.PropertyDefinitions. + # That's why the Settings component does not return the default value (true) when + # the property is not set. + ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getSettings().getString('sonar.useStructureDump')!='false' end def self.production? diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb index 8df6024d53f..52ccec511e0 100644 --- a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb +++ b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb @@ -92,8 +92,8 @@ module NeedAuthentication # Downcase login (typically for Active Directory) # Note that login in Sonar DB is case-sensitive, however in this case authentication and automatic user creation will always happen with downcase login - downcase = java_facade.getConfigurationValue('sonar.authenticator.downcase') - if downcase == 'true' + downcase = java_facade.getSettings().getBoolean('sonar.authenticator.downcase') + if downcase login = login.downcase end @@ -101,12 +101,12 @@ module NeedAuthentication user = User.find_by_login(login) # Automatically create a user in the sonar db if authentication has been successfully done - create_user = java_facade.getConfigurationValue('sonar.authenticator.createUsers') - if !user && create_user=='true' + create_user = java_facade.getSettings().getBoolean('sonar.authenticator.createUsers') + if !user && create_user user=User.new(:login => login, :name => login, :email => '', :password => password, :password_confirmation => password) user.save! - default_group_name = java_facade.getConfigurationValue('sonar.defaultGroup') || 'sonar-users' + default_group_name = java_facade.getSettings().getString('sonar.defaultGroup') default_group=Group.find_by_name(default_group_name) if default_group user.groups<<default_group diff --git a/sonar-server/src/test/java/org/sonar/server/configuration/ConfigurationFactoryTest.java b/sonar-server/src/test/java/org/sonar/server/configuration/ConfigurationFactoryTest.java deleted file mode 100644 index 4c7e2aa39a3..00000000000 --- a/sonar-server/src/test/java/org/sonar/server/configuration/ConfigurationFactoryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 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.server.configuration; - -import org.apache.commons.configuration.Configuration; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -public class ConfigurationFactoryTest { - - @Test - public void checkExistentFile() { - Configuration configuration = new ConfigurationFactory().getConfigurationFromPropertiesFile("/org/sonar/server/configuration/ConfigurationFactoryTest/checkExistentFile.properties"); - assertNotNull(configuration); - assertThat(configuration.getString("this"), is("is a test")); - } - - @Test(expected = ConfigurationException.class) - public void failsWhenFileNotFound() { - new ConfigurationFactory().getConfigurationFromPropertiesFile("unknown.properties"); - } - - @Test - public void shouldReadEnvironmentVariables() { - Configuration configuration = new ConfigurationFactory().getConfigurationFromPropertiesFile("/org/sonar/server/configuration/ConfigurationFactoryTest/shouldReadEnvironmentVariables.properties"); - assertNotNull(configuration); - assertThat(configuration.getString("my.param.one"), is("foo")); - assertThat(configuration.getString("my.param.two"), is(System.getenv("PATH"))); - } - -} diff --git a/sonar-server/src/test/java/org/sonar/server/database/EmbeddedDatabaseTest.java b/sonar-server/src/test/java/org/sonar/server/database/EmbeddedDatabaseTest.java index a75dd1fca40..8f995e3bfea 100644 --- a/sonar-server/src/test/java/org/sonar/server/database/EmbeddedDatabaseTest.java +++ b/sonar-server/src/test/java/org/sonar/server/database/EmbeddedDatabaseTest.java @@ -19,12 +19,12 @@ */ package org.sonar.server.database; -import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FileUtils; import org.apache.derby.jdbc.ClientDriver; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.sonar.api.config.Settings; import java.io.File; import java.io.IOException; @@ -52,7 +52,7 @@ public class EmbeddedDatabaseTest { if (testPort == null) { testPort = Integer.toString(findFreeServerPort()); } - defaultProps = EmbeddedDatabase.getDefaultProperties(new CompositeConfiguration()); + defaultProps = EmbeddedDatabase.getDefaultProperties(new Settings()); defaultProps.put("derby.drda.portNumber", testPort); // changing the defaut port driverUrl = "jdbc:derby://localhost:" + testPort + "/sonar;create=true;user=sonar;password=sonar"; } diff --git a/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java b/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java index e3874c385af..aa2e30497a7 100644 --- a/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java +++ b/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java @@ -24,8 +24,10 @@ import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; import org.sonar.jpa.entity.SchemaMigration; +import org.sonar.server.configuration.ServerSettings; import javax.naming.Context; import javax.persistence.EntityManagerFactory; @@ -41,7 +43,7 @@ public class JndiDatabaseConnectorTest { @Before public void setup() { - Configuration conf = new PropertiesConfiguration(); + Settings conf = new Settings(); conf.setProperty(DatabaseProperties.PROP_DIALECT, DatabaseProperties.DIALECT_HSQLDB); conf.setProperty(DatabaseProperties.PROP_URL, "jdbc:hsqldb:mem:sonar"); conf.setProperty(DatabaseProperties.PROP_DRIVER, "org.hsqldb.jdbcDriver"); @@ -69,7 +71,7 @@ public class JndiDatabaseConnectorTest { assertEquals(2, emfCreationCounter); } - private JndiDatabaseConnector getTestJndiConnector(Configuration conf) { + private JndiDatabaseConnector getTestJndiConnector(Settings conf) { JndiDatabaseConnector connector = new JndiDatabaseConnector(conf) { @Override protected int loadVersion() { diff --git a/sonar-server/src/test/java/org/sonar/server/notifications/NotificationServiceTest.java b/sonar-server/src/test/java/org/sonar/server/notifications/NotificationServiceTest.java index c75a702b3cf..38a089538ca 100644 --- a/sonar-server/src/test/java/org/sonar/server/notifications/NotificationServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/notifications/NotificationServiceTest.java @@ -19,30 +19,21 @@ */ package org.sonar.server.notifications; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import org.apache.commons.configuration.BaseConfiguration; -import org.apache.commons.configuration.Configuration; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.Settings; import org.sonar.api.notifications.Notification; import org.sonar.api.notifications.NotificationChannel; import org.sonar.api.notifications.NotificationDispatcher; import org.sonar.core.notifications.DefaultNotificationManager; import org.sonar.jpa.entity.NotificationQueueElement; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + public class NotificationServiceTest { private static String USER_SIMON = "simon"; @@ -51,9 +42,7 @@ public class NotificationServiceTest { private NotificationChannel emailChannel; private NotificationChannel gtalkChannel; - private NotificationDispatcher commentOnReviewAssignedToMe; private String assignee; - private NotificationDispatcher commentOnReviewCreatedByMe; private String creator; private DefaultNotificationManager manager; @@ -67,7 +56,7 @@ public class NotificationServiceTest { gtalkChannel = mock(NotificationChannel.class); when(gtalkChannel.getKey()).thenReturn("gtalk"); - commentOnReviewAssignedToMe = mock(NotificationDispatcher.class); + NotificationDispatcher commentOnReviewAssignedToMe = mock(NotificationDispatcher.class); when(commentOnReviewAssignedToMe.getKey()).thenReturn("comment on review assigned to me"); doAnswer(new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { @@ -76,7 +65,7 @@ public class NotificationServiceTest { } }).when(commentOnReviewAssignedToMe).dispatch(any(Notification.class), any(NotificationDispatcher.Context.class)); - commentOnReviewCreatedByMe = mock(NotificationDispatcher.class); + NotificationDispatcher commentOnReviewCreatedByMe = mock(NotificationDispatcher.class); when(commentOnReviewCreatedByMe.getKey()).thenReturn("comment on review created by me"); doAnswer(new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { @@ -85,12 +74,12 @@ public class NotificationServiceTest { } }).when(commentOnReviewCreatedByMe).dispatch(any(Notification.class), any(NotificationDispatcher.Context.class)); - NotificationDispatcher[] dispatchers = new NotificationDispatcher[] { commentOnReviewAssignedToMe, commentOnReviewCreatedByMe }; + NotificationDispatcher[] dispatchers = new NotificationDispatcher[] {commentOnReviewAssignedToMe, commentOnReviewCreatedByMe}; NotificationChannel[] channels = new NotificationChannel[] { emailChannel, gtalkChannel }; manager = mock(DefaultNotificationManager.class); - Configuration configuration = new BaseConfiguration(); - configuration.setProperty("sonar.notifications.delay", "1"); // delay 1 second - service = spy(new NotificationService(configuration, manager, dispatchers, channels)); + Settings settings = new Settings(new PropertyDefinitions(NotificationService.class)); + settings.setProperty("sonar.notifications.delay", 1L); // delay 1 second + service = spy(new NotificationService(settings, manager, dispatchers, channels)); doReturn(false).when(manager).isEnabled(any(String.class), any(String.class), any(String.class)); } diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/DefaultServerPluginRepositoryTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/DefaultServerPluginRepositoryTest.java index afe742b1887..f9cfcc862fc 100644 --- a/sonar-server/src/test/java/org/sonar/server/plugins/DefaultServerPluginRepositoryTest.java +++ b/sonar-server/src/test/java/org/sonar/server/plugins/DefaultServerPluginRepositoryTest.java @@ -23,10 +23,11 @@ import org.apache.commons.io.FileUtils; import org.hamcrest.core.Is; import org.junit.After; import org.junit.Test; -import org.picocontainer.containers.TransientPicoContainer; -import org.sonar.api.*; +import org.sonar.api.BatchExtension; +import org.sonar.api.ExtensionProvider; +import org.sonar.api.ServerExtension; +import org.sonar.api.SonarPlugin; import org.sonar.api.platform.PluginMetadata; -import org.sonar.batch.Batch; import org.sonar.core.plugins.DefaultPluginMetadata; import java.io.File; @@ -34,7 +35,6 @@ import java.util.Arrays; import java.util.List; import static junit.framework.Assert.assertFalse; -import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertThat; @@ -75,41 +75,6 @@ public class DefaultServerPluginRepositoryTest { } @Test - public void shouldRegisterServerExtensions() { - DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); - - TransientPicoContainer container = new TransientPicoContainer(); - repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeBatchExtension.class, FakeServerExtension.class)))); - - assertThat(container.getComponents(Extension.class).size(), is(1)); - assertThat(container.getComponents(FakeServerExtension.class).size(), is(1)); - assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0)); - } - - @Test - public void shouldInvokeServerExtensionProviders() { - DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); - - TransientPicoContainer container = new TransientPicoContainer(); - repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeExtensionProvider.class)))); - - assertThat(container.getComponents(Extension.class).size(), is(2));// provider + FakeServerExtension - assertThat(container.getComponents(FakeServerExtension.class).size(), is(1)); - assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0)); - } - - @Test - public void shouldNotSupportProvidersOfProviders() { - DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); - - TransientPicoContainer container = new TransientPicoContainer(); - repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(SuperExtensionProvider.class)))); - - assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0)); - assertThat(container.getComponents(FakeServerExtension.class).size(), is(0)); - } - - @Test public void shouldDisablePlugin() { DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); repository.disable("checkstyle"); diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/ServerExtensionInstallerTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/ServerExtensionInstallerTest.java new file mode 100644 index 00000000000..f584a73c133 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/plugins/ServerExtensionInstallerTest.java @@ -0,0 +1,102 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 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.server.plugins; + +import org.junit.Test; +import org.sonar.api.BatchExtension; +import org.sonar.api.ExtensionProvider; +import org.sonar.api.ServerExtension; +import org.sonar.api.SonarPlugin; + +import java.util.Arrays; +import java.util.List; + +public class ServerExtensionInstallerTest { + @Test + public void shouldRegisterServerExtensions() { +// ExtensionRegistrar repository = new ExtensionRegistrar(mock(PluginRepository.class)); +// +// ComponentContainer container = new ComponentContainer(); +// repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeBatchExtension.class, FakeServerExtension.class)))); +// +// assertThat(container.getComponentsByType(Extension.class).size(), is(1)); +// assertThat(container.getComponentsByType(FakeServerExtension.class).size(), is(1)); +// assertThat(container.getComponentsByType(FakeBatchExtension.class).size(), is(0)); + } + + @Test + public void shouldInvokeServerExtensionProviders() { +// DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); +// +// ComponentContainer container = new ComponentContainer(); +// repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeExtensionProvider.class)))); +// +// assertThat(container.getComponentsByType(Extension.class).size(), is(2));// provider + FakeServerExtension +// assertThat(container.getComponentsByType(FakeServerExtension.class).size(), is(1)); +// assertThat(container.getComponentsByType(FakeBatchExtension.class).size(), is(0)); + } + + @Test + public void shouldNotSupportProvidersOfProviders() { +// DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class)); +// +// ComponentContainer container = new ComponentContainer(); +// repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(SuperExtensionProvider.class)))); +// +// assertThat(container.getComponentsByType(FakeBatchExtension.class).size(), is(0)); +// assertThat(container.getComponentsByType(FakeServerExtension.class).size(), is(0)); + } + + public static class FakePlugin extends SonarPlugin { + private List<Class> extensions; + + public FakePlugin(List<Class> extensions) { + this.extensions = extensions; + } + + public List getExtensions() { + return extensions; + } + } + + public static class FakeBatchExtension implements BatchExtension { + + } + + public static class FakeServerExtension implements ServerExtension { + + } + + public static class FakeExtensionProvider extends ExtensionProvider implements ServerExtension { + + @Override + public Object provide() { + return Arrays.asList(FakeBatchExtension.class, FakeServerExtension.class); + } + } + + public static class SuperExtensionProvider extends ExtensionProvider implements ServerExtension { + + @Override + public Object provide() { + return FakeExtensionProvider.class; + } + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java b/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java index 81fc553cdfb..0943141b0f4 100644 --- a/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java +++ b/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java @@ -19,9 +19,9 @@ */ package org.sonar.server.ui; -import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.Test; import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; import org.sonar.api.security.LoginPasswordAuthenticator; import static org.hamcrest.Matchers.is; @@ -33,48 +33,48 @@ public class AuthenticatorFactoryTest { @Test public void doNotFailIfNoAuthenticationPlugins() { - AuthenticatorFactory factory = new AuthenticatorFactory(new PropertiesConfiguration()); + AuthenticatorFactory factory = new AuthenticatorFactory(new Settings()); assertThat(factory.getAuthenticator(), nullValue()); } @Test public void startSelectedAuthenticator() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName()); + Settings settings = new Settings(); + settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName()); LoginPasswordAuthenticator authenticator = new FakeAuthenticator(); - AuthenticatorFactory factory = new AuthenticatorFactory(configuration, new LoginPasswordAuthenticator[]{authenticator}); + AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{authenticator}); factory.start(); assertThat(factory.getAuthenticator(), is(authenticator)); } @Test(expected = ConnectionException.class) public void authenticatorDoesNotStart() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName()); + Settings settings = new Settings(); + settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName()); - AuthenticatorFactory factory = new AuthenticatorFactory(configuration, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); + AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); factory.start(); factory.getAuthenticator(); } @Test(expected = AuthenticatorNotFoundException.class) public void authenticatorNotFound() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "foo"); + Settings settings = new Settings(); + settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "foo"); - AuthenticatorFactory factory = new AuthenticatorFactory(configuration, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); + AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); factory.start(); factory.getAuthenticator(); } @Test public void ignoreStartupFailure() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName()); - configuration.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, Boolean.TRUE.toString()); + Settings settings = new Settings(); + settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName()); + settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, Boolean.TRUE); - AuthenticatorFactory factory = new AuthenticatorFactory(configuration, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); + AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()}); factory.start(); assertThat(factory.getAuthenticator(), not(nullValue())); } |