001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2013, 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.io.Parameters;
024 import org.qedeq.base.trace.Trace;
025 import org.qedeq.kernel.bo.KernelContext;
026 import org.qedeq.kernel.bo.common.KernelServices;
027 import org.qedeq.kernel.bo.common.PluginExecutor;
028 import org.qedeq.kernel.bo.common.ServiceProcess;
029 import org.qedeq.kernel.bo.module.KernelQedeqBo;
030 import org.qedeq.kernel.bo.module.PluginBo;
031
032 /**
033 * Manage all known plugins.
034 */
035 public class PluginManager {
036
037 /** This class. */
038 private static final Class CLASS = PluginManager.class;
039
040 /** Maps plugin ids to plugins. */
041 private final Map id2plugin = new HashMap();
042
043 /** Stores all plugins. */
044 private final List plugins = new ArrayList();
045
046 /** Collects process infos. */
047 private final ServiceProcessManager processManager;
048
049 /** Basic kernel properties. */
050 private final KernelServices kernel;
051
052 /**
053 * Constructor.
054 *
055 * @param kernel Kernel access.
056 * @param processManager Collects process information.
057 */
058 public PluginManager(final KernelServices kernel, final ServiceProcessManager processManager) {
059 this.kernel = kernel;
060 this.processManager = processManager;
061 }
062
063 /**
064 * Get all registered plugins.
065 *
066 * @return Registered plugins.
067 */
068 synchronized PluginBo[] getPlugins() {
069 return (PluginBo[]) plugins.toArray(new PluginBo[] {});
070 }
071
072 /**
073 * Add a plugin..
074 *
075 * @param pluginClass Class that extends {@link PluginBo} to add.
076 * A plugin with same name can not be added twice.
077 * Must not be <code>null</code>.
078 * @throws RuntimeException Plugin addition failed.
079 */
080 synchronized void addPlugin(final String pluginClass) {
081 final String method = "addPlugin";
082 PluginBo plugin = null;
083 try {
084 Class cl = Class.forName(pluginClass);
085 plugin = (PluginBo) cl.newInstance();
086 } catch (ClassNotFoundException e) {
087 Trace.fatal(CLASS, this, method, "Plugin class not in class path: " + pluginClass, e);
088 throw new RuntimeException(e);
089 } catch (InstantiationException e) {
090 Trace.fatal(CLASS, this, method, "Plugin class could not be istanciated: "
091 + pluginClass, e);
092 throw new RuntimeException(e);
093 } catch (IllegalAccessException e) {
094 Trace.fatal(CLASS, this, method,
095 "Programming error, access for instantiation failed for plugin: " + pluginClass,
096 e);
097 throw new RuntimeException(e);
098 } catch (RuntimeException e) {
099 Trace.fatal(CLASS, this, method,
100 "Programming error, instantiation failed for plugin: " + pluginClass, e);
101 throw new RuntimeException(e);
102 }
103 addPlugin(plugin);
104 // set default plugin values for not yet set parameters
105 final Parameters parameters = kernel.getConfig().getPluginEntries(plugin);
106 plugin.setDefaultValuesForEmptyPluginParameters(parameters);
107 kernel.getConfig().setPluginKeyValues(plugin, parameters);
108 }
109
110 /**
111 * Add a plugin.
112 *
113 * @param plugin Plugin to add. A plugin with same name can not be added twice.
114 * Must not be <code>null</code>.
115 * @throws RuntimeException Plugin addition failed.
116 */
117 synchronized void addPlugin(final PluginBo plugin) {
118 if (id2plugin.get(plugin.getPluginId()) != null) {
119 final PluginBo oldPlugin = (PluginBo) id2plugin.get(plugin.getPluginId());
120 final RuntimeException e = new IllegalArgumentException("plugin with that name already added: "
121 + oldPlugin.getPluginId() + ": " + plugin.getPluginDescription());
122 Trace.fatal(CLASS, this, "addPlugin", "Programing error", e);
123 throw e;
124 }
125 id2plugin.put(plugin.getPluginId(), plugin);
126 plugins.add(plugin);
127 }
128
129 /**
130 * Execute a plugin on an QEDEQ module.
131 *
132 * @param id Plugin to use.
133 * @param qedeq QEDEQ module to work on.
134 * @return Plugin specific resulting object. Might be <code>null</code>.
135 * @throws RuntimeException Plugin unknown, or execution had a major problem.
136 */
137 Object executePlugin(final String id, final KernelQedeqBo qedeq) {
138 final PluginBo plugin = (PluginBo) id2plugin.get(id);
139 if (plugin == null) {
140 final String message = "Kernel does not know about plugin: ";
141 final RuntimeException e = new RuntimeException(message + id);
142 Trace.fatal(CLASS, this, "executePlugin", message + id,
143 e);
144 throw e;
145 }
146 final Parameters parameters = KernelContext.getInstance().getConfig().getPluginEntries(plugin);
147 final ServiceProcess process = processManager.createProcess(plugin,
148 qedeq, parameters);
149 process.setBlocked(true);
150 synchronized (qedeq) {
151 process.setBlocked(false);
152 try {
153 final PluginExecutor exe = plugin.createExecutor(qedeq, parameters);
154 process.setExecutor(exe);
155 final Object result = exe.executePlugin();
156 process.setSuccessState();
157 return result;
158 } finally {
159 if (process.isRunning()) {
160 process.setFailureState();
161 }
162 // remove old executor
163 process.setExecutor(null);
164 }
165 }
166 }
167
168 /**
169 * Clear all plugin errors and warnings on an QEDEQ module.
170 *
171 * @param qedeq Clear reults for this module.
172 */
173 public void clearAllPluginResults(final KernelQedeqBo qedeq) {
174 qedeq.clearAllPluginErrorsAndWarnings();
175 }
176
177 }
|