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 }