001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.server.platform;
021    
022    import com.google.common.annotations.VisibleForTesting;
023    import org.apache.commons.configuration.Configuration;
024    import org.sonar.api.CoreProperties;
025    import org.sonar.api.config.PropertyDefinitions;
026    import org.sonar.api.config.Settings;
027    import org.sonar.core.config.ConfigurationUtils;
028    import org.sonar.core.properties.PropertiesDao;
029    import org.sonar.core.properties.PropertyDto;
030    
031    import javax.servlet.ServletContext;
032    import java.io.File;
033    import java.util.List;
034    import java.util.Properties;
035    
036    /**
037     * Load settings in the following order (the last override the first) :
038     * <ol>
039     * <li>general settings persisted in database</li>
040     * <li>file $SONAR_HOME/conf/sonar.properties</li>
041     * <li>environment variables</li>
042     * <li>system properties</li>
043     * </ol>
044     *
045     * @since 2.12
046     */
047    public class ServerSettings extends Settings {
048    
049      public static final String DEPLOY_DIR = "sonar.web.deployDir";
050    
051      private PropertiesDao propertiesDao;
052      private Configuration deprecatedConfiguration;
053      private File deployDir;
054    
055      public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext) {
056        super(definitions);
057        this.deprecatedConfiguration = deprecatedConfiguration;
058        this.deployDir = getDeployDir(servletContext);
059        load();
060      }
061    
062      ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, File deployDir, File sonarHome) {
063        super(definitions);
064        this.deprecatedConfiguration = deprecatedConfiguration;
065        this.deployDir = deployDir;
066        load(sonarHome);
067      }
068    
069      public ServerSettings activateDatabaseSettings(PropertiesDao dao) {
070        return activateDatabaseSettings(dao, SonarHome.getHome());
071      }
072    
073      @VisibleForTesting
074      ServerSettings activateDatabaseSettings(PropertiesDao dao, File sonarHome) {
075        this.propertiesDao = dao;
076        load(sonarHome);
077        return this;
078      }
079    
080      private ServerSettings load() {
081        return load(SonarHome.getHome());
082      }
083    
084      private ServerSettings load(File sonarHome) {
085        clear();
086        setProperty(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath());
087        setProperty(DEPLOY_DIR, deployDir.getAbsolutePath());
088    
089        // order is important : the last override the first
090        loadDatabaseSettings();
091        loadPropertiesFile(sonarHome);
092        addEnvironmentVariables();
093        addSystemProperties();
094    
095        // update deprecated configuration
096        ConfigurationUtils.copyToCommonsConfiguration(properties, deprecatedConfiguration);
097    
098        return this;
099      }
100    
101      private void loadDatabaseSettings() {
102        if (propertiesDao != null) {
103          List<PropertyDto> dpProps = propertiesDao.selectGlobalProperties();
104          for (PropertyDto dbProp : dpProps) {
105            setProperty(dbProp.getKey(), dbProp.getValue());
106          }
107        }
108      }
109    
110      private void loadPropertiesFile(File sonarHome) {
111        File propertiesFile = new File(sonarHome, "conf/sonar.properties");
112        if (!propertiesFile.isFile() || !propertiesFile.exists()) {
113          throw new IllegalStateException("Properties file does not exist: " + propertiesFile);
114        }
115    
116        try {
117          Properties p = ConfigurationUtils.openProperties(propertiesFile);
118          p = ConfigurationUtils.interpolateEnvVariables(p);
119          addProperties(p);
120        } catch (Exception e) {
121          throw new IllegalStateException("Fail to load configuration file: " + propertiesFile, e);
122        }
123      }
124    
125      static File getDeployDir(ServletContext servletContext) {
126        String dirname = servletContext.getRealPath("/deploy/");
127        if (dirname == null) {
128          throw new IllegalArgumentException("Web app directory not found : /deploy/");
129        }
130        File dir = new File(dirname);
131        if (!dir.exists()) {
132          throw new IllegalArgumentException("Web app directory does not exist: " + dir);
133        }
134        return dir;
135      }
136    }