From 65724fddb93afec431e93f4a8bcc3dc3fb0c7fb5 Mon Sep 17 00:00:00 2001 From: simonbrandhof Date: Mon, 4 Oct 2010 08:53:59 +0000 Subject: [PATCH] add the method JRubyFacade.getComponentByClassname(pluginKey, classname) to get components from ruby code --- .../server/plugins/PluginClassLoaders.java | 36 +++++++++++++++---- .../java/org/sonar/server/ui/JRubyFacade.java | 20 +++++++---- .../webapp/WEB-INF/lib/need_authentication.rb | 2 +- .../plugins/PluginClassLoadersTest.java | 13 +++++++ 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/PluginClassLoaders.java b/sonar-server/src/main/java/org/sonar/server/plugins/PluginClassLoaders.java index b998cbf83a3..09d96372314 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/PluginClassLoaders.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/PluginClassLoaders.java @@ -19,43 +19,51 @@ */ package org.sonar.server.plugins; +import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; import org.codehaus.classworlds.ClassRealm; import org.codehaus.classworlds.ClassWorld; import org.codehaus.classworlds.DuplicateRealmException; +import org.slf4j.LoggerFactory; import org.sonar.api.ServerComponent; import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.util.Collection; import java.util.HashMap; import java.util.Map; public class PluginClassLoaders implements ServerComponent { - private Map classLoaderByPluginKey = new HashMap(); + private Map classLoaderByPluginKey = Maps.newHashMap(); private ClassWorld world = new ClassWorld(); public ClassLoader create(PluginMetadata plugin) { + return create(plugin.getKey(), plugin.getDeployedFiles()); + } + + ClassLoader create(String pluginKey, Collection classloaderFiles) { try { ClassRealm realm; - realm = world.newRealm(plugin.getKey(), getClass().getClassLoader()); - for (File file : plugin.getDeployedFiles()) { + realm = world.newRealm(pluginKey, getClass().getClassLoader()); + for (File file : classloaderFiles) { realm.addConstituent(toUrl(file)); } ClassLoader classloader = realm.getClassLoader(); - classLoaderByPluginKey.put(plugin.getKey(), classloader); + classLoaderByPluginKey.put(pluginKey, classloader); return classloader; } catch (DuplicateRealmException e) { - throw new RuntimeException("Fail to load the classloader of the plugin: " + plugin, e); + throw new RuntimeException("Fail to load the classloader of the plugin: " + pluginKey, e); } catch (MalformedURLException e) { - throw new RuntimeException("Fail to load the classloader of the plugin: " + plugin, e); + throw new RuntimeException("Fail to load the classloader of the plugin: " + pluginKey, e); } } - private URL toUrl(File file) throws MalformedURLException { + + URL toUrl(File file) throws MalformedURLException { // From Classworlds javadoc : // A constituent is a URL that points to either a JAR format file containing // classes and/or resources, or a directory that should be used for searching. @@ -75,4 +83,18 @@ public class PluginClassLoaders implements ServerComponent { public ClassLoader getClassLoader(String pluginKey) { return classLoaderByPluginKey.get(pluginKey); } + + public Class getClass(String pluginKey, String classname) { + Class clazz = null; + ClassLoader classloader = classLoaderByPluginKey.get(pluginKey); + if (classloader != null) { + try { + clazz = classloader.loadClass(classname); + + } catch (ClassNotFoundException e) { + LoggerFactory.getLogger(getClass()).warn("Class not found in plugin " + pluginKey + ": " + classname, e); + } + } + return clazz; + } } diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 73180166d1a..6fde91d0f0a 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -43,6 +43,7 @@ import org.sonar.server.filters.Filter; import org.sonar.server.filters.FilterExecutor; import org.sonar.server.filters.FilterResult; import org.sonar.server.platform.Platform; +import org.sonar.server.plugins.PluginClassLoaders; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.UpdateFinder; import org.sonar.server.plugins.UpdateFinderFactory; @@ -56,7 +57,7 @@ import java.util.List; public final class JRubyFacade implements ServerComponent { public FilterResult executeFilter(Filter filter) { - return getContainer().getComponent(FilterExecutor.class).execute(filter); + return getContainer().getComponent(FilterExecutor.class).execute(filter); } /* PLUGINS */ @@ -79,7 +80,7 @@ public final class JRubyFacade implements ServerComponent { public String colorizeCode(String code, String language) { try { return getContainer().getComponent(CodeColorizers.class).toHtml(code, language); - + } catch (Exception e) { LoggerFactory.getLogger(getClass()).error("Can not highlight the code, language= " + language, e); return code; @@ -87,7 +88,6 @@ public final class JRubyFacade implements ServerComponent { } - public List> getWidgets(String resourceScope, String resourceQualifier, String resourceLanguage) { return getContainer().getComponent(Views.class).getWidgets(resourceScope, resourceQualifier, resourceLanguage); } @@ -125,8 +125,6 @@ public final class JRubyFacade implements ServerComponent { } - - /* PROFILES CONSOLE : RULES AND METRIC THRESHOLDS */ public List getRuleRepositories() { @@ -217,7 +215,7 @@ public final class JRubyFacade implements ServerComponent { return getContainer().getComponent(Configuration.class).getString(key, null); } - public Object getComponentByClass(String className) { + public Object getCoreComponentByClassname(String className) { if (className == null) { return null; } @@ -232,6 +230,16 @@ public final class JRubyFacade implements ServerComponent { } } + public Object getComponentByClassname(String pluginKey, String className) { + Object component = null; + PicoContainer container = getContainer(); + Class componentClass = container.getComponent(PluginClassLoaders.class).getClass(pluginKey, className); + if (componentClass!=null) { + component = container.getComponent(componentClass); + } + return component; + } + public PicoContainer getContainer() { return Platform.getInstance().getContainer(); } diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb index 17a26929067..1811eff2572 100644 --- a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb +++ b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb @@ -60,7 +60,7 @@ class AuthenticatorFactory def self.authenticator if @@authenticator.nil? - authenticator_factory=Java::OrgSonarServerUi::JRubyFacade.new.getComponentByClass('org.sonar.server.ui.AuthenticatorFactory') + authenticator_factory=Java::OrgSonarServerUi::JRubyFacade.new.getCoreComponentByClassname('org.sonar.server.ui.AuthenticatorFactory') component=authenticator_factory.getAuthenticator() @@authenticator=(component ? PluginAuthenticator.new(component) : DefaultAuthenticator.new) end diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/PluginClassLoadersTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/PluginClassLoadersTest.java index 868e8c64e38..ed4021ad6d9 100644 --- a/sonar-server/src/test/java/org/sonar/server/plugins/PluginClassLoadersTest.java +++ b/sonar-server/src/test/java/org/sonar/server/plugins/PluginClassLoadersTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.plugins; +import com.google.common.collect.Lists; import org.junit.Test; import org.sonar.test.TestUtils; @@ -47,6 +48,18 @@ public class PluginClassLoadersTest { assertNotNull(classloader.getResource("foo.txt")); } + @Test + public void shouldGetClassByName() throws IOException { + File jar = getFile("sonar-build-breaker-plugin-0.1.jar"); + + PluginClassLoaders classloaders = new PluginClassLoaders(); + classloaders.create("build-breaker", Lists.newArrayList(jar)); + + assertNotNull(classloaders.getClass("build-breaker", "org.sonar.plugins.buildbreaker.BuildBreakerPlugin")); + assertNull(classloaders.getClass("build-breaker", "org.sonar.plugins.buildbreaker.Unknown")); + assertNull(classloaders.getClass("unknown", "org.sonar.plugins.buildbreaker.BuildBreakerPlugin")); + } + private File getFile(String filename) { return TestUtils.getResource(PluginClassLoadersTest.class, filename); } -- 2.39.5