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.core.persistence.Database;
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 Database database;
049 private File deployDir;
050 private File homeDir;
051
052 public DefaultServerFileSystem(Database database, Settings settings) {
053 this.database = database;
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(Database database, File homeDir, File deployDir) {
066 this.database = database;
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 getTempDir() {
107 return new File(homeDir, "temp");
108 }
109
110 public File getDeployDir() {
111 return deployDir;
112 }
113
114 public File getDeployedJdbcDriver() {
115 return new File(deployDir, "jdbc-driver.jar");
116 }
117
118 public File getDeployedPluginsDir() {
119 return new File(deployDir, "plugins");
120 }
121
122 public File getDownloadedPluginsDir() {
123 return new File(getHomeDir(), "extensions/downloads");
124 }
125
126 public File getRemovedPluginsDir() {
127 return new File(getHomeDir(), "extensions/trash");
128 }
129
130 public File getJdbcDriver() {
131 String dialect = database.getDialect().getId();
132 File dir = new File(getHomeDir(), "/extensions/jdbc-driver/" + dialect + "/");
133 List<File> jars = getFiles(dir, "jar");
134 if (jars.isEmpty()) {
135 throw new ServerStartException("No JDBC driver found in " + dir.getAbsolutePath());
136 }
137 if (jars.size() > 1) {
138 throw new ServerStartException("The directory " + dir.getAbsolutePath() + " accepts only a single JAR file");
139 }
140 return jars.get(0);
141 }
142
143 public List<File> getCorePlugins() {
144 File corePluginsDir = new File(getHomeDir(), "lib/core-plugins");
145 return getFiles(corePluginsDir, "jar");
146 }
147
148 public List<File> getUserPlugins() {
149 File pluginsDir = getUserPluginsDir();
150 return getFiles(pluginsDir, "jar");
151 }
152
153 public File getUserPluginsDir() {
154 return new File(getHomeDir(), "extensions/plugins");
155 }
156
157 public File getDeprecatedPluginsDir() {
158 return new File(getHomeDir(), "extensions/deprecated");
159 }
160
161
162 public File getPluginIndex() {
163 return new File(getDeployDir(), "plugins/index.txt");
164 }
165
166 public List<File> getExtensions(String dirName, String... suffixes) {
167 File dir = new File(getHomeDir(), "extensions/rules/" + dirName);
168 if (dir.exists() && dir.isDirectory()) {
169 return getFiles(dir, suffixes);
170 }
171 return Collections.emptyList();
172 }
173
174 public List<File> getPluginExtensionXml(String pluginKey) {
175 File dir = new File(getHomeDir(), "extensions/rules/" + pluginKey);
176 if (dir.exists() && dir.isDirectory()) {
177 return getFiles(dir, "xml");
178 }
179 return Collections.emptyList();
180 }
181
182 private List<File> getFiles(File dir, String... fileSuffixes) {
183 List<File> files = new ArrayList<File>();
184 if (dir != null && dir.exists()) {
185 if (fileSuffixes != null && fileSuffixes.length > 0) {
186 files.addAll(FileUtils.listFiles(dir, fileSuffixes, false));
187 } else {
188 files.addAll(FileUtils.listFiles(dir, null, false));
189 }
190 }
191 return files;
192 }
193 }