/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * Author: Michael Dewsnip, NZDL Project, University of Waikato * * Copyright (C) 2006 New Zealand Digital Library Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.greenstone; import java.io.*; import java.util.*; import javax.swing.*; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.cdm.Argument; import org.greenstone.gatherer.cdm.Plugin; import org.greenstone.gatherer.remote.RemoteGreenstoneServer; import org.greenstone.gatherer.util.SafeProcess; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.Utility; import org.greenstone.gatherer.util.XMLTools; import org.w3c.dom.*; import org.xml.sax.*; /** This class is for maintaining a list of known plug-ins, and importing new plugins using the parser. */ public class Plugins { // A list of all the plugins in the core Greenstone "perllib/plugins" folder (arguments may not be loaded) static private ArrayList core_greenstone_plugins_list = null; // The name of the loaded collection static private String collection_name = null; // A list of all the plugins in the loaded collection's "perllib/plugins" folder (arguments may not be loaded) static private ArrayList collection_specific_plugins_list = new ArrayList(); static public Plugin getPlugin(String plugin_name, boolean arguments_required) { Plugin plugin = null; boolean collection_specific = false; // Check the collection-specific plugins first for (int i = 0; i < collection_specific_plugins_list.size(); i++) { Plugin collection_specific_plugin = (Plugin) collection_specific_plugins_list.get(i); if (collection_specific_plugin.getName().equals(plugin_name)) { plugin = collection_specific_plugin; collection_specific = true; break; } } // Try the core Greenstone plugins if necessary if (plugin == null) { for (int i = 0; i < core_greenstone_plugins_list.size(); i++) { Plugin core_greenstone_plugin = (Plugin) core_greenstone_plugins_list.get(i); if (core_greenstone_plugin.getName().equals(plugin_name)) { plugin = core_greenstone_plugin; break; } } } // If we've found the plugin, load its arguments now, if required if (plugin != null && arguments_required) { if (!plugin.hasLoadedOptions()) { loadPluginInfo(plugin, collection_specific); } else { DebugStream.println("Already loaded arguments for " + plugin_name + "!"); } } return plugin; } /** Returns a new list from merging the collection-specific and the core Greenstone plugins. */ static public ArrayList getPluginsList() { ArrayList plugins_list = new ArrayList(); plugins_list.addAll(collection_specific_plugins_list); // Add in the core Greenstone plugins, taking care not to overwrite any collection-specific ones for (int i = 0; i < core_greenstone_plugins_list.size(); i++) { Plugin core_greenstone_plugin = (Plugin) core_greenstone_plugins_list.get(i); boolean found = false; for (int j = 0; j < collection_specific_plugins_list.size(); j++) { Plugin collection_specific_plugin = (Plugin) collection_specific_plugins_list.get(j); if (core_greenstone_plugin.getName().equals(collection_specific_plugin.getName())) { found = true; break; } } if (!found) { plugins_list.add(core_greenstone_plugin); } } return plugins_list; } static private void loadPluginInfo(Plugin plugin, boolean collection_specific) { DebugStream.println("Loading arguments for " + plugin.getName() + "..."); // Run pluginfo.pl to get the list of plugins try { String pluginfo_xml = null; if (Gatherer.isGsdlRemote) { String pluginfo_options = "&plugin=" + plugin; if (collection_specific) { pluginfo_options += "&collection=" + collection_name; } pluginfo_xml = Gatherer.remoteGreenstoneServer.getScriptOptions("pluginfo.pl", pluginfo_options); } else { ArrayList args = new ArrayList(); args.add(Configuration.perl_path); args.add("-S"); args.add(LocalGreenstone.getBinScriptDirectoryPath() + "pluginfo.pl"); args.add("-gs_version"); if (Gatherer.GS3) { args.add("3"); } else { args.add("2"); } if (collection_specific) { args.add("-collection"); args.add(collection_name); if (Gatherer.GS3) { args.add("-site"); args.add(Configuration.site_name); } } args.add("-xml"); args.add("-language"); args.add(Configuration.getLanguage()); args.add(plugin.getName()); // Run the pluginfo.pl process: // Create the process. SafeProcess process = new SafeProcess((String[]) args.toArray(new String[] { })); process.setSplitStdErrorNewLines(true); // run the SafeProcess int exitVal = process.runProcess(); if(exitVal != 0) { throw new Exception("*** Error running pluginfo.pl loadPlugInfo, process exited with: " + exitVal); } // get the result: We expect XML to have come out of the process std error stream. pluginfo_xml = process.getStdError(); // make sure to have parsed out any lines preceding the XML content pluginfo_xml = XMLTools.readXMLStream(pluginfo_xml).toString(); ///System.err.println("*********\nPluginInfo, got:\n" + pluginfo_xml + "\n**********\n"); } // Check the XML output was obtained successfully if (pluginfo_xml == null || pluginfo_xml.length() == 0) { plugin.setHasLoadedOptions(false); // failure to load options JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.PlugInManager.PlugIn_XML_Parse_Failed", plugin.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE); return; } else { plugin.setHasLoadedOptions(true); } parsePluginInfoXML(plugin, pluginfo_xml); } catch (Exception exception) { DebugStream.printStackTrace(exception); } } static public void loadPluginsList(String collection_name_arg) { DebugStream.println("In loadPluginsList()..."); // If we're getting the collection-specific plugins, clear the old list no matter what if (collection_name_arg != null) { collection_name = collection_name_arg; collection_specific_plugins_list = new ArrayList(); } // Run pluginfo.pl to get the list of plugins try { String xml = null; if (Gatherer.isGsdlRemote) { String pluginfo_options = "&listall"; if (collection_name != null) { pluginfo_options += "&collection=" + collection_name; } String pluginfo_output = Gatherer.remoteGreenstoneServer.getScriptOptions("pluginfo.pl", pluginfo_options); xml = pluginfo_output; } else { ArrayList args = new ArrayList(); args.add(Configuration.perl_path); args.add("-S"); args.add(LocalGreenstone.getBinScriptDirectoryPath() + "pluginfo.pl"); args.add("-gs_version"); if (Gatherer.GS3) { args.add("3"); } else { args.add("2"); } if (collection_name != null) { args.add("-collection"); args.add(collection_name); if (Gatherer.GS3) { args.add("-site"); args.add(Configuration.site_name); } } args.add("-listall"); args.add("-xml"); // Run the pluginfo.pl process: // Create the process. SafeProcess process = new SafeProcess((String[]) args.toArray(new String[] { })); process.setSplitStdErrorNewLines(true); // run the SafeProcess int exitVal = process.runProcess(); if(exitVal != 0) { throw new Exception("*** Error running pluginfo.pl loadPluginsList, process exited with: " + exitVal); } // get the result: We expect XML to have come out of the process std error stream. xml = process.getStdError(); // make sure to parse out any lines before the XML content, else running "gli -debug" results in an XML error: // for pluginfo.pl -listall, we see a "AutoloadConverters" (PDFBox) message // before actual XML output, which breaks XML parsing. // This gets rid of output before " tag plugin.setDoesReplaceSrcDocsWithHtml(XMLTools.getValue(node).equalsIgnoreCase(StaticStrings.YES_STR)); } else if (node_name.equalsIgnoreCase("Processes")) { plugin.setDefaultProcessExpression(XMLTools.getValue(node)); } else if (node_name.equalsIgnoreCase("Blocks")) { plugin.setDefaultBlockExpression(XMLTools.getValue(node)); } // Parse the plugin arguments else if (node_name.equalsIgnoreCase("Arguments")) { for (Node argument_node = node.getFirstChild(); argument_node != null; argument_node = argument_node.getNextSibling()) { // An option if (argument_node.getNodeName().equalsIgnoreCase("Option")) { Argument argument = new Argument(); argument.parseXML((Element) argument_node); plugin.addArgument(argument); } } } // A super plugin class else if (node_name.equalsIgnoreCase("PlugInfo")) { Plugin super_plugin = new Plugin(); parsePluginInfoXMLNode(super_plugin, node); plugin.setSuper(super_plugin); } } } static private ArrayList parsePluginsListXML(String xml) { ArrayList plugins_list = new ArrayList(); Document document = XMLTools.parseXML(new StringReader(xml)); Node root = document.getDocumentElement(); for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) { String node_name = node.getNodeName(); if (node_name.equals("PlugInfo")) { Plugin plugin = new Plugin(); parsePluginInfoXMLNode(plugin, node); plugins_list.add(plugin); } } return plugins_list; } }