001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2011, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.service;
017
018 import java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 import org.qedeq.base.trace.Trace;
024 import org.qedeq.kernel.bo.common.PluginExecutor;
025 import org.qedeq.kernel.bo.common.ServiceProcess;
026 import org.qedeq.kernel.bo.module.KernelQedeqBo;
027 import org.qedeq.kernel.bo.module.PluginBo;
028
029 /**
030 * Manage all known plugins.
031 */
032 public class PluginManager {
033
034 /** This class. */
035 private static final Class CLASS = PluginManager.class;
036
037 /** Maps plugin ids to plugins. */
038 private final Map id2plugin = new HashMap();
039
040 /** Stores all plugins. */
041 private final List plugins = new ArrayList();
042
043 /** Collects process infos. */
044 private ServiceProcessManager processManager;
045
046
047 /**
048 * Constructor.
049 *
050 * @param processManager Collects process information.
051 */
052 public PluginManager(final ServiceProcessManager processManager) {
053 this.processManager = processManager;
054 }
055
056 /**
057 * Get all registered plugins.
058 *
059 * @return Registered plugins.
060 */
061 synchronized PluginBo[] getPlugins() {
062 return (PluginBo[]) plugins.toArray(new PluginBo[] {});
063 }
064
065 /**
066 * Add a plugin..
067 *
068 * @param pluginClass Class that extends {@link PluginBo} to add.
069 * A plugin with same name can not be added twice.
070 * Must not be <code>null</code>.
071 * @throws RuntimeException Plugin addition failed.
072 */
073 synchronized void addPlugin(final String pluginClass) {
074 final String method = "addPlugin";
075 PluginBo plugin = null;
076 try {
077 Class cl = Class.forName(pluginClass);
078 plugin = (PluginBo) cl.newInstance();
079 } catch (ClassNotFoundException e) {
080 Trace.fatal(CLASS, this, method, "Plugin class not in class path: " + pluginClass, e);
081 throw new RuntimeException(e);
082 } catch (InstantiationException e) {
083 Trace.fatal(CLASS, this, method, "Plugin class could not be istanciated: "
084 + pluginClass, e);
085 throw new RuntimeException(e);
086 } catch (IllegalAccessException e) {
087 Trace.fatal(CLASS, this, method,
088 "Programming error, access for instantiation failed for plugin: " + pluginClass,
089 e);
090 throw new RuntimeException(e);
091 } catch (RuntimeException e) {
092 Trace.fatal(CLASS, this, method,
093 "Programming error, instantiation failed for plugin: " + pluginClass, e);
094 throw new RuntimeException(e);
095 }
096 addPlugin(plugin);
097 }
098
099 /**
100 * Add a plugin.
101 *
102 * @param plugin Plugin to add. A plugin with same name can not be added twice.
103 * Must not be <code>null</code>.
104 * @throws RuntimeException Plugin addition failed.
105 */
106 synchronized void addPlugin(final PluginBo plugin) {
107 if (id2plugin.get(plugin.getPluginId()) != null) {
108 final PluginBo oldPlugin = (PluginBo) id2plugin.get(plugin.getPluginId());
109 final RuntimeException e = new IllegalArgumentException("plugin with that name already added: "
110 + oldPlugin.getPluginId() + ": " + plugin.getPluginDescription());
111 Trace.fatal(CLASS, this, "addPlugin", "Programing error", e);
112 throw e;
113 }
114 id2plugin.put(plugin.getPluginId(), plugin);
115 plugins.add(plugin);
116 }
117
118 /**
119 * Execute a plugin on an QEDEQ module.
120 *
121 * @param id Plugin to use.
122 * @param qedeq QEDEQ module to work on.
123 * @param parameters Plugin specific parameters. Might be <code>null</code>.
124 * @return Plugin specific resulting object. Might be <code>null</code>.
125 * @throws RuntimeException Plugin unknown, or execution had a major problem.
126 */
127 Object executePlugin(final String id, final KernelQedeqBo qedeq,
128 final Map parameters) {
129 final PluginBo plugin = (PluginBo) id2plugin.get(id);
130 if (plugin == null) {
131 final String message = "Kernel does not know about plugin: ";
132 final RuntimeException e = new RuntimeException(message + id);
133 Trace.fatal(CLASS, this, "executePlugin", message + id,
134 e);
135 throw e;
136 }
137 Map para = parameters;
138 if (parameters == null) {
139 para = new HashMap();
140 }
141 final ServiceProcess process = processManager.createProcess(plugin,
142 qedeq, para);
143 process.setBlocked(true);
144 synchronized (qedeq) {
145 process.setBlocked(false);
146 try {
147 final PluginExecutor exe = plugin.createExecutor(qedeq, para);
148 process.setExecutor(exe);
149 final Object result = exe.executePlugin();
150 process.setSuccessState();
151 return result;
152 } finally {
153 if (process.isRunning()) {
154 process.setFailureState();
155 }
156 // remove old executor
157 process.setExecutor(null);
158 }
159 }
160 }
161
162 /**
163 * Clear all plugin errors and warnings on an QEDEQ module.
164 *
165 * @param qedeq Clear reults for this module.
166 */
167 public void clearAllPluginResults(final KernelQedeqBo qedeq) {
168 qedeq.clearAllPluginErrorsAndWarnings();
169 }
170
171 }
|