001 /*
002 * Copyright (C) 2010 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 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 import java.util.*;
027
028 /**
029 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
030 * @version $Revision$
031 */
032 public class PluginManager {
033
034 /** . */
035 private final Logger log = LoggerFactory.getLogger(PluginManager.class);
036
037 /** . */
038 private final PluginContext context;
039
040 /** . */
041 private List<CRaSHPlugin<?>> plugins;
042
043 /** . */
044 private PluginDiscovery discovery;
045
046 public PluginManager(PluginContext context, PluginDiscovery discovery) {
047 this.context = context;
048 this.plugins = null;
049 this.discovery = discovery;
050 }
051
052 public synchronized <T> Iterable<T> getPlugins(Class<T> wantedType) {
053
054 //
055 if (plugins == null) {
056 List<CRaSHPlugin<?>> plugins = Utils.list(discovery.getPlugins());
057 for (CRaSHPlugin<?> plugin : plugins) {
058 plugin.context = context;
059 plugin.status = CRaSHPlugin.CONSTRUCTED;
060 }
061 this.plugins = plugins;
062 }
063
064 //
065 List<T> tmp = Collections.emptyList();
066
067 //
068 for (CRaSHPlugin<?> plugin : plugins) {
069 Class<?> pluginType = plugin.getType();
070 if (wantedType.isAssignableFrom(pluginType)) {
071
072 switch (plugin.status) {
073 default:
074 case CRaSHPlugin.FAILED:
075 case CRaSHPlugin.INITIALIZED:
076 // Do nothing
077 break;
078 case CRaSHPlugin.CONSTRUCTED:
079 int status = CRaSHPlugin.FAILED;
080 try {
081 plugin.status = CRaSHPlugin.INITIALIZING;
082 plugin.init();
083 log.info("Initialized plugin " + plugin);
084 status = CRaSHPlugin.INITIALIZED;
085 }
086 catch (Exception e) {
087 log.error("Could not initialize plugin " + plugin, e);
088 } finally {
089 plugin.status = status;
090 }
091 break;
092 case CRaSHPlugin.INITIALIZING:
093 throw new RuntimeException("Circular dependency");
094 }
095
096 //
097 if (plugin.status == CRaSHPlugin.INITIALIZED) {
098 if (tmp.isEmpty()) {
099 tmp = new ArrayList<T>();
100 }
101 T t = wantedType.cast(plugin);
102 tmp.add(t);
103 }
104 }
105 }
106
107 //
108 return tmp;
109 }
110
111 public void shutdown() {
112 if (plugins != null) {
113 for (CRaSHPlugin<?> plugin : plugins) {
114 plugin.destroy();
115 }
116 }
117 }
118 }