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.platform;
021
022 import org.picocontainer.Characteristics;
023 import org.picocontainer.MutablePicoContainer;
024 import org.slf4j.Logger;
025 import org.slf4j.LoggerFactory;
026 import org.sonar.api.*;
027
028 import java.util.Collection;
029 import java.util.HashMap;
030 import java.util.IdentityHashMap;
031 import java.util.Map;
032
033 /**
034 * @since 2.2
035 */
036 public abstract class PluginRepository implements BatchComponent, ServerComponent {
037
038 private static final Logger LOG = LoggerFactory.getLogger(PluginRepository.class);
039
040 private Map<String, Plugin> pluginByKey = new HashMap<String, Plugin>();
041 private Map<Object, Plugin> pluginByExtension = new IdentityHashMap<Object, Plugin>();
042
043 public void registerPlugin(MutablePicoContainer container, Plugin plugin, Class<? extends Extension> extensionClass) {
044 LOG.debug("Registering the plugin {}", plugin.getKey());
045 pluginByKey.put(plugin.getKey(), plugin);
046 for (Object extension : plugin.getExtensions()) {
047 if (isExtension(extension, extensionClass)) {
048 LOG.debug("Registering the extension: {}", extension);
049 container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension);
050 pluginByExtension.put(extension, plugin);
051 }
052 }
053 }
054
055 public Collection<Plugin> getPlugins() {
056 return pluginByKey.values();
057 }
058
059 public Plugin getPlugin(String key) {
060 return pluginByKey.get(key);
061 }
062
063 /**
064 * Returns the list of properties of a plugin
065 */
066 public Property[] getProperties(Plugin plugin) {
067 if (plugin != null) {
068 Class<? extends Plugin> classInstance = plugin.getClass();
069 if (classInstance.isAnnotationPresent(Properties.class)) {
070 return classInstance.getAnnotation(Properties.class).value();
071 }
072 }
073 return new Property[0];
074 }
075
076 public Property[] getProperties(String pluginKey) {
077 return getProperties(pluginByKey.get(pluginKey));
078 }
079
080 public Plugin getPluginForExtension(Object extension) {
081 Plugin plugin = pluginByExtension.get(extension);
082 if (plugin == null && !(extension instanceof Class)) {
083 plugin = pluginByExtension.get(extension.getClass());
084 }
085 return plugin;
086 }
087
088 public String getPluginKeyForExtension(Object extension) {
089 Plugin plugin = getPluginForExtension(extension);
090 if (plugin != null) {
091 return plugin.getKey();
092 }
093 return null;
094 }
095
096 private boolean isExtension(Object extension, Class<? extends Extension> extensionClass) {
097 Class clazz = (extension instanceof Class ? (Class) extension : extension.getClass());
098 return extensionClass.isAssignableFrom(clazz);
099 }
100
101 public void registerExtension(MutablePicoContainer container, Plugin plugin, Object extension) {
102 container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension);
103 pluginByExtension.put(extension, plugin);
104 }
105
106 protected Object getExtensionKey(Object component) {
107 if (component instanceof Class) {
108 return component;
109 }
110 return component.getClass().getCanonicalName() + "-" + component.toString();
111 }
112
113 }