001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.plugin;
021
022 import org.crsh.util.Utils;
023
024 import java.util.*;
025 import java.util.logging.Level;
026 import java.util.logging.Logger;
027
028 class PluginManager {
029
030 /** . */
031 private final Logger log = Logger.getLogger(PluginManager.class.getName());
032
033 /** . */
034 private final PluginContext context;
035
036 /** . */
037 private List<CRaSHPlugin<?>> plugins;
038
039 /** . */
040 private PluginDiscovery discovery;
041
042 PluginManager(PluginContext context, PluginDiscovery discovery) {
043 this.context = context;
044 this.plugins = null;
045 this.discovery = discovery;
046 }
047
048 synchronized Iterable<CRaSHPlugin<?>> getPlugins() {
049 if (plugins == null) {
050 List<CRaSHPlugin<?>> plugins = Utils.list(discovery.getPlugins());
051 for (CRaSHPlugin<?> plugin : plugins) {
052 plugin.context = context;
053 plugin.status = CRaSHPlugin.CONSTRUCTED;
054 }
055 this.plugins = plugins;
056 }
057 return plugins;
058 }
059
060 synchronized <T> Iterable<T> getPlugins(Class<T> wantedType) {
061
062 //
063 Iterable<CRaSHPlugin<?>> plugins = getPlugins();
064
065 //
066 List<T> tmp = Collections.emptyList();
067
068 //
069 for (CRaSHPlugin<?> plugin : plugins) {
070 Class<?> pluginType = plugin.getType();
071 if (wantedType.isAssignableFrom(pluginType)) {
072
073 switch (plugin.status) {
074 default:
075 case CRaSHPlugin.FAILED:
076 case CRaSHPlugin.INITIALIZED:
077 // Do nothing
078 break;
079 case CRaSHPlugin.CONSTRUCTED:
080 int status = CRaSHPlugin.FAILED;
081 try {
082 plugin.status = CRaSHPlugin.INITIALIZING;
083 plugin.init();
084 log.log(Level.INFO, "Initialized plugin " + plugin);
085 status = CRaSHPlugin.INITIALIZED;
086 }
087 catch (Exception e) {
088 log.log(Level.SEVERE, "Could not initialize plugin " + plugin, e);
089 } finally {
090 plugin.status = status;
091 }
092 break;
093 case CRaSHPlugin.INITIALIZING:
094 throw new RuntimeException("Circular dependency");
095 }
096
097 //
098 if (plugin.status == CRaSHPlugin.INITIALIZED) {
099 if (tmp.isEmpty()) {
100 tmp = new ArrayList<T>();
101 }
102 T t = wantedType.cast(plugin);
103 tmp.add(t);
104 }
105 }
106 }
107
108 //
109 return tmp;
110 }
111
112 void shutdown() {
113 if (plugins != null) {
114 for (CRaSHPlugin<?> plugin : plugins) {
115 plugin.destroy();
116 }
117 }
118 }
119 }