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