1 package com.atlassian.plugin;
2
3 import com.atlassian.plugin.classloader.PluginsClassLoader;
4 import com.atlassian.plugin.descriptors.UnloadableModuleDescriptor;
5 import com.atlassian.plugin.descriptors.UnloadableModuleDescriptorFactory;
6 import com.atlassian.plugin.impl.UnloadablePlugin;
7 import com.atlassian.plugin.impl.UnloadablePluginFactory;
8 import com.atlassian.plugin.loaders.DynamicPluginLoader;
9 import com.atlassian.plugin.loaders.PluginLoader;
10 import com.atlassian.plugin.parsers.DescriptorParserFactory;
11 import com.atlassian.plugin.predicate.*;
12 import com.atlassian.plugin.event.PluginEventManager;
13 import com.atlassian.plugin.event.events.PluginFrameworkStartedEvent;
14 import com.atlassian.plugin.event.impl.PluginEventManagerImpl;
15 import org.apache.commons.collections.Closure;
16 import org.apache.commons.collections.CollectionUtils;
17 import org.apache.commons.collections.Predicate;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import java.io.InputStream;
22 import java.util.*;
23
24
25
26
27
28
29
30
31
32
33
34
35 public class DefaultPluginManager implements PluginManager
36 {
37 private static final Log log = LogFactory.getLog(DefaultPluginManager.class);
38 private final List pluginLoaders;
39 private final PluginStateStore store;
40 private final ModuleDescriptorFactory moduleDescriptorFactory;
41 private final PluginsClassLoader classLoader;
42 private final Map
43 private final PluginEventManager pluginEventManager;
44
45
46
47
48 private PluginInstaller pluginInstaller;
49
50
51
52
53 private final Map
54
55 public DefaultPluginManager(PluginStateStore store, List pluginLoaders, ModuleDescriptorFactory moduleDescriptorFactory)
56 {
57 this(store, pluginLoaders, moduleDescriptorFactory, new PluginEventManagerImpl());
58 }
59
60 public DefaultPluginManager(PluginStateStore store, List pluginLoaders, ModuleDescriptorFactory moduleDescriptorFactory, PluginEventManager pluginEventManager)
61 {
62 if (store == null)
63 {
64 throw new IllegalArgumentException("PluginStateStore must not be null.");
65 }
66 if (pluginLoaders == null)
67 {
68 throw new IllegalArgumentException("Plugin Loaders list must not be null.");
69 }
70 if (moduleDescriptorFactory == null)
71 {
72 throw new IllegalArgumentException("ModuleDescriptorFactory must not be null.");
73 }
74 if (pluginEventManager == null)
75 {
76 throw new IllegalArgumentException("PluginEventManager must not be null.");
77 }
78 this.pluginLoaders = pluginLoaders;
79 this.store = store;
80 this.moduleDescriptorFactory = moduleDescriptorFactory;
81 this.pluginEventManager = pluginEventManager;
82 classLoader = new PluginsClassLoader(this);
83 }
84
85
86
87
88
89
90 public void init() throws PluginParseException
91 {
92 for (Iterator iterator = pluginLoaders.iterator(); iterator.hasNext();)
93 {
94 PluginLoader loader = (PluginLoader) iterator.next();
95 if (loader == null) continue;
96
97 for (Iterator pluginIterator = loader.loadAllPlugins(moduleDescriptorFactory).iterator(); pluginIterator.hasNext();)
98 {
99 addPlugin(loader, (Plugin) pluginIterator.next());
100 }
101 }
102 pluginEventManager.broadcast(new PluginFrameworkStartedEvent(this, this));
103 }
104
105
106
107
108
109
110
111 public void setPluginInstaller(PluginInstaller pluginInstaller)
112 {
113 this.pluginInstaller = pluginInstaller;
114 }
115
116 protected final PluginStateStore getStore()
117 {
118 return store;
119 }
120
121 public String installPlugin(PluginJar pluginJar) throws PluginParseException
122 {
123
124 String key = validatePlugin(pluginJar);
125 pluginInstaller.installPlugin(key, pluginJar);
126 scanForNewPlugins();
127
128 return key;
129 }
130
131
132
133
134
135
136
137
138
139
140 String validatePlugin(PluginJar pluginJar) throws PluginParseException
141 {
142 String key;
143
144 boolean foundADynamicPluginLoader = false;
145 for (Iterator iterator = pluginLoaders.iterator(); iterator.hasNext();)
146 {
147 PluginLoader loader = (PluginLoader) iterator.next();
148 if (loader instanceof DynamicPluginLoader)
149 {
150 foundADynamicPluginLoader = true;
151 key = ((DynamicPluginLoader) loader).canLoad(pluginJar);
152 if (key != null)
153 return key;
154 }
155 }
156
157 if (!foundADynamicPluginLoader)
158 {
159 throw new IllegalStateException("Should be at least one DynamicPluginLoader in the plugin loader list");
160 }
161 throw new PluginParseException("Jar " + pluginJar.getFileName() + " is not a valid plugin");
162 }
163
164 public int scanForNewPlugins() throws PluginParseException
165 {
166 int numberFound = 0;
167
168 for (Iterator iterator = pluginLoaders.iterator(); iterator.hasNext();)
169 {
170 PluginLoader loader = (PluginLoader) iterator.next();
171
172 if (loader != null)
173 {
174 if (loader.supportsAddition())
175 {
176 Collection addedPlugins = loader.addFoundPlugins(moduleDescriptorFactory);
177 for (Iterator iterator1 = addedPlugins.iterator(); iterator1.hasNext();)
178 {
179 Plugin newPlugin = (Plugin) iterator1.next();
180 numberFound++;
181 addPlugin(loader, newPlugin);
182 }
183 }
184 }
185 }
186
187 return numberFound;
188 }
189
190 public void uninstall(Plugin plugin) throws PluginException
191 {
192 unloadPlugin(plugin);
193
194
195 removeStateFromStore(getStore(), plugin);
196 }
197
198 protected void removeStateFromStore(PluginStateStore stateStore, Plugin plugin)
199 {
200 PluginManagerState currentState = stateStore.loadPluginState();
201 currentState.removeState(plugin.getKey());
202 stateStore.savePluginState(currentState);
203 }
204
205
206
207
208
209
210
211
212 protected void unloadPlugin(Plugin plugin) throws PluginException
213 {
214 if (!plugin.isUninstallable())
215 throw new PluginException("Plugin is not uninstallable: " + plugin.getKey());
216
217 PluginLoader loader = (PluginLoader) pluginToPluginLoader.get(plugin);
218
219 if (loader != null && !loader.supportsRemoval())
220 {
221 throw new PluginException("Not uninstalling plugin - loader doesn't allow removal. Plugin: " + plugin.getKey());
222 }
223
224 if (isPluginEnabled(plugin.getKey()))
225 notifyPluginDisabled(plugin);
226
227 notifyUninstallPlugin(plugin);
228 if (loader != null)
229 {
230 removePluginFromLoader(plugin);
231 }
232
233 plugins.remove(plugin.getKey());
234 }
235
236 private void removePluginFromLoader(Plugin plugin) throws PluginException
237 {
238 if (plugin.isDeleteable())
239 {
240 PluginLoader pluginLoader = (PluginLoader) pluginToPluginLoader.get(plugin);
241 pluginLoader.removePlugin(plugin);
242 }
243
244 pluginToPluginLoader.remove(plugin);
245 }
246
247 protected void notifyUninstallPlugin(Plugin plugin)
248 {
249 classLoader.notifyUninstallPlugin(plugin);
250
251 for (Iterator it = plugin.getModuleDescriptors().iterator(); it.hasNext();)
252 {
253 ModuleDescriptor descriptor = (ModuleDescriptor) it.next();
254 descriptor.destroy(plugin);
255 }
256 }
257
258 protected PluginManagerState getState()
259 {
260 return getStore().loadPluginState();
261 }
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 protected void addPlugin(PluginLoader loader, Plugin plugin) throws PluginParseException
277 {
278
279 if (plugins.containsKey(plugin.getKey()))
280 {
281 Plugin existingPlugin = (Plugin) plugins.get(plugin.getKey());
282 if (plugin.compareTo(existingPlugin) >= 0)
283 {
284 if (log.isDebugEnabled())
285 {
286 log.debug("Reinstalling plugin '" + plugin.getKey() + "' version " +
287 existingPlugin.getPluginInformation().getVersion() + " with version " +
288 plugin.getPluginInformation().getVersion());
289 }
290 try
291 {
292 log.info("Unloading " + existingPlugin.getName() + " to upgrade.");
293 updatePlugin(existingPlugin, plugin);
294 if (log.isDebugEnabled())
295 log.debug("Plugin '" + plugin.getKey() + "' unloaded.");
296 }
297 catch (PluginException e)
298 {
299 throw new PluginParseException("Duplicate plugin found (installed version is the same or older) and could not be unloaded: '" + plugin.getKey() + "'", e);
300 }
301 }
302 else
303 {
304
305 if (log.isDebugEnabled())
306 log.debug("Duplicate plugin found (installed version is newer): '" + plugin.getKey() + "'");
307
308 return;
309 }
310 }
311
312 plugins.put(plugin.getKey(), plugin);
313
314 enablePluginModules(plugin);
315
316 pluginToPluginLoader.put(plugin, loader);
317 }
318
319
320
321
322
323
324
325
326
327 protected void updatePlugin(final Plugin oldPlugin, final Plugin newPlugin) throws PluginException
328 {
329 if (!oldPlugin.getKey().equals(newPlugin.getKey()))
330 throw new IllegalArgumentException("New plugin must have the same key as the old plugin");
331
332
333
334 Map oldPluginState = getState().getPluginStateMap(oldPlugin);
335
336 uninstall(oldPlugin);
337
338
339 final Set newModuleKeys = new HashSet();
340 newModuleKeys.add(newPlugin.getKey());
341
342 for (Iterator moduleIter = newPlugin.getModuleDescriptors().iterator(); moduleIter.hasNext();)
343 {
344 ModuleDescriptor moduleDescriptor = (ModuleDescriptor) moduleIter.next();
345 newModuleKeys.add(moduleDescriptor.getKey());
346 }
347
348
349 CollectionUtils.filter(oldPluginState.keySet(), new Predicate()
350 {
351 public boolean evaluate(Object o)
352 {
353 return newModuleKeys.contains(o);
354 }
355 });
356
357
358 PluginManagerState currentState = getState();
359 currentState.getMap().putAll(oldPluginState);
360 getStore().savePluginState(currentState);
361 }
362
363 public Collection getPlugins()
364 {
365 return plugins.values();
366 }
367
368
369
370
371
372 public Collection getPlugins(final PluginPredicate pluginPredicate)
373 {
374 return CollectionUtils.select(getPlugins(), new Predicate()
375 {
376 public boolean evaluate(Object o)
377 {
378 return pluginPredicate.matches((Plugin) o);
379 }
380 });
381 }
382
383
384
385
386 public Collection getEnabledPlugins()
387 {
388 return getPlugins(new EnabledPluginPredicate(this));
389 }
390
391
392
393
394
395 public Collection getModules(final ModuleDescriptorPredicate moduleDescriptorPredicate)
396 {
397 return getModules(getModuleDescriptors(moduleDescriptorPredicate));
398 }
399
400
401
402
403
404 public Collection getModuleDescriptors(final ModuleDescriptorPredicate moduleDescriptorPredicate)
405 {
406 final Collection moduleDescriptors = getModuleDescriptors(getPlugins());
407 CollectionUtils.filter(moduleDescriptors, new Predicate()
408 {
409 public boolean evaluate(Object o)
410 {
411 return moduleDescriptorPredicate.matches((ModuleDescriptor) o);
412 }
413 });
414 return moduleDescriptors;
415 }
416
417
418
419
420
421
422
423 private Collection getModuleDescriptors(final Collection plugins)
424 {
425 final Collection moduleDescriptors = new LinkedList();
426 for (Iterator pluginsIt = plugins.iterator(); pluginsIt.hasNext();)
427 {
428 moduleDescriptors.addAll(((Plugin) pluginsIt.next()).getModuleDescriptors());
429 }
430 return moduleDescriptors;
431 }
432
433
434
435
436
437
438
439
440 private Collection getModules(final Collection moduleDescriptors)
441 {
442 final Collection result = new ArrayList();
443 CollectionUtils.forAllDo(moduleDescriptors, new Closure()
444 {
445 public void execute(Object o)
446 {
447 CollectionUtils.addIgnoreNull(result, ((ModuleDescriptor) o).getModule());
448 }
449 });
450 return result;
451 }
452
453 public Plugin getPlugin(String key)
454 {
455 return (Plugin) plugins.get(key);
456 }
457
458 public Plugin getEnabledPlugin(String pluginKey)
459 {
460 if (!isPluginEnabled(pluginKey))
461 return null;
462
463 return getPlugin(pluginKey);
464 }
465
466 public ModuleDescriptor getPluginModule(String completeKey)
467 {
468 ModuleCompleteKey key = new ModuleCompleteKey(completeKey);
469
470 final Plugin plugin = getPlugin(key.getPluginKey());
471
472 if (plugin == null)
473 return null;
474
475 return plugin.getModuleDescriptor(key.getModuleKey());
476 }
477
478 public ModuleDescriptor getEnabledPluginModule(String completeKey)
479 {
480 ModuleCompleteKey key = new ModuleCompleteKey(completeKey);
481
482
483 if (!isPluginModuleEnabled(completeKey))
484 return null;
485
486 return getEnabledPlugin(key.getPluginKey()).getModuleDescriptor(key.getModuleKey());
487 }
488
489
490
491
492 public List getEnabledModulesByClass(final Class moduleClass)
493 {
494 return (List) getModules(getEnabledModuleDescriptorsByModuleClass(moduleClass));
495 }
496
497
498
499
500
501 public List getEnabledModulesByClassAndDescriptor(final Class[] descriptorClasses, final Class moduleClass)
502 {
503 final Collection moduleDescriptors = getEnabledModuleDescriptorsByModuleClass(moduleClass);
504 filterModuleDescriptors(moduleDescriptors, new ModuleDescriptorOfClassPredicate(descriptorClasses));
505
506 return (List) getModules(moduleDescriptors);
507 }
508
509
510
511
512
513 public List getEnabledModulesByClassAndDescriptor(final Class descriptorClass, final Class moduleClass)
514 {
515 final Collection moduleDescriptors = getEnabledModuleDescriptorsByModuleClass(moduleClass);
516 filterModuleDescriptors(moduleDescriptors, new ModuleDescriptorOfClassPredicate(descriptorClass));
517
518 return (List) getModules(moduleDescriptors);
519 }
520
521
522
523
524
525
526
527 private Collection getEnabledModuleDescriptorsByModuleClass(final Class moduleClass)
528 {
529 final Collection moduleDescriptors = getModuleDescriptors(getEnabledPlugins());
530 filterModuleDescriptors(moduleDescriptors, new ModuleOfClassPredicate(moduleClass));
531 filterModuleDescriptors(moduleDescriptors, new EnabledModulePredicate(this));
532 return moduleDescriptors;
533 }
534
535 public List getEnabledModuleDescriptorsByClass(Class moduleDescriptorClass)
536 {
537 return getEnabledModuleDescriptorsByClass(moduleDescriptorClass, false);
538 }
539
540
541
542
543
544
545
546
547 public List getEnabledModuleDescriptorsByClass(Class moduleDescriptorClass, boolean verbose)
548 {
549 final List result = new LinkedList();
550 for (Iterator iterator = plugins.values().iterator(); iterator.hasNext();)
551 {
552 final Plugin plugin = (Plugin) iterator.next();
553
554
555 if (!isPluginEnabled(plugin.getKey()))
556 {
557 if (verbose && log.isInfoEnabled())
558 {
559 log.info("Plugin [" + plugin.getKey() + "] is disabled.");
560 }
561 continue;
562 }
563
564 for (Iterator iterator1 = plugin.getModuleDescriptors().iterator(); iterator1.hasNext();)
565 {
566 final ModuleDescriptor module = (ModuleDescriptor) iterator1.next();
567 if (moduleDescriptorClass.isInstance(module) && isPluginModuleEnabled(module.getCompleteKey()))
568 {
569 result.add(module);
570 }
571 else
572 {
573 if (verbose && log.isInfoEnabled())
574 {
575 log.info("Module [" + module.getCompleteKey() + "] is disabled.");
576 }
577 }
578 }
579 }
580
581 return result;
582 }
583
584
585
586
587
588 public List getEnabledModuleDescriptorsByType(String type) throws PluginParseException, IllegalArgumentException
589 {
590 final Collection moduleDescriptors = getModuleDescriptors(getEnabledPlugins());
591 filterModuleDescriptors(moduleDescriptors, new ModuleDescriptorOfTypePredicate(moduleDescriptorFactory, type));
592 filterModuleDescriptors(moduleDescriptors, new EnabledModulePredicate(this));
593 return (List) moduleDescriptors;
594 }
595
596
597
598
599
600
601
602 private static void filterModuleDescriptors(final Collection moduleDescriptors, final ModuleDescriptorPredicate moduleDescriptorPredicate)
603 {
604 CollectionUtils.filter(moduleDescriptors, new Predicate()
605 {
606 public boolean evaluate(Object o)
607 {
608 return moduleDescriptorPredicate.matches((ModuleDescriptor) o);
609 }
610 });
611 }
612
613 public void enablePlugin(String key)
614 {
615 if (key == null)
616 throw new IllegalArgumentException("You must specify a plugin key to disable.");
617
618 if (!plugins.containsKey(key))
619 {
620 if (log.isInfoEnabled())
621 log.info("No plugin was found for key '" + key + "'. Not enabling.");
622
623 return;
624 }
625
626 Plugin plugin = (Plugin) plugins.get(key);
627
628 if (!plugin.getPluginInformation().satisfiesMinJavaVersion())
629 {
630 log.error("Minimum Java version of '" + plugin.getPluginInformation().getMinJavaVersion() + "' was not satisfied for module '" + key + "'. Not enabling.");
631 return;
632 }
633
634 enablePluginState(plugin, getStore());
635 notifyPluginEnabled(plugin);
636 }
637
638 protected void enablePluginState(Plugin plugin, PluginStateStore stateStore)
639 {
640 PluginManagerState currentState = stateStore.loadPluginState();
641 String key = plugin.getKey();
642 if (!plugin.isEnabledByDefault())
643 currentState.setState(key, Boolean.TRUE);
644 else
645 currentState.removeState(key);
646 stateStore.savePluginState(currentState);
647 }
648
649
650
651
652
653
654
655
656 protected void notifyPluginEnabled(Plugin plugin)
657 {
658 classLoader.notifyPluginOrModuleEnabled();
659
660 if (plugin instanceof StateAware) {
661 ((StateAware)plugin).enabled();
662 }
663
664 enablePluginModules(plugin);
665
666 }
667
668
669
670
671
672
673 private void enablePluginModules(Plugin plugin)
674 {
675 for (Iterator it = plugin.getModuleDescriptors().iterator(); it.hasNext();)
676 {
677 ModuleDescriptor descriptor = (ModuleDescriptor) it.next();
678
679 if (!(descriptor instanceof StateAware))
680 {
681 if (log.isDebugEnabled())
682 log.debug("ModuleDescriptor '" + descriptor.getName() + "' is not StateAware. No need to enable.");
683 continue;
684 }
685
686 if (!isPluginModuleEnabled(descriptor.getCompleteKey()))
687 {
688 if (log.isDebugEnabled())
689 log.debug("Plugin module is disabled, so not enabling ModuleDescriptor '" + descriptor.getName() + "'.");
690 continue;
691 }
692
693 try
694 {
695 if (log.isDebugEnabled())
696 log.debug("Enabling " + descriptor.getKey());
697 ((StateAware) descriptor).enabled();
698 }
699 catch (Throwable exception)
700 {
701 log.error("There was an error loading the descriptor '" + descriptor.getName() + "' of plugin '" + plugin.getKey() + "'. Disabling.", exception);
702 replacePluginWithUnloadablePlugin(plugin, descriptor, exception);
703 }
704 }
705 classLoader.notifyPluginOrModuleEnabled();
706 }
707
708 public void disablePlugin(String key)
709 {
710 if (key == null)
711 throw new IllegalArgumentException("You must specify a plugin key to disable.");
712
713 if (!plugins.containsKey(key))
714 {
715 if (log.isInfoEnabled())
716 log.info("No plugin was found for key '" + key + "'. Not disabling.");
717
718 return;
719 }
720
721 Plugin plugin = (Plugin) plugins.get(key);
722
723 notifyPluginDisabled(plugin);
724 disablePluginState(plugin, getStore());
725 }
726
727 protected void disablePluginState(Plugin plugin, PluginStateStore stateStore)
728 {
729 String key = plugin.getKey();
730 PluginManagerState currentState = stateStore.loadPluginState();
731 if (plugin.isEnabledByDefault())
732 currentState.setState(key, Boolean.FALSE);
733 else
734 currentState.removeState(key);
735 stateStore.savePluginState(currentState);
736 }
737
738 protected List getEnabledStateAwareModuleKeys(Plugin plugin)
739 {
740 List keys = new ArrayList();
741 List moduleDescriptors = new ArrayList(plugin.getModuleDescriptors());
742 Collections.reverse(moduleDescriptors);
743 for (Iterator it = moduleDescriptors.iterator(); it.hasNext();)
744 {
745 ModuleDescriptor md = (ModuleDescriptor) it.next();
746 if (md instanceof StateAware)
747 {
748 if (isPluginModuleEnabled(md.getCompleteKey()))
749 {
750 keys.add(md.getCompleteKey());
751 }
752 }
753 }
754 return keys;
755 }
756
757 protected void notifyPluginDisabled(Plugin plugin)
758 {
759 List keysToDisable = getEnabledStateAwareModuleKeys(plugin);
760
761 for (Iterator it = keysToDisable.iterator(); it.hasNext();)
762 {
763 String key = (String) it.next();
764 StateAware descriptor = (StateAware) getPluginModule(key);
765 descriptor.disabled();
766 }
767
768
769 if (plugin instanceof StateAware) {
770 ((StateAware)plugin).disabled();
771 }
772 }
773
774 public void disablePluginModule(String completeKey)
775 {
776 if (completeKey == null)
777 throw new IllegalArgumentException("You must specify a plugin module key to disable.");
778
779 final ModuleDescriptor module = getPluginModule(completeKey);
780
781 if (module == null)
782 {
783 if (log.isInfoEnabled())
784 log.info("Returned module for key '" + completeKey + "' was null. Not disabling.");
785
786 return;
787 }
788 disablePluginModuleState(module, getStore());
789 notifyModuleDisabled(module);
790 }
791
792 protected void disablePluginModuleState(ModuleDescriptor module, PluginStateStore stateStore)
793 {
794 String completeKey = module.getCompleteKey();
795 PluginManagerState currentState = stateStore.loadPluginState();
796 if (module.isEnabledByDefault())
797 currentState.setState(completeKey, Boolean.FALSE);
798 else
799 currentState.removeState(completeKey);
800 stateStore.savePluginState(currentState);
801 }
802
803 protected void notifyModuleDisabled(ModuleDescriptor module)
804 {
805 if (module instanceof StateAware)
806 ((StateAware) module).disabled();
807 }
808
809 public void enablePluginModule(String completeKey)
810 {
811 if (completeKey == null)
812 throw new IllegalArgumentException("You must specify a plugin module key to disable.");
813
814 final ModuleDescriptor module = getPluginModule(completeKey);
815
816 if (module == null)
817 {
818 if (log.isInfoEnabled())
819 log.info("Returned module for key '" + completeKey + "' was null. Not enabling.");
820
821 return;
822 }
823
824 if (!module.satisfiesMinJavaVersion())
825 {
826 log.error("Minimum Java version of '" + module.getMinJavaVersion() + "' was not satisfied for module '" + completeKey + "'. Not enabling.");
827 return;
828 }
829 enablePluginModuleState(module, getStore());
830 notifyModuleEnabled(module);
831 }
832
833 protected void enablePluginModuleState(ModuleDescriptor module, PluginStateStore stateStore)
834 {
835 String completeKey = module.getCompleteKey();
836 PluginManagerState currentState = stateStore.loadPluginState();
837 if (!module.isEnabledByDefault())
838 currentState.setState(completeKey, Boolean.TRUE);
839 else
840 currentState.removeState(completeKey);
841 stateStore.savePluginState(currentState);
842 }
843
844 protected void notifyModuleEnabled(ModuleDescriptor module)
845 {
846 classLoader.notifyPluginOrModuleEnabled();
847 if (module instanceof StateAware)
848 ((StateAware) module).enabled();
849 }
850
851 public boolean isPluginModuleEnabled(String completeKey)
852 {
853
854 if (completeKey == null) {
855 return false;
856 }
857 ModuleCompleteKey key = new ModuleCompleteKey(completeKey);
858
859 final ModuleDescriptor pluginModule = getPluginModule(completeKey);
860 return isPluginEnabled(key.getPluginKey()) && pluginModule != null && getState().isEnabled(pluginModule);
861 }
862
863 public boolean isPluginEnabled(String key)
864 {
865 return plugins.containsKey(key) && getState().isEnabled((Plugin) plugins.get(key));
866 }
867
868 public InputStream getDynamicResourceAsStream(String name)
869 {
870 return getClassLoader().getResourceAsStream(name);
871 }
872
873 public Class getDynamicPluginClass(String className) throws ClassNotFoundException
874 {
875 return getClassLoader().loadClass(className);
876 }
877
878 public ClassLoader getClassLoader()
879 {
880 return classLoader;
881 }
882
883 public InputStream getPluginResourceAsStream(String pluginKey, String resourcePath)
884 {
885 Plugin plugin = getEnabledPlugin(pluginKey);
886 if (plugin == null)
887 {
888 log.error("Attempted to retreive resource " + resourcePath + " for non-existent or inactive plugin " + pluginKey);
889 return null;
890 }
891
892 return plugin.getResourceAsStream(resourcePath);
893 }
894
895
896
897
898
899
900
901
902
903 private UnloadablePlugin replacePluginWithUnloadablePlugin(Plugin plugin, ModuleDescriptor descriptor, Throwable throwable)
904 {
905 UnloadableModuleDescriptor unloadableDescriptor =
906 UnloadableModuleDescriptorFactory.createUnloadableModuleDescriptor(plugin, descriptor, throwable);
907 UnloadablePlugin unloadablePlugin = UnloadablePluginFactory.createUnloadablePlugin(plugin, unloadableDescriptor);
908
909 unloadablePlugin.setUninstallable(plugin.isUninstallable());
910 unloadablePlugin.setDeletable(plugin.isDeleteable());
911 plugins.put(plugin.getKey(), unloadablePlugin);
912
913
914 disablePluginState(plugin, getStore());
915 return unloadablePlugin;
916 }
917
918 public boolean isSystemPlugin(String key)
919 {
920 Plugin plugin = getPlugin(key);
921 return plugin != null && plugin.isSystemPlugin();
922 }
923
924
925
926
927 public void setDescriptorParserFactory(DescriptorParserFactory descriptorParserFactory)
928 {
929 }
930 }