root/main/trunk/gli/src/org/greenstone/gatherer/greenstone/Plugins.java @ 31641

Revision 31641, 12.2 KB (checked in by ak19, 6 months ago)

Bugfix after changing over to SafeProcess?: XML parsing failed because of something else being printed to STDERR before the actual XML, which the old code had been handling. Now the new code handles it too.

  • Property svn:keywords set to Author Date Id Revision
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: Michael Dewsnip, NZDL Project, University of Waikato
9 *
10 * Copyright (C) 2006 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.greenstone;
28
29import java.io.*;
30import java.util.*;
31import javax.swing.*;
32import org.greenstone.gatherer.Configuration;
33import org.greenstone.gatherer.DebugStream;
34import org.greenstone.gatherer.Dictionary;
35import org.greenstone.gatherer.Gatherer;
36import org.greenstone.gatherer.cdm.Argument;
37import org.greenstone.gatherer.cdm.Plugin;
38import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
39import org.greenstone.gatherer.util.SafeProcess;
40import org.greenstone.gatherer.util.StaticStrings;
41import org.greenstone.gatherer.util.Utility;
42import org.greenstone.gatherer.util.XMLTools;
43import org.w3c.dom.*;
44import org.xml.sax.*;
45
46
47/** This class is for maintaining a list of known plug-ins, and importing new plugins using the parser. */
48public class Plugins
49{
50    // A list of all the plugins in the core Greenstone "perllib/plugins" folder (arguments may not be loaded)
51    static private ArrayList core_greenstone_plugins_list = null;
52    // The name of the loaded collection
53    static private String collection_name = null;
54    // A list of all the plugins in the loaded collection's "perllib/plugins" folder (arguments may not be loaded)
55    static private ArrayList collection_specific_plugins_list = new ArrayList();
56
57
58    static public Plugin getPlugin(String plugin_name, boolean arguments_required)
59    {
60    Plugin plugin = null;
61    boolean collection_specific = false;
62
63    // Check the collection-specific plugins first
64    for (int i = 0; i < collection_specific_plugins_list.size(); i++) {
65        Plugin collection_specific_plugin = (Plugin) collection_specific_plugins_list.get(i);
66        if (collection_specific_plugin.getName().equals(plugin_name)) {
67        plugin = collection_specific_plugin;
68        collection_specific = true;
69        break;
70        }
71    }
72
73    // Try the core Greenstone plugins if necessary
74    if (plugin == null) {
75        for (int i = 0; i < core_greenstone_plugins_list.size(); i++) {
76        Plugin core_greenstone_plugin = (Plugin) core_greenstone_plugins_list.get(i);
77        if (core_greenstone_plugin.getName().equals(plugin_name)) {
78            plugin = core_greenstone_plugin;
79            break;
80        }
81        }
82    }
83
84    // If we've found the plugin, load its arguments now, if required
85    if (plugin != null && arguments_required) {
86        if (!plugin.hasLoadedOptions()) {
87        loadPluginInfo(plugin, collection_specific);
88        }
89        else {
90        DebugStream.println("Already loaded arguments for " + plugin_name + "!");
91        }
92    }
93
94    return plugin;
95    }
96
97
98    /** Returns a new list from merging the collection-specific and the core Greenstone plugins. */
99    static public ArrayList getPluginsList()
100    {
101    ArrayList plugins_list = new ArrayList();
102    plugins_list.addAll(collection_specific_plugins_list);
103
104    // Add in the core Greenstone plugins, taking care not to overwrite any collection-specific ones
105    for (int i = 0; i < core_greenstone_plugins_list.size(); i++) {
106        Plugin core_greenstone_plugin = (Plugin) core_greenstone_plugins_list.get(i);
107
108        boolean found = false;
109        for (int j = 0; j < collection_specific_plugins_list.size(); j++) {
110        Plugin collection_specific_plugin = (Plugin) collection_specific_plugins_list.get(j);
111        if (core_greenstone_plugin.getName().equals(collection_specific_plugin.getName())) {
112            found = true;
113            break;
114        }
115        }
116
117        if (!found) {
118        plugins_list.add(core_greenstone_plugin);
119        }
120    }
121
122    return plugins_list;
123    }
124
125
126    static private void loadPluginInfo(Plugin plugin, boolean collection_specific)
127    {
128    DebugStream.println("Loading arguments for " + plugin.getName() + "...");
129
130    // Run pluginfo.pl to get the list of plugins
131    try {
132        String pluginfo_xml = null;
133        if (Gatherer.isGsdlRemote) {
134        String pluginfo_options = "&plugin=" + plugin;
135        if (collection_specific) {
136            pluginfo_options += "&collection=" + collection_name;
137        }
138        pluginfo_xml = Gatherer.remoteGreenstoneServer.getScriptOptions("pluginfo.pl", pluginfo_options);
139        }
140        else {
141        ArrayList args = new ArrayList();
142        args.add(Configuration.perl_path);
143        args.add("-S");
144        args.add(LocalGreenstone.getBinScriptDirectoryPath() + "pluginfo.pl");
145        args.add("-gs_version");
146        if (Gatherer.GS3) {
147            args.add("3");
148        } else {
149            args.add("2");
150        }
151        if (collection_specific) {
152            args.add("-collection");
153            args.add(collection_name);
154            if (Gatherer.GS3) {
155              args.add("-site");
156              args.add(Configuration.site_name);
157            }           
158        }
159        args.add("-xml");
160        args.add("-language");
161        args.add(Configuration.getLanguage());
162        args.add(plugin.getName());
163
164        // Run the pluginfo.pl process:
165        // Create the process.
166        SafeProcess process = new SafeProcess((String[]) args.toArray(new String[] { }));
167
168        // run the SafeProcess
169        int exitVal = process.runProcess();
170        if(exitVal != 0) {
171            throw new Exception("*** Error running pluginfo.pl loadPlugInfo, process exited with: "
172                    + exitVal);
173        }
174        // get the result: We expect XML to have come out of the process std error stream.
175        pluginfo_xml = process.getStdError();
176        ///System.err.println("*********\nPluginInfo, got:\n" + pluginfo_xml + "\n**********\n");
177        }
178
179        // Check the XML output was obtained successfully
180        if (pluginfo_xml == null || pluginfo_xml.length() == 0) {
181        plugin.setHasLoadedOptions(false); // failure to load options
182        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.PlugInManager.PlugIn_XML_Parse_Failed", plugin.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
183        return;
184        } else {
185        plugin.setHasLoadedOptions(true);
186        }
187
188        parsePluginInfoXML(plugin, pluginfo_xml);
189    }
190    catch (Exception exception) {
191        DebugStream.printStackTrace(exception);
192    }
193    }
194
195
196    static public void loadPluginsList(String collection_name_arg)
197    {
198    DebugStream.println("In loadPluginsList()...");
199
200    // If we're getting the collection-specific plugins, clear the old list no matter what
201    if (collection_name_arg != null) {
202        collection_name = collection_name_arg;
203        collection_specific_plugins_list = new ArrayList();
204    }
205
206    // Run pluginfo.pl to get the list of plugins
207    try {
208        String xml = null;
209        if (Gatherer.isGsdlRemote) {
210        String pluginfo_options = "&listall";
211        if (collection_name != null) {
212            pluginfo_options += "&collection=" + collection_name;
213        }
214        String pluginfo_output = Gatherer.remoteGreenstoneServer.getScriptOptions("pluginfo.pl", pluginfo_options);
215        xml = pluginfo_output;
216        }
217        else {
218        ArrayList args = new ArrayList();
219        args.add(Configuration.perl_path);
220        args.add("-S");     
221        args.add(LocalGreenstone.getBinScriptDirectoryPath() + "pluginfo.pl");
222        args.add("-gs_version");
223        if (Gatherer.GS3) {
224            args.add("3");
225        } else {
226            args.add("2");
227        }
228        if (collection_name != null) {
229            args.add("-collection");
230            args.add(collection_name);
231            if (Gatherer.GS3) {
232              args.add("-site");
233              args.add(Configuration.site_name);
234            }
235        }
236        args.add("-listall");
237        args.add("-xml");
238
239        // Run the pluginfo.pl process:
240        // Create the process.
241        SafeProcess process = new SafeProcess((String[]) args.toArray(new String[] { }));
242
243        // run the SafeProcess
244        int exitVal = process.runProcess();
245        if(exitVal != 0) {
246            throw new Exception("*** Error running pluginfo.pl loadPluginsList, process exited with: "
247                    + exitVal);
248        }
249        // get the result: We expect XML to have come out of the process std error stream. 
250        xml = process.getStdError();
251
252        // for pluginfo.pl -listall, we see a "AutoloadConverters" (PDFBox) message
253        // before actual XML output, which breaks XML parsing. Get rid of output before "<?xml"
254        int startIndex = xml.indexOf("<?xml");
255        if(startIndex != 0) {
256            xml = xml.substring(startIndex);
257        }
258        ///System.err.println("*********\nPluginsList, got:\n" + xml + "\n**********\n");
259        }
260
261        // Check the XML output was obtained successfully
262        if (xml == null || xml.length() == 0) {
263        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.PluginManager.Plugin_List_XML_Parse_Failed"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
264        return;
265        }
266
267        if (collection_name != null) {
268        collection_specific_plugins_list = parsePluginsListXML(xml);
269        }
270        else {
271        core_greenstone_plugins_list = parsePluginsListXML(xml);
272        }
273    }
274    catch (Exception exception) {
275        DebugStream.printStackTrace(exception);
276    }
277    }
278
279
280    static private void parsePluginInfoXML(Plugin plugin, String xml)
281    {
282    Document document = XMLTools.parseXML(new StringReader(xml));
283    if (document == null) {
284        plugin.setHasLoadedOptions(false); // failure to load the options/failed plugin
285        JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.PlugInManager.PlugIn_XML_Parse_Failed", plugin.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
286        return;
287    } else {
288        plugin.setHasLoadedOptions(true);
289    }
290
291    parsePluginInfoXMLNode(plugin, document.getDocumentElement());
292    }
293
294
295    static private void parsePluginInfoXMLNode(Plugin plugin, Node root_node)
296    {
297    for (Node node = root_node.getFirstChild(); node != null; node = node.getNextSibling()) {
298        String node_name = node.getNodeName();
299
300        if (node_name.equalsIgnoreCase("Name")) {
301        plugin.setName(XMLTools.getValue(node));
302        }
303        else if (node_name.equals("Desc")) {
304        plugin.setDescription(XMLTools.getValue(node));
305        }
306        else if (node_name.equals("Abstract")) {
307        plugin.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(StaticStrings.YES_STR));
308        }
309        else if (node_name.equalsIgnoreCase("Explodes")) {
310        plugin.setDoesExplodeMetadataDatabases(XMLTools.getValue(node).equalsIgnoreCase(StaticStrings.YES_STR));
311        }
312        else if (node_name.equalsIgnoreCase("SourceReplaceable")) { // looking for <SourceReplaceable> tag
313        plugin.setDoesReplaceSrcDocsWithHtml(XMLTools.getValue(node).equalsIgnoreCase(StaticStrings.YES_STR));
314        }
315        else if (node_name.equalsIgnoreCase("Processes")) {
316        plugin.setDefaultProcessExpression(XMLTools.getValue(node));
317        }
318        else if (node_name.equalsIgnoreCase("Blocks")) {
319        plugin.setDefaultBlockExpression(XMLTools.getValue(node));
320        }
321        // Parse the plugin arguments
322        else if (node_name.equalsIgnoreCase("Arguments")) {
323        for (Node argument_node = node.getFirstChild(); argument_node != null; argument_node = argument_node.getNextSibling()) {
324            // An option
325            if (argument_node.getNodeName().equalsIgnoreCase("Option")) {
326            Argument argument = new Argument();
327            argument.parseXML((Element) argument_node);
328            plugin.addArgument(argument);
329            }
330        }
331        }
332        // A super plugin class
333        else if (node_name.equalsIgnoreCase("PlugInfo")) {
334        Plugin super_plugin = new Plugin();
335        parsePluginInfoXMLNode(super_plugin, node);
336        plugin.setSuper(super_plugin);
337        }
338    }
339    }
340
341
342    static private ArrayList parsePluginsListXML(String xml)
343    {
344    ArrayList plugins_list = new ArrayList();
345   
346    Document document = XMLTools.parseXML(new StringReader(xml));
347    Node root = document.getDocumentElement();
348    for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
349        String node_name = node.getNodeName();
350
351        if (node_name.equals("PlugInfo")) {
352        Plugin plugin = new Plugin();
353        parsePluginInfoXMLNode(plugin, node);
354        plugins_list.add(plugin);
355        }
356    }
357
358    return plugins_list;
359    }
360}
Note: See TracBrowser for help on using the browser.