001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 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.api; 021 022 import org.sonar.api.utils.SonarException; 023 024 import java.io.IOException; 025 import java.io.InputStream; 026 import java.net.URL; 027 import java.util.*; 028 import java.util.jar.Manifest; 029 030 /** 031 * Plugins dictionnary. 032 * 033 * @since 1.10 034 */ 035 public class Plugins { 036 037 private Map<String, Plugin> plugins = null; 038 private List<Class<? extends Extension>> extensionClasses = null; 039 private Map<Class<? extends Extension>, Plugin> pluginsByExtensionClass = null; 040 private Map<Class<? extends Extension>, List<Class<? extends Extension>>> extensionClassesByType = null; 041 042 public Plugins() { 043 try { 044 introspectPlugins(); 045 introspectExtensions(); 046 047 } catch (Exception e) { 048 throw new SonarException("can not load plugins", e); 049 } 050 } 051 052 public void introspectPlugins() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { 053 Enumeration<URL> pluginsEnum = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); 054 plugins = new HashMap<String, Plugin>(); 055 while (pluginsEnum.hasMoreElements()) { 056 URL pluginUrl = pluginsEnum.nextElement(); 057 InputStream in = pluginUrl.openStream(); 058 Manifest manifest = new Manifest(in); 059 in.close(); 060 String pluginClassProp = manifest.getMainAttributes().getValue("Plugin-Class"); 061 if (pluginClassProp != null) { 062 Class<?> pluginClass = Class.forName(pluginClassProp, true, getClass().getClassLoader()); 063 Plugin pluginInstance = (Plugin) pluginClass.newInstance(); 064 plugins.put(pluginInstance.getKey(), pluginInstance); 065 066 } 067 } 068 } 069 070 private void introspectExtensions() { 071 extensionClasses = new ArrayList<Class<? extends Extension>>(); 072 pluginsByExtensionClass = new HashMap<Class<? extends Extension>, Plugin>(); 073 extensionClassesByType = new HashMap<Class<? extends Extension>, List<Class<? extends Extension>>>(); 074 075 for (Plugin plugin : getPlugins()) { 076 for (Class<? extends Extension> extensionClass : plugin.getExtensions()) { 077 extensionClasses.add(extensionClass); 078 pluginsByExtensionClass.put(extensionClass, plugin); 079 } 080 } 081 } 082 083 public Collection<Plugin> getPlugins() { 084 return plugins.values(); 085 } 086 087 public Plugin getPlugin(String key) { 088 return plugins.get(key); 089 } 090 091 092 public Plugin getPluginByExtension(Class<? extends Extension> clazz) { 093 return pluginsByExtensionClass.get(clazz); 094 } 095 096 public String getPluginKeyByExtension(Class<? extends Extension> clazz) { 097 Plugin plugin = getPluginByExtension(clazz); 098 if (plugin != null) { 099 return plugin.getKey(); 100 } 101 return null; 102 } 103 104 public Plugin getPluginByExtension(Extension extension) { 105 return getPluginByExtension(extension.getClass()); 106 } 107 108 public List<Class<? extends Extension>> getExtensions() { 109 return extensionClasses; 110 } 111 112 public List<Class<? extends Extension>> getExtensions(Class<? extends Extension> type) { 113 List<Class<? extends Extension>> list = extensionClassesByType.get(type); 114 if (list == null) { 115 list = new ArrayList<Class<? extends Extension>>(); 116 for (Class<? extends Extension> extension : getExtensions()) { 117 if (type.isAssignableFrom(extension)) { 118 list.add(extension); 119 } 120 } 121 extensionClassesByType.put(type, list); 122 } 123 124 return list; 125 } 126 127 public Property[] getProperties(Plugin plugin) { 128 Class<? extends Plugin> classInstance = plugin.getClass(); 129 if (classInstance.isAnnotationPresent(Properties.class)) { 130 return classInstance.getAnnotation(Properties.class).value(); 131 } 132 return new Property[0]; 133 } 134 }