]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3224 remove the need for server restart
authorSimon Brandhof <simon.brandhof@gmail.com>
Thu, 22 Mar 2012 18:30:15 +0000 (19:30 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Thu, 22 Mar 2012 18:31:59 +0000 (19:31 +0100)
35 files changed:
sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsApp.java [deleted file]
sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/plugins/ApplicationDeployer.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/plugins/ClassLoaderUtils.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java
sonar-server/src/main/java/org/sonar/server/startup/ApplicationDeployer.java [deleted file]
sonar-server/src/main/java/org/sonar/server/startup/ClassLoaderUtils.java [deleted file]
sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/platform/ServerFileSystemTest.java [deleted file]
sonar-server/src/test/java/org/sonar/server/plugins/ApplicationDeployerTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/plugins/ClassLoaderUtilsTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/startup/ApplicationDeployerTest.java [deleted file]
sonar-server/src/test/java/org/sonar/server/startup/ClassLoaderUtilsTest.java [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar [deleted file]
sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt [deleted file]
sonar-server/src/test/resources/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/plugins/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp.jar [deleted file]

diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsApp.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsApp.java
deleted file mode 100644 (file)
index 22c05c7..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.web;
-
-import com.google.common.annotations.Beta;
-import org.sonar.api.ServerExtension;
-
-/**
- * Complete Ruby on Rails application (controllers/helpers/models/views)
- * @since 2.15
- */
-@Beta
-public abstract class RubyRailsApp implements ServerExtension {
-
-  /**
-   * The app key, ie the plugin key. It does not relate to URLs at all.
-   */
-  public abstract String getKey();
-
-  /**
-   * The classloader path to the root directory. It contains a sub-directory named app/.
-   * <p>For example if Ruby on Rails controllers are located in /org/sonar/sqale/app/controllers/,
-   * then the path is /org/sonar/sqale</p>
-   */
-  public abstract String getPath();
-
-}
index 17f66d2abbb1df7f69602d32c890a101edead705..0560513eff26eeff863be492d31c753b4028e622 100644 (file)
@@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.jpa.session.DatabaseConnector;
+import org.sonar.core.persistence.Database;
 
 import java.io.File;
 import java.io.FileFilter;
@@ -45,12 +45,12 @@ public class DefaultServerFileSystem implements ServerFileSystem {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(DefaultServerFileSystem.class);
 
-  private DatabaseConnector databaseConnector;
+  private Database database;
   private File deployDir;
   private File homeDir;
 
-  public DefaultServerFileSystem(DatabaseConnector databaseConnector, Settings settings) {
-    this.databaseConnector = databaseConnector;
+  public DefaultServerFileSystem(Database database, Settings settings) {
+    this.database = database;
     this.homeDir = new File(settings.getString(CoreProperties.SONAR_HOME));
 
     String deployPath = settings.getString(ServerSettings.DEPLOY_DIR);
@@ -62,8 +62,8 @@ public class DefaultServerFileSystem implements ServerFileSystem {
   /**
    * for unit tests
    */
-  public DefaultServerFileSystem(DatabaseConnector databaseConnector, File homeDir, File deployDir) {
-    this.databaseConnector = databaseConnector;
+  public DefaultServerFileSystem(Database database, File homeDir, File deployDir) {
+    this.database = database;
     this.deployDir = deployDir;
     this.homeDir = homeDir;
   }
@@ -102,7 +102,7 @@ public class DefaultServerFileSystem implements ServerFileSystem {
   public File getHomeDir() {
     return homeDir;
   }
-  
+
   public File getTempDir() {
     return new File(homeDir, "temp");
   }
@@ -128,7 +128,7 @@ public class DefaultServerFileSystem implements ServerFileSystem {
   }
 
   public File getJdbcDriver() {
-    String dialect = databaseConnector.getDialect().getId();
+    String dialect = database.getDialect().getId();
     File dir = new File(getHomeDir(), "/extensions/jdbc-driver/" + dialect + "/");
     List<File> jars = getFiles(dir, "jar");
     if (jars.isEmpty()) {
index f479bab81233397de904e58c7165a834fceea8a9..682cd208416da5b5726f6f8eb17df07556e76f86 100644 (file)
@@ -141,6 +141,10 @@ public final class Platform {
     for (Class daoClass : DaoUtils.getDaoClasses()) {
       rootContainer.addSingleton(daoClass);
     }
+    rootContainer.addSingleton(PluginDeployer.class);
+    rootContainer.addSingleton(DefaultServerPluginRepository.class);
+    rootContainer.addSingleton(DefaultServerFileSystem.class);
+    rootContainer.addSingleton(ApplicationDeployer.class);
     rootContainer.startComponents();
   }
 
@@ -153,10 +157,8 @@ public final class Platform {
     coreContainer = rootContainer.createChild();
     coreContainer.addSingleton(ServerDatabaseSettingsLoader.class);
     coreContainer.addSingleton(DefaultDatabaseConnector.class);
-    coreContainer.addSingleton(PluginDeployer.class);
-    coreContainer.addSingleton(DefaultServerPluginRepository.class);
+
     coreContainer.addSingleton(ServerExtensionInstaller.class);
-    coreContainer.addSingleton(DefaultServerFileSystem.class);
     coreContainer.addSingleton(ThreadLocalDatabaseSessionFactory.class);
     coreContainer.addPicoAdapter(new DatabaseSessionProvider());
     coreContainer.startComponents();
@@ -220,7 +222,6 @@ public final class Platform {
   private void executeStartupTasks() {
     ComponentContainer startupContainer = servicesContainer.createChild();
     startupContainer.addSingleton(GwtPublisher.class);
-    startupContainer.addSingleton(ApplicationDeployer.class);
     startupContainer.addSingleton(RegisterMetrics.class);
     startupContainer.addSingleton(RegisterRules.class);
     startupContainer.addSingleton(RegisterProvidedProfiles.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/ApplicationDeployer.java b/sonar-server/src/main/java/org/sonar/server/plugins/ApplicationDeployer.java
new file mode 100644 (file)
index 0000000..ea22a3d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.api.platform.PluginRepository;
+import org.sonar.api.platform.ServerFileSystem;
+import org.sonar.server.plugins.ClassLoaderUtils;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Ruby on Rails requires the files to be on filesystem but not in Java classpath (JAR). This component extracts
+ * all the needed files from plugins and copy them to $SONAR_HOME/temp
+ *
+ * @since 2.15
+ */
+public class ApplicationDeployer {
+  private static final Logger LOG = LoggerFactory.getLogger(ApplicationDeployer.class);
+  private static final String ROR_PATH = "org/sonar/ror/";
+
+  private ServerFileSystem fileSystem;
+  private PluginRepository pluginRepository;
+
+  public ApplicationDeployer(ServerFileSystem fileSystem, PluginRepository pluginRepository) {
+    this.fileSystem = fileSystem;
+    this.pluginRepository = pluginRepository;
+  }
+
+  public void start() throws IOException {
+    deployRubyRailsApps();
+  }
+
+  private void deployRubyRailsApps() {
+    LOG.info("Deploy Ruby on Rails applications");
+    File appsDir = prepareRubyRailsRootDirectory();
+
+    for (PluginMetadata pluginMetadata : pluginRepository.getMetadata()) {
+      String pluginKey = pluginMetadata.getKey();
+      try {
+        deployRubyRailsApp(appsDir, pluginKey, pluginRepository.getPlugin(pluginKey).getClass().getClassLoader());
+      } catch (Exception e) {
+        throw new IllegalStateException("Fail to deploy Ruby on Rails application: " + pluginKey, e);
+      }
+    }
+  }
+
+  @VisibleForTesting
+  File prepareRubyRailsRootDirectory() {
+    File appsDir = new File(fileSystem.getTempDir(), "ror");
+    prepareDir(appsDir);
+    return appsDir;
+  }
+
+  @VisibleForTesting
+  static void deployRubyRailsApp(File appsDir, final String pluginKey, ClassLoader appClassLoader) {
+    if (hasRubyRailsApp(pluginKey, appClassLoader)) {
+      LOG.info("Deploy app: " + pluginKey);
+      File appDir = new File(appsDir, pluginKey);
+      ClassLoaderUtils.copyResources(appClassLoader, ROR_PATH + pluginKey, appDir, new Function<String, String>() {
+        @Override
+        public String apply(@Nullable String relativePath) {
+          // Relocate the deployed files :
+          // relativePath format is: org/sonar/ror/sqale/app/controllers/foo_controller.rb
+          // app path is: org/sonar/ror/sqale
+          // -> deployed file is app/controllers/foo_controller.rb
+          return StringUtils.substringAfter(relativePath, pluginKey + "/");
+        }
+      });
+    }
+  }
+
+  @VisibleForTesting
+  static boolean hasRubyRailsApp(String pluginKey, ClassLoader classLoader) {
+    return classLoader.getResource(ROR_PATH + pluginKey) != null;
+
+  }
+
+  private void prepareDir(File appsDir) {
+    if (appsDir.exists() && appsDir.isDirectory()) {
+      try {
+        FileUtils.deleteDirectory(appsDir);
+      } catch (IOException e) {
+        throw new IllegalStateException("Fail to delete temp directory: " + appsDir);
+      }
+    }
+    try {
+      FileUtils.forceMkdir(appsDir);
+    } catch (IOException e) {
+      throw new IllegalStateException("Fail to create temp directory: " + appsDir);
+    }
+  }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/ClassLoaderUtils.java b/sonar-server/src/main/java/org/sonar/server/plugins/ClassLoaderUtils.java
new file mode 100644 (file)
index 0000000..66bfed5
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import com.google.common.base.*;
+import com.google.common.collect.Lists;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.CharEncoding;
+import org.apache.commons.lang.StringUtils;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * TODO it this class needed in sonar-plugin-api ?
+ *
+ * @since 2.15
+ */
+public final class ClassLoaderUtils {
+
+  private ClassLoaderUtils() {
+  }
+
+  public static File copyResources(ClassLoader classLoader, String rootPath, File toDir) {
+    return copyResources(classLoader, rootPath, toDir, Functions.<String>identity());
+  }
+
+  public static File copyResources(ClassLoader classLoader, String rootPath, File toDir, Function<String, String> relocationFunction) {
+    Collection<String> relativePaths = listFiles(classLoader, rootPath);
+    for (String relativePath : relativePaths) {
+      URL resource = classLoader.getResource(relativePath);
+      String filename = relocationFunction.apply(relativePath);
+      File toFile = new File(toDir, filename);
+      try {
+        FileUtils.copyURLToFile(resource, toFile);
+      } catch (IOException e) {
+        throw new IllegalStateException("Fail to extract " + relativePath + " to " + toFile.getAbsolutePath());
+      }
+    }
+
+    return toDir;
+  }
+
+  public static Collection<String> listFiles(ClassLoader classLoader, String rootPath) {
+    return listResources(classLoader, rootPath, new Predicate<String>() {
+      @Override
+      public boolean apply(@Nullable String path) {
+        return !StringUtils.endsWith(path, "/");
+      }
+    });
+  }
+
+  public static Collection<String> listResources(ClassLoader classloader, String rootPath) {
+    return listResources(classloader, rootPath, Predicates.<String>alwaysTrue());
+  }
+
+  public static Collection<String> listResources(ClassLoader classloader, String rootPath, Predicate<String> predicate) {
+    try {
+      Collection<String> paths = Lists.newArrayList();
+      rootPath = StringUtils.removeStart(rootPath, "/");
+
+      URL root = classloader.getResource(rootPath);
+      if (root == null) {
+        return paths;
+      }
+      if (!"jar".equals(root.getProtocol())) {
+        throw new IllegalStateException("Unsupported protocol: " + root.getProtocol());
+      }
+      String jarPath = root.getPath().substring(5, root.getPath().indexOf("!")); //strip out only the JAR file
+      JarFile jar = new JarFile(URLDecoder.decode(jarPath, CharEncoding.UTF_8));
+      Enumeration<JarEntry> entries = jar.entries();
+      while (entries.hasMoreElements()) {
+        String name = entries.nextElement().getName();
+        if (name.startsWith(rootPath) && predicate.apply(name)) {
+          paths.add(name);
+        }
+      }
+      return paths;
+    } catch (Exception e) {
+      throw Throwables.propagate(e);
+    }
+  }
+}
index d098265f9774edaebd29efcbbac2517a1236cf1d..df05348967dd6de552d0a2462c1e26e5518ac803 100644 (file)
@@ -47,15 +47,15 @@ public class PluginDeployer implements ServerComponent {
 
   private DefaultServerFileSystem fileSystem;
   private Map<String, PluginMetadata> pluginByKeys = Maps.newHashMap();
-  private PluginInstaller extractor;
+  private PluginInstaller installer;
 
   public PluginDeployer(DefaultServerFileSystem fileSystem) {
     this(fileSystem, new PluginInstaller());
   }
 
-  PluginDeployer(DefaultServerFileSystem fileSystem, PluginInstaller extractor) {
+  PluginDeployer(DefaultServerFileSystem fileSystem, PluginInstaller installer) {
     this.fileSystem = fileSystem;
-    this.extractor = extractor;
+    this.installer = installer;
   }
 
   public void start() throws IOException {
@@ -90,7 +90,7 @@ public class PluginDeployer implements ServerComponent {
   }
 
   private void registerPlugin(File file, boolean isCore, boolean canDelete) throws IOException {
-    DefaultPluginMetadata metadata = extractor.extractMetadata(file, isCore);
+    DefaultPluginMetadata metadata = installer.extractMetadata(file, isCore);
     if (StringUtils.isNotBlank(metadata.getKey())) {
       PluginMetadata existing = pluginByKeys.get(metadata.getKey());
       if (existing != null) {
@@ -198,7 +198,7 @@ public class PluginDeployer implements ServerComponent {
         plugin.addDeprecatedExtension(deprecatedExtension);
       }
 
-      extractor.install(plugin, pluginDeployDir);
+      installer.install(plugin, pluginDeployDir);
 
     } catch (IOException e) {
       throw new RuntimeException("Fail to deploy the plugin " + plugin, e);
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/ApplicationDeployer.java b/sonar-server/src/main/java/org/sonar/server/startup/ApplicationDeployer.java
deleted file mode 100644 (file)
index 5d3165a..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.startup;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.api.web.RubyRailsApp;
-
-import javax.annotation.Nullable;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Ruby on Rails requires the files to be on filesystem but not in Java classpath (JAR). This component extracts
- * all the needed files from plugins and copy them to $SONAR_HOME/temp
- *
- * @since 2.15
- */
-public class ApplicationDeployer {
-  private static final Logger LOG = LoggerFactory.getLogger(ApplicationDeployer.class);
-
-  private ServerFileSystem fileSystem;
-  private RubyRailsApp[] apps;
-
-  public ApplicationDeployer(ServerFileSystem fileSystem, RubyRailsApp[] apps) {
-    this.fileSystem = fileSystem;
-    this.apps = apps;
-  }
-
-  public ApplicationDeployer(ServerFileSystem fileSystem) {
-    this(fileSystem, new RubyRailsApp[0]);
-  }
-
-  public void start() throws IOException {
-    deployRubyRailsApps();
-  }
-
-  private void deployRubyRailsApps() {
-    LOG.info("Deploy Ruby on Rails applications");
-    File appsDir = prepareRubyRailsRootDirectory();
-
-    for (final RubyRailsApp app : apps) {
-      try {
-        deployRubyRailsApp(appsDir, app, app.getClass().getClassLoader());
-      } catch (Exception e) {
-        throw new IllegalStateException("Fail to deploy Ruby on Rails application: " + app.getKey(), e);
-      }
-    }
-  }
-
-  @VisibleForTesting
-  File prepareRubyRailsRootDirectory() {
-    File appsDir = new File(fileSystem.getTempDir(), "ror");
-    prepareDir(appsDir);
-    return appsDir;
-  }
-
-  @VisibleForTesting
-  static void deployRubyRailsApp(File appsDir, final RubyRailsApp app, ClassLoader appClassLoader) {
-    LOG.debug("Deploy: " + app.getKey());
-    File appDir = new File(appsDir, app.getKey());
-    if (appDir.exists()) {
-      LOG.error("Ruby on Rails application already exists: " + app.getKey());
-    } else {
-      ClassLoaderUtils.copyResources(appClassLoader, app.getPath(), appDir, new Function<String, String>() {
-        @Override
-        public String apply(@Nullable String relativePath) {
-          // relativePath format is: org/sonar/sqale/app/controllers/foo_controller.rb
-          // app path is: /org/sonar/sqale
-          // -> deployed file is app/controllers/foo_controller.rb
-          return StringUtils.substringAfter(relativePath, StringUtils.removeStart(app.getPath(), "/") + "/");
-        }
-      });
-    }
-  }
-
-  private void prepareDir(File appsDir) {
-    if (appsDir.exists() && appsDir.isDirectory()) {
-      try {
-        FileUtils.deleteDirectory(appsDir);
-      } catch (IOException e) {
-        throw new IllegalStateException("Fail to delete temp directory: " + appsDir);
-      }
-    }
-    try {
-      FileUtils.forceMkdir(appsDir);
-    } catch (IOException e) {
-      throw new IllegalStateException("Fail to create temp directory: " + appsDir);
-    }
-  }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/ClassLoaderUtils.java b/sonar-server/src/main/java/org/sonar/server/startup/ClassLoaderUtils.java
deleted file mode 100644 (file)
index 95e95b2..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.startup;
-
-import com.google.common.base.*;
-import com.google.common.collect.Lists;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.CharEncoding;
-import org.apache.commons.lang.StringUtils;
-
-import javax.annotation.Nullable;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * TODO it this class needed in sonar-plugin-api ?
- *
- * @since 2.15
- */
-public final class ClassLoaderUtils {
-
-  private ClassLoaderUtils() {
-  }
-
-  public static File copyResources(ClassLoader classLoader, String rootPath, File toDir) {
-    return copyResources(classLoader, rootPath, toDir, Functions.<String>identity());
-  }
-
-  public static File copyResources(ClassLoader classLoader, String rootPath, File toDir, Function<String, String> relocationFunction) {
-    Collection<String> relativePaths = listFiles(classLoader, rootPath);
-    for (String relativePath : relativePaths) {
-      URL resource = classLoader.getResource(relativePath);
-      String filename = relocationFunction.apply(relativePath);
-      File toFile = new File(toDir, filename);
-      try {
-        FileUtils.copyURLToFile(resource, toFile);
-      } catch (IOException e) {
-        throw new IllegalStateException("Fail to extract " + relativePath + " to " + toFile.getAbsolutePath());
-      }
-    }
-
-    return toDir;
-  }
-
-  public static Collection<String> listFiles(ClassLoader classLoader, String rootPath) {
-    return listResources(classLoader, rootPath, new Predicate<String>() {
-      @Override
-      public boolean apply(@Nullable String path) {
-        return !StringUtils.endsWith(path, "/");
-      }
-    });
-  }
-
-  public static Collection<String> listResources(ClassLoader classloader, String rootPath) {
-    return listResources(classloader, rootPath, Predicates.<String>alwaysTrue());
-  }
-
-  public static Collection<String> listResources(ClassLoader classloader, String rootPath, Predicate<String> predicate) {
-    try {
-      Collection<String> paths = Lists.newArrayList();
-      rootPath = StringUtils.removeStart(rootPath, "/");
-
-      URL root = classloader.getResource(rootPath);
-      if (root == null) {
-        return paths;
-      }
-      if (!"jar".equals(root.getProtocol())) {
-        throw new IllegalStateException("Unsupported protocol: " + root.getProtocol());
-      }
-      String jarPath = root.getPath().substring(5, root.getPath().indexOf("!")); //strip out only the JAR file
-      JarFile jar = new JarFile(URLDecoder.decode(jarPath, CharEncoding.UTF_8));
-      Enumeration<JarEntry> entries = jar.entries();
-      while (entries.hasMoreElements()) {
-        String name = entries.nextElement().getName();
-        if (name.startsWith(rootPath) && predicate.apply(name)) {
-          paths.add(name);
-        }
-      }
-      return paths;
-    } catch (Exception e) {
-      throw Throwables.propagate(e);
-    }
-  }
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java b/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java
new file mode 100644 (file)
index 0000000..8c67db5
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.platform;
+
+import org.junit.Test;
+import org.sonar.core.persistence.Database;
+import org.sonar.core.persistence.dialect.Dialect;
+import org.sonar.core.persistence.dialect.MySql;
+import org.sonar.test.TestUtils;
+
+import java.io.File;
+import java.util.List;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DefaultServerFileSystemTest {
+
+  private static final String PATH = "/org/sonar/server/platform/DefaultServerFileSystemTest/";
+
+  @Test
+  public void testGetJdbcDriver() {
+    Database database = mock(Database.class);
+    when(database.getDialect()).thenReturn(new MySql());
+    File driver = new DefaultServerFileSystem(database, TestUtils.getResource(PATH + "testGetJdbcDriver"), null).getJdbcDriver();
+    assertNotNull(driver);
+  }
+
+  @Test(expected = ServerStartException.class)
+  public void failIfJdbcDriverNotFound() {
+    Database database = mock(Database.class);
+
+    Dialect fakeDialect = mock(Dialect.class);
+    when(fakeDialect.getId()).thenReturn("none");
+    when(database.getDialect()).thenReturn(fakeDialect);
+
+    new DefaultServerFileSystem(database, TestUtils.getResource(PATH + "testGetJdbcDriver"), null).getJdbcDriver();
+  }
+
+  @Test
+  public void shouldFindPlugins() {
+    List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindPlugins"), null).getUserPlugins();
+    assertEquals(2, plugins.size());
+  }
+
+  @Test
+  public void shouldNotFailIfNoPlugins() {
+    List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoPlugins"), null).getUserPlugins();
+    assertEquals(0, plugins.size());
+  }
+
+  @Test
+  public void shouldFindCheckstyleExtensions() {
+    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindCheckstyleExtensions"), null);
+
+    List<File> xmls = fs.getPluginExtensionXml("checkstyle");
+    assertEquals(1, xmls.size());
+
+    List<File> jars = fs.getExtensions("checkstyle");
+    assertEquals(3, jars.size());
+  }
+
+  @Test
+  public void shouldNotFailIfNoCheckstyleExtensions() {
+    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoCheckstyleExtensions"), null);
+    List<File> xmls = fs.getPluginExtensionXml("checkstyle");
+    assertEquals(0, xmls.size());
+
+    List<File> jars = fs.getExtensions("checkstyle");
+    assertEquals(0, jars.size());
+  }
+
+  @Test(expected = ServerStartException.class)
+  public void shouldFailIfHomeDirectoryNotExists() {
+    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, new File("/notexists"), null);
+    fs.start();
+  }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/platform/ServerFileSystemTest.java b/sonar-server/src/test/java/org/sonar/server/platform/ServerFileSystemTest.java
deleted file mode 100644 (file)
index bd70a44..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.platform;
-
-import org.junit.Test;
-import org.sonar.jpa.session.DatabaseConnector;
-import org.sonar.core.persistence.dialect.Dialect;
-import org.sonar.core.persistence.dialect.MySql;
-import org.sonar.test.TestUtils;
-
-import java.io.File;
-import java.util.List;
-
-import static junit.framework.Assert.assertNotNull;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ServerFileSystemTest {
-
-  private static final String PATH = "/org/sonar/server/platform/ServerFileSystemTest/";
-
-  @Test
-  public void testGetJdbcDriver() {
-    DatabaseConnector databaseConnector = mock(DatabaseConnector.class);
-    when(databaseConnector.getDialect()).thenReturn(new MySql());
-    File driver = new DefaultServerFileSystem(databaseConnector, TestUtils.getResource(PATH + "testGetJdbcDriver"), null).getJdbcDriver();
-    assertNotNull(driver);
-  }
-
-  @Test(expected = ServerStartException.class)
-  public void failIfJdbcDriverNotFound() {
-    DatabaseConnector databaseConnector = mock(DatabaseConnector.class);
-
-    Dialect fakeDialect = mock(Dialect.class);
-    when(fakeDialect.getId()).thenReturn("none");
-    when(databaseConnector.getDialect()).thenReturn(fakeDialect);
-
-    new DefaultServerFileSystem(databaseConnector, TestUtils.getResource(PATH + "testGetJdbcDriver"), null).getJdbcDriver();
-  }
-
-  @Test
-  public void shouldFindPlugins() {
-    List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindPlugins"), null).getUserPlugins();
-    assertEquals(2, plugins.size());
-  }
-
-  @Test
-  public void shouldNotFailIfNoPlugins() {
-    List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoPlugins"), null).getUserPlugins();
-    assertEquals(0, plugins.size());
-  }
-
-  @Test
-  public void shouldFindCheckstyleExtensions() {
-    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindCheckstyleExtensions"), null);
-
-    List<File> xmls = fs.getPluginExtensionXml("checkstyle");
-    assertEquals(1, xmls.size());
-
-    List<File> jars = fs.getExtensions("checkstyle");
-    assertEquals(3, jars.size());
-  }
-
-  @Test
-  public void shouldNotFailIfNoCheckstyleExtensions() {
-    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoCheckstyleExtensions"), null);
-    List<File> xmls = fs.getPluginExtensionXml("checkstyle");
-    assertEquals(0, xmls.size());
-
-    List<File> jars = fs.getExtensions("checkstyle");
-    assertEquals(0, jars.size());
-  }
-
-  @Test(expected = ServerStartException.class)
-  public void shouldFailIfHomeDirectoryNotExists() {
-    DefaultServerFileSystem fs = new DefaultServerFileSystem(null, new File("/notexists"), null);
-    fs.start();
-  }
-
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/ApplicationDeployerTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/ApplicationDeployerTest.java
new file mode 100644 (file)
index 0000000..9226491
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.platform.PluginRepository;
+import org.sonar.api.platform.ServerFileSystem;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ApplicationDeployerTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Test
+  public void hasRubyRailsApp() throws Exception {
+    ClassLoader classLoader = new URLClassLoader(new URL[]{
+      getClass().getResource("/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar").toURI().toURL()}, null);
+
+    assertTrue(ApplicationDeployer.hasRubyRailsApp("fake", classLoader));
+    assertFalse(ApplicationDeployer.hasRubyRailsApp("other", classLoader));
+  }
+
+  @Test
+  public void deployRubyRailsApp() throws Exception {
+    File tempDir = this.temp.getRoot();
+    ClassLoader classLoader = new URLClassLoader(new URL[]{
+      getClass().getResource("/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar").toURI().toURL()}, null);
+
+    ApplicationDeployer.deployRubyRailsApp(tempDir, "fake", classLoader);
+
+    File appDir = new File(tempDir, "fake");
+    assertThat(appDir.isDirectory(), is(true));
+    assertThat(appDir.exists(), is(true));
+    assertThat(FileUtils.listFiles(appDir, null, true).size(), is(2));
+    assertThat(new File(appDir, "app/controllers/fake_controller.rb").exists(), is(true));
+    assertThat(new File(appDir, "app/views/fake/index.html.erb").exists(), is(true));
+  }
+
+  @Test
+  public void prepareRubyRailsRootDirectory() throws Exception {
+    ServerFileSystem fileSystem = mock(ServerFileSystem.class);
+    File tempDir = this.temp.getRoot();
+    when(fileSystem.getTempDir()).thenReturn(tempDir);
+
+    File dir = new ApplicationDeployer(fileSystem, mock(PluginRepository.class)).prepareRubyRailsRootDirectory();
+
+    assertThat(dir.isDirectory(), is(true));
+    assertThat(dir.exists(), is(true));
+    assertThat(dir.getCanonicalPath(), is(new File(tempDir, "ror").getCanonicalPath()));
+  }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/ClassLoaderUtilsTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/ClassLoaderUtilsTest.java
new file mode 100644 (file)
index 0000000..2635898
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.hamcrest.core.Is;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collection;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.hasItems;
+
+public class ClassLoaderUtilsTest {
+
+  private ClassLoader classLoader;
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Before
+  public void prepareClassLoader() {
+    //  This JAR file has the three following files :
+    //    org/sonar/sqale/app/copyright.txt
+    //    org/sonar/sqale/app/README.md
+    //    org/sonar/other/other.txt
+    URL jarUrl = getClass().getResource("/org/sonar/server/plugins/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar");
+    classLoader = new URLClassLoader(new URL[]{jarUrl}, /* no parent classloader */null);
+  }
+
+  @Test
+  public void listResources_unknown_root() {
+    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "unknown/directory");
+    assertThat(strings.size(), Is.is(0));
+  }
+
+  @Test
+  public void listResources_all() {
+    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "org/sonar/sqale");
+    assertThat(strings, hasItems(
+      "org/sonar/sqale/",
+      "org/sonar/sqale/app/",
+      "org/sonar/sqale/app/copyright.txt",
+      "org/sonar/sqale/app/README.md"));
+    assertThat(strings.size(), Is.is(4));
+  }
+
+  @Test
+  public void listResources_root_path_starts_with_slash() {
+    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "/org/sonar/sqale");
+    assertThat(strings, hasItems(
+      "org/sonar/sqale/",
+      "org/sonar/sqale/app/",
+      "org/sonar/sqale/app/copyright.txt",
+      "org/sonar/sqale/app/README.md"));
+    assertThat(strings.size(), Is.is(4));
+  }
+
+  @Test
+  public void listResources_use_predicate() {
+    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "org/sonar/sqale", new Predicate<String>() {
+      @Override
+      public boolean apply(@Nullable String s) {
+        return StringUtils.endsWith(s, "md");
+      }
+    });
+    assertThat(strings.size(), Is.is(1));
+    assertThat(strings, hasItems("org/sonar/sqale/app/README.md"));
+  }
+
+  @Test
+  public void listFiles() {
+    Collection<String> strings = ClassLoaderUtils.listFiles(classLoader, "org/sonar/sqale");
+    assertThat(strings, hasItems(
+      "org/sonar/sqale/app/copyright.txt",
+      "org/sonar/sqale/app/README.md"));
+    assertThat(strings.size(), Is.is(2));
+  }
+
+  @Test
+  public void copyRubyRailsApp() {
+    File toDir = temp.newFolder("dest");
+    ClassLoaderUtils.copyResources(classLoader, "org/sonar/sqale", toDir);
+
+    assertThat(FileUtils.listFiles(toDir, null, true).size(), Is.is(2));
+    assertThat(new File(toDir, "org/sonar/sqale/app/copyright.txt").exists(), Is.is(true));
+    assertThat(new File(toDir, "org/sonar/sqale/app/README.md").exists(), Is.is(true));
+  }
+
+  @Test
+  public void copyRubyRailsApp_relocate_files() {
+    File toDir = temp.newFolder("dest");
+    ClassLoaderUtils.copyResources(classLoader, "org/sonar/sqale", toDir, new Function<String, String>() {
+      @Override
+      public String apply(@Nullable String path) {
+        return "foo/" + FilenameUtils.getName(path);
+      }
+    });
+
+    assertThat(FileUtils.listFiles(toDir, null, true).size(), Is.is(2));
+    assertThat(new File(toDir, "foo/copyright.txt").exists(), Is.is(true));
+    assertThat(new File(toDir, "foo/README.md").exists(), Is.is(true));
+  }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/startup/ApplicationDeployerTest.java b/sonar-server/src/test/java/org/sonar/server/startup/ApplicationDeployerTest.java
deleted file mode 100644 (file)
index 7eb728e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.startup;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.platform.ServerFileSystem;
-import org.sonar.api.web.RubyRailsApp;
-
-import java.io.File;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ApplicationDeployerTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Test
-  public void deployRubyRailsApp() throws Exception {
-    File tempDir = this.temp.getRoot();
-    ClassLoader classLoader = new URLClassLoader(new URL[]{
-      getClass().getResource("/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp.jar").toURI().toURL()}, null);
-    ApplicationDeployer.deployRubyRailsApp(tempDir, new FakeRubyRailsApp(), classLoader);
-
-    File appDir = new File(tempDir, "fake");
-    assertThat(appDir.isDirectory(), is(true));
-    assertThat(appDir.exists(), is(true));
-    assertThat(FileUtils.listFiles(appDir, null, true).size(), is(2));
-    assertThat(new File(appDir, "app/controllers/fake_controller.rb").exists(), is(true));
-    assertThat(new File(appDir, "app/views/fake/index.html.erb").exists(), is(true));
-  }
-
-  @Test
-  public void prepareRubyRailsRootDirectory() throws Exception {
-    ServerFileSystem fileSystem = mock(ServerFileSystem.class);
-    File tempDir = this.temp.getRoot();
-    when(fileSystem.getTempDir()).thenReturn(tempDir);
-
-    File dir = new ApplicationDeployer(fileSystem, new RubyRailsApp[]{new FakeRubyRailsApp()}).prepareRubyRailsRootDirectory();
-
-    assertThat(dir.isDirectory(), is(true));
-    assertThat(dir.exists(), is(true));
-    assertThat(dir.getCanonicalPath(), is(new File(tempDir, "ror").getCanonicalPath()));
-  }
-
-  static class FakeRubyRailsApp extends RubyRailsApp {
-
-    @Override
-    public String getKey() {
-      return "fake";
-    }
-
-    @Override
-    public String getPath() {
-      return "/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp";
-    }
-  }
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/startup/ClassLoaderUtilsTest.java b/sonar-server/src/test/java/org/sonar/server/startup/ClassLoaderUtilsTest.java
deleted file mode 100644 (file)
index 1960a1c..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.server.startup;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.hamcrest.core.Is;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import javax.annotation.Nullable;
-import java.io.File;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-
-import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.hasItems;
-
-public class ClassLoaderUtilsTest {
-
-  private ClassLoader classLoader;
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Before
-  public void prepareClassLoader() {
-    //  This JAR file has the three following files :
-    //    org/sonar/sqale/app/copyright.txt
-    //    org/sonar/sqale/app/README.md
-    //    org/sonar/other/other.txt
-    URL jarUrl = getClass().getResource("/org/sonar/server/startup/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar");
-    classLoader = new URLClassLoader(new URL[]{jarUrl}, /* no parent classloader */null);
-  }
-
-  @Test
-  public void listResources_unknown_root() {
-    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "unknown/directory");
-    assertThat(strings.size(), Is.is(0));
-  }
-
-  @Test
-  public void listResources_all() {
-    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "org/sonar/sqale");
-    assertThat(strings, hasItems(
-      "org/sonar/sqale/",
-      "org/sonar/sqale/app/",
-      "org/sonar/sqale/app/copyright.txt",
-      "org/sonar/sqale/app/README.md"));
-    assertThat(strings.size(), Is.is(4));
-  }
-
-  @Test
-  public void listResources_root_path_starts_with_slash() {
-    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "/org/sonar/sqale");
-    assertThat(strings, hasItems(
-      "org/sonar/sqale/",
-      "org/sonar/sqale/app/",
-      "org/sonar/sqale/app/copyright.txt",
-      "org/sonar/sqale/app/README.md"));
-    assertThat(strings.size(), Is.is(4));
-  }
-
-  @Test
-  public void listResources_use_predicate() {
-    Collection<String> strings = ClassLoaderUtils.listResources(classLoader, "org/sonar/sqale", new Predicate<String>() {
-      @Override
-      public boolean apply(@Nullable String s) {
-        return StringUtils.endsWith(s, "md");
-      }
-    });
-    assertThat(strings.size(), Is.is(1));
-    assertThat(strings, hasItems("org/sonar/sqale/app/README.md"));
-  }
-
-  @Test
-  public void listFiles() {
-    Collection<String> strings = ClassLoaderUtils.listFiles(classLoader, "org/sonar/sqale");
-    assertThat(strings, hasItems(
-      "org/sonar/sqale/app/copyright.txt",
-      "org/sonar/sqale/app/README.md"));
-    assertThat(strings.size(), Is.is(2));
-  }
-
-  @Test
-  public void copyRubyRailsApp() {
-    File toDir = temp.newFolder("dest");
-    ClassLoaderUtils.copyResources(classLoader, "org/sonar/sqale", toDir);
-
-    assertThat(FileUtils.listFiles(toDir, null, true).size(), Is.is(2));
-    assertThat(new File(toDir, "org/sonar/sqale/app/copyright.txt").exists(), Is.is(true));
-    assertThat(new File(toDir, "org/sonar/sqale/app/README.md").exists(), Is.is(true));
-  }
-
-  @Test
-  public void copyRubyRailsApp_relocate_files() {
-    File toDir = temp.newFolder("dest");
-    ClassLoaderUtils.copyResources(classLoader, "org/sonar/sqale", toDir, new Function<String, String>() {
-      @Override
-      public String apply(@Nullable String path) {
-        return "foo/" + FilenameUtils.getName(path);
-      }
-    });
-
-    assertThat(FileUtils.listFiles(toDir, null, true).size(), Is.is(2));
-    assertThat(new File(toDir, "foo/copyright.txt").exists(), Is.is(true));
-    assertThat(new File(toDir, "foo/README.md").exists(), Is.is(true));
-  }
-}
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar
new file mode 100644 (file)
index 0000000..904931c
--- /dev/null
@@ -0,0 +1 @@
+asdad
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt b/sonar-server/src/test/resources/org/sonar/server/platform/DefaultServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.jar
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules.xml
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindCheckstyleExtensions/extensions/rules/checkstyle/my-rules2.jar
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin1.jar
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldFindPlugins/extensions/plugins/plugin2.jar
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoCheckstyleExtensions/extensions/pmd/pmd.xml
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/shouldNotFailIfNoPlugins/extensions/plugins/nojar.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/mysql/fake.jar
deleted file mode 100644 (file)
index 904931c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-asdad
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt b/sonar-server/src/test/resources/org/sonar/server/platform/ServerFileSystemTest/testGetJdbcDriver/extensions/jdbc-driver/none/nojar.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar
new file mode 100644 (file)
index 0000000..583b3e9
Binary files /dev/null and b/sonar-server/src/test/resources/org/sonar/server/plugins/ApplicationDeployerTest/FakeRubyRailsApp.jar differ
diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar
new file mode 100644 (file)
index 0000000..21024e3
Binary files /dev/null and b/sonar-server/src/test/resources/org/sonar/server/plugins/ClassLoaderUtilsTest/ClassLoaderUtilsTest.jar differ
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp.jar b/sonar-server/src/test/resources/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp.jar
deleted file mode 100644 (file)
index e4f4dfb..0000000
Binary files a/sonar-server/src/test/resources/org/sonar/server/startup/ApplicationDeployerTest/FakeRubyRailsApp.jar and /dev/null differ