001 /*
002 *
003 * $Revision: 13883 $ $Date: 2008-08-20 11:52:39 +0200 (Mi, 20 Aug 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.services.plugins;
025
026 import java.io.File;
027 import java.io.InputStream;
028 import java.io.Reader;
029 import java.io.StringReader;
030 import java.net.MalformedURLException;
031 import java.net.URL;
032 import java.util.Collection;
033 import java.util.HashSet;
034 import java.util.Hashtable;
035 import java.util.Iterator;
036 import java.util.Properties;
037 import java.util.Enumeration;
038
039 import org.apache.log4j.Logger;
040 import org.mycore.common.MCRConfiguration;
041 import org.mycore.datamodel.ifs.MCRFileContentType;
042
043 /**
044 * Loads and manages plugins
045 *
046 * @author Thomas Scheffler (yagee)
047 */
048 public class TextFilterPluginManager {
049 /** The logger */
050 private static final Logger LOGGER = Logger.getLogger(TextFilterPluginManager.class);
051
052 /** The configuration */
053 private static final MCRConfiguration CONF = MCRConfiguration.instance();
054
055 /** Pluginbasket */
056 private static Hashtable CONTENT_TYPE_PLUGIN_BAG = null;
057
058 private static Hashtable PLUGINS = null;
059
060 /** initialized */
061 private static TextFilterPluginManager SINGLETON;
062
063 /**
064 *
065 */
066 private TextFilterPluginManager() {
067 init();
068 }
069
070 public static TextFilterPluginManager getInstance() {
071 if (SINGLETON == null) {
072 SINGLETON = new TextFilterPluginManager();
073 }
074
075 return SINGLETON;
076 }
077
078 private void init() {
079 CONTENT_TYPE_PLUGIN_BAG = new Hashtable();
080 PLUGINS = new Hashtable();
081 loadPlugins();
082 }
083
084 /**
085 * load TextFilterPlugins from the MCR.PluginDirectory
086 *
087 */
088 public void loadPlugins() {
089 MCRConfiguration config = MCRConfiguration.instance();
090 String prefix = "MCR.TextFilterPlugin.";
091 Properties props = config.getProperties(prefix);
092 if (props == null) {
093 return;
094 }
095
096 TextFilterPlugin filter = null;
097 MCRFileContentType ct;
098
099 Enumeration e = props.propertyNames();
100 while (e.hasMoreElements())
101 {
102 String propertyName = (String) e.nextElement();
103 try
104 {
105 Object o = config.getInstanceOf(propertyName);
106 if (null != o)
107 {
108 filter = (TextFilterPlugin)o;
109 LOGGER.info(new StringBuffer(propertyName + "Loading TextFilterPlugin: ").append(filter.getName()).append(" v:").append(filter.getMajorNumber()).append('.').append(filter.getMinorNumber()).toString());
110 for (Iterator CtIterator = filter.getSupportedContentTypes().iterator(); CtIterator.hasNext();) {
111 // Add MIME Type filters to the basket
112 ct = (MCRFileContentType) CtIterator.next();
113
114 if (ct != null) {
115 CONTENT_TYPE_PLUGIN_BAG.put(ct, filter);
116 }
117 }
118
119 PLUGINS.put(filter.getClass().getName(), filter);
120 }
121 else LOGGER.info("TextFilterPlugin not available: "+ propertyName + " with property: " + props.getProperty(propertyName));
122 } catch (Exception e1)
123 {
124 LOGGER.info(e1.toString());
125 }
126
127 }
128 }
129
130 /**
131 * removes all plugins from the manager
132 *
133 */
134 public void clear() {
135 init();
136 }
137
138 /**
139 * removes all plugins and reload plugins after that
140 *
141 * This is when you delete a plugin while the application is running,
142 * replacing one with a new version or if you just add one.
143 */
144 public void reloadPlugins() {
145 clear();
146 loadPlugins();
147 }
148
149 /**
150 * returns a Collection of all loaded plugins.
151 *
152 * @return a Collection of Plugins
153 */
154 public Collection getPlugins() {
155 return PLUGINS.values();
156 }
157
158 /**
159 * returns TextFilterPlugin to corresponding MIME type
160 *
161 * @param ct supported
162 * MIME type
163 * @return corresponding TextFilterPlugin or null if MIME is emtpy or null
164 */
165 public TextFilterPlugin getPlugin(MCRFileContentType ct) {
166 return (ct == null) ? null : (TextFilterPlugin) CONTENT_TYPE_PLUGIN_BAG.get(ct);
167 }
168
169 /**
170 * checks whether content type is supported
171 *
172 * @param ct content type
173 * of Inputstream
174 * @return true if content type is supported, else false
175 */
176 public boolean isSupported(MCRFileContentType ct) {
177 return (ct == null) ? false : CONTENT_TYPE_PLUGIN_BAG.containsKey(ct);
178 }
179
180 /**
181 * returns a Reader for the characters of the InputStream
182 *
183 * @param ct
184 * ContentType of the InputStream
185 * @param input
186 * InputStream to be parsed
187 * @return null if ContentType is unsupported, else a Reader for the parsed
188 * characters
189 * @throws FilterPluginTransformException
190 */
191 public Reader transform(MCRFileContentType ct, InputStream input) throws FilterPluginTransformException {
192 if (isSupported(ct)) {
193 try {
194 return getPlugin(ct).transform(ct, input);
195 } catch (Exception ex) {
196 LOGGER.warn("Exception in text filter plug-in:", ex);
197 return new StringReader("");
198 }
199 }
200
201 return null;
202 }
203
204 }