001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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 org.apache.commons.io.FileUtils;
023    import org.apache.commons.lang.StringUtils;
024    import org.sonar.api.CoreProperties;
025    import org.sonar.api.config.Settings;
026    import org.sonar.api.platform.ServerFileSystem;
027    import org.sonar.api.utils.Logs;
028    import org.sonar.jpa.session.DatabaseConnector;
029    
030    import java.io.File;
031    import java.io.IOException;
032    import java.util.ArrayList;
033    import java.util.Collections;
034    import java.util.List;
035    
036    /**
037     * Introspect the filesystem and the classloader to get extension files at startup.
038     *
039     * @since 2.2
040     */
041    public class DefaultServerFileSystem implements ServerFileSystem {
042    
043      private DatabaseConnector databaseConnector;
044      private File deployDir;
045      private File homeDir;
046    
047      public DefaultServerFileSystem(DatabaseConnector databaseConnector, Settings settings) {
048        this.databaseConnector = databaseConnector;
049        this.homeDir = new File(settings.getString(CoreProperties.SONAR_HOME));
050    
051        String deployPath = settings.getString(ServerSettings.DEPLOY_DIR);
052        if (StringUtils.isNotBlank(deployPath)) {
053          this.deployDir = new File(deployPath);
054        }
055      }
056    
057      /**
058       * for unit tests
059       */
060      public DefaultServerFileSystem(DatabaseConnector databaseConnector, File homeDir, File deployDir) {
061        this.databaseConnector = databaseConnector;
062        this.deployDir = deployDir;
063        this.homeDir = homeDir;
064      }
065    
066      public void start() {
067        Logs.INFO.info("Sonar home: " + homeDir.getAbsolutePath());
068        if (!homeDir.isDirectory() || !homeDir.exists()) {
069          throw new ServerStartException("Sonar home directory does not exist");
070        }
071    
072        if (deployDir == null) {
073          throw new ServerStartException("The target directory to deploy libraries is not set");
074        }
075        try {
076          Logs.INFO.info("Deploy dir: " + deployDir.getAbsolutePath());
077          FileUtils.forceMkdir(deployDir);
078          FileUtils.cleanDirectory(deployDir);
079    
080        } catch (IOException e) {
081          throw new ServerStartException("The following directory can not be created: " + deployDir.getAbsolutePath(), e);
082        }
083    
084        File deprecated = getDeprecatedPluginsDir();
085        try {
086          FileUtils.forceMkdir(deprecated);
087          FileUtils.cleanDirectory(deprecated);
088    
089        } catch (IOException e) {
090          throw new ServerStartException("The following directory can not be created: " + deprecated.getAbsolutePath(), e);
091        }
092      }
093    
094      public File getHomeDir() {
095        return homeDir;
096      }
097    
098      public File getDeployDir() {
099        return deployDir;
100      }
101    
102      public File getDeployedJdbcDriver() {
103        return new File(deployDir, "jdbc-driver.jar");
104      }
105    
106      public File getDeployedPluginsDir() {
107        return new File(deployDir, "plugins");
108      }
109    
110      public File getDownloadedPluginsDir() {
111        return new File(getHomeDir(), "extensions/downloads");
112      }
113    
114      public File getRemovedPluginsDir() {
115        return new File(getHomeDir(), "extensions/trash");
116      }
117    
118      public File getJdbcDriver() {
119        String dialect = databaseConnector.getDialect().getId();
120        File dir = new File(getHomeDir(), "/extensions/jdbc-driver/" + dialect + "/");
121        List<File> jars = getFiles(dir, "jar");
122        if (jars.isEmpty()) {
123          throw new ServerStartException("No JDBC driver found in " + dir.getAbsolutePath());
124        }
125        if (jars.size() > 1) {
126          throw new ServerStartException("The directory " + dir.getAbsolutePath() + " accepts only one JAR file");
127        }
128        return jars.get(0);
129      }
130    
131      public List<File> getCorePlugins() {
132        File corePluginsDir = new File(getHomeDir(), "lib/core-plugins");
133        return getFiles(corePluginsDir, "jar");
134      }
135    
136      public List<File> getUserPlugins() {
137        File pluginsDir = getUserPluginsDir();
138        return getFiles(pluginsDir, "jar");
139      }
140    
141      public File getUserPluginsDir() {
142        return new File(getHomeDir(), "extensions/plugins");
143      }
144    
145      public File getDeprecatedPluginsDir() {
146        return new File(getHomeDir(), "extensions/deprecated");
147      }
148    
149      public List<File> getPluginExtensions() {
150        return getFiles(getPluginExtensionsDir(), "jar");
151      }
152    
153      public File getPluginExtensionsDir() {
154        return new File(getHomeDir(), "extensions/rules");
155      }
156    
157      public File getPluginIndex() {
158        return new File(getDeployDir(), "plugins/index.txt");
159      }
160    
161      public List<File> getExtensions(String dirName, String... suffixes) {
162        File dir = new File(getHomeDir(), "extensions/rules/" + dirName);
163        if (dir.exists() && dir.isDirectory()) {
164          return getFiles(dir, suffixes);
165        }
166        return Collections.emptyList();
167      }
168    
169      public File getPluginExtensionsDir(String pluginKey) {
170        return new File(getHomeDir(), "extensions/rules/" + pluginKey);
171      }
172    
173      public List<File> getPluginExtensionXml(String pluginKey) {
174        File dir = new File(getHomeDir(), "extensions/rules/" + pluginKey);
175        if (dir.exists() && dir.isDirectory()) {
176          return getFiles(dir, "xml");
177        }
178        return Collections.emptyList();
179      }
180    
181      public File getMaven2Plugin() {
182        File dir = new File(getHomeDir(), "lib/deprecated-maven-plugin/");
183        List<File> files = getFiles(dir, "jar");
184        if (files.isEmpty()) {
185          return null;
186        }
187        return files.get(0);
188      }
189    
190      private List<File> getFiles(File dir, String... fileSuffixes) {
191        List<File> files = new ArrayList<File>();
192        if (dir != null && dir.exists()) {
193          if (fileSuffixes != null && fileSuffixes.length > 0) {
194            files.addAll(FileUtils.listFiles(dir, fileSuffixes, false));
195          } else {
196            files.addAll(FileUtils.listFiles(dir, null, false));
197          }
198        }
199        return files;
200      }
201    }