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 PluginManager(PluginContext context, PluginDiscovery discovery) { 047 this.context = context; 048 this.plugins = null; 049 this.discovery = discovery; 050 } 051 052 public synchronized Iterable<CRaSHPlugin<?>> getPlugins() { 053 if (plugins == null) { 054 List<CRaSHPlugin<?>> plugins = Utils.list(discovery.getPlugins()); 055 for (CRaSHPlugin<?> plugin : plugins) { 056 plugin.context = context; 057 plugin.status = CRaSHPlugin.CONSTRUCTED; 058 } 059 this.plugins = plugins; 060 } 061 return plugins; 062 } 063 064 public synchronized <T> Iterable<T> getPlugins(Class<T> wantedType) { 065 066 // 067 Iterable<CRaSHPlugin<?>> plugins = getPlugins(); 068 069 // 070 List<T> tmp = Collections.emptyList(); 071 072 // 073 for (CRaSHPlugin<?> plugin : plugins) { 074 Class<?> pluginType = plugin.getType(); 075 if (wantedType.isAssignableFrom(pluginType)) { 076 077 switch (plugin.status) { 078 default: 079 case CRaSHPlugin.FAILED: 080 case CRaSHPlugin.INITIALIZED: 081 // Do nothing 082 break; 083 case CRaSHPlugin.CONSTRUCTED: 084 int status = CRaSHPlugin.FAILED; 085 try { 086 plugin.status = CRaSHPlugin.INITIALIZING; 087 plugin.init(); 088 log.info("Initialized plugin " + plugin); 089 status = CRaSHPlugin.INITIALIZED; 090 } 091 catch (Exception e) { 092 log.error("Could not initialize plugin " + plugin, e); 093 } finally { 094 plugin.status = status; 095 } 096 break; 097 case CRaSHPlugin.INITIALIZING: 098 throw new RuntimeException("Circular dependency"); 099 } 100 101 // 102 if (plugin.status == CRaSHPlugin.INITIALIZED) { 103 if (tmp.isEmpty()) { 104 tmp = new ArrayList<T>(); 105 } 106 T t = wantedType.cast(plugin); 107 tmp.add(t); 108 } 109 } 110 } 111 112 // 113 return tmp; 114 } 115 116 void shutdown() { 117 if (plugins != null) { 118 for (CRaSHPlugin<?> plugin : plugins) { 119 plugin.destroy(); 120 } 121 } 122 } 123 }