/**
*#########################################################################
*
* 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: Anupama Krishnan, Greenstone Digital Library, University of Waikato
* Code based entirely on Katherine Don's ExplodeMetadataDatabasePrompt.java
* (part of the Greenstone Digital Library)
*
* Copyright (C) 2008 Greenstone 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.gui;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.io.*;
import java.util.ArrayList;
import org.w3c.dom.Document;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.cdm.Argument;
import org.greenstone.gatherer.cdm.ArgumentControl;
import org.greenstone.gatherer.cdm.CollectionDesignManager;
import org.greenstone.gatherer.cdm.Plugin;
import org.greenstone.gatherer.collection.CollectionManager;
import org.greenstone.gatherer.collection.ScriptOptions;
import org.greenstone.gatherer.collection.Collection;
import org.greenstone.gatherer.feedback.Base64;
import org.greenstone.gatherer.greenstone.LocalGreenstone;
import org.greenstone.gatherer.gui.tree.DragTree;
import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
import org.greenstone.gatherer.shell.GShell;
import org.greenstone.gatherer.shell.GShellEvent;
import org.greenstone.gatherer.shell.GShellListener;
import org.greenstone.gatherer.util.Utility;
import org.greenstone.gatherer.util.XMLTools;
public class ReplaceSrcDocWithHtmlPrompt
extends ModalDialog
implements GShellListener
{
/** The size of this new collection dialog box. */
static private Dimension SIZE = new Dimension(675, 250);
private JDialog self;
/** the source document files we wil be replacing with their GS3-generated html equivalent */
private File[] srcdoc_files = null;
/** the names of the srcdoc_files that could not be replaced with their GS3-generated html equivalent */
private java.util.Vector failedFiles = null;
/** the list of potential plugins to be used */
private Argument plugin_arg = null;
/** holds all the available options for the src-replacing script */
private ScriptOptions options = null;
/** the pane containing the options */
private JPanel options_pane = null;
/** the error message if any */
private StringBuffer error_message = null;
/** whether we were successful or not */
private boolean successful;
/** The command output of a successful execution of the replace script
* containing the generated tailname of the replacement file */
private String successfulOutput;
public ReplaceSrcDocWithHtmlPrompt(File[] source_files) {
super(Gatherer.g_man, true);
this.self = this;
this.srcdoc_files = source_files;
failedFiles = new java.util.Vector(source_files.length); // number of failures will never be more than num source docs
// check that we actually have a src doc file which can be replaced with its GS3-generated html
// since all the files here have the same extension, the first file can be used to work out
// the necessary plugin
ArrayList replacer_plugins = CollectionDesignManager.plugin_manager.getSrcReplacerPlugins(source_files[0]);
if (replacer_plugins.size() == 0) {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("ReplaceSrcWithHTMLPrompt.NotSrcReplaceable"), Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"), JOptionPane.ERROR_MESSAGE);
return;
}
plugin_arg = createPluginArgument(replacer_plugins);
setJMenuBar(new SimpleMenuBar("replacingSourceDoc"));
setSize(SIZE);
setTitle(Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"));
// set up the script options
// we have empty initial values
String dom_string = "\n";
Document doc = XMLTools.parseXML(new StringReader(dom_string));
options = new ScriptOptions(doc.getDocumentElement(), "replace_srcdoc_with_html.pl");
// Creation
JPanel content_pane = (JPanel) getContentPane();
content_pane.setOpaque(true);
content_pane.setComponentOrientation(Dictionary.getOrientation());
options_pane = new JPanel();
addScriptOptions(options_pane);
JScrollPane middle_pane = new JScrollPane(options_pane);
middle_pane.setComponentOrientation(Dictionary.getOrientation());
JTextArea instructions_area = new JTextArea(Dictionary.get("ReplaceSrcWithHTMLPrompt.Instructions"));
instructions_area.setComponentOrientation(Dictionary.getOrientation());
instructions_area.setEditable(false);
instructions_area.setLineWrap(true);
instructions_area.setRows(5);
instructions_area.setWrapStyleWord(true);
JPanel button_pane = new JPanel();
button_pane.setComponentOrientation(Dictionary.getOrientation());
JButton srcreplace_button = new GLIButton(Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc"), Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc_Tooltip"));
JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
// Connection
cancel_button.addActionListener(new CancelListener());
srcreplace_button.addActionListener(new SrcReplaceListener());
// Layout
button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
button_pane.setLayout(new GridLayout(1,2));
button_pane.add(srcreplace_button);
button_pane.add(cancel_button);
content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
content_pane.setLayout(new BorderLayout());
content_pane.add(instructions_area, BorderLayout.NORTH);
content_pane.add(middle_pane, BorderLayout.CENTER);
content_pane.add(button_pane, BorderLayout.SOUTH);
// Final dialog setup & positioning.
Dimension screen_size = Configuration.screen_size;
setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
setVisible(true);
}
public void destroy()
{
}
/** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell.
* @param event A GShellEvent that contains, amoung other things, the message.
*/
public synchronized void message(GShellEvent event) {
String message = event.getMessage();
if (message.startsWith("replace_srcdoc_with_html.pl>")) {
message = message.substring(28); // length of "replace_srcdoc_with_html.pl>"?
error_message.append(message);
error_message.append("\n");
}
}
/** All implementation of GShellListener must include this method so the listener can be informed when a GShell begins its task. Implementation side-effect, not actually used.
* @param event A GShellEvent that contains details of the initial state of the GShell before task comencement.
*/
public synchronized void processBegun(GShellEvent event) {
// We don't care.
}
/** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task.
* @param event A GShellEvent that contains details of the final state of the GShell after task completion.
*/
public synchronized void processComplete(GShellEvent event) {
successful = false;
if(event.getStatus() == GShell.OK) {
successful = true;
GShell process = (GShell)event.getSource();
successfulOutput = process.getCommandOutput();
process.resetCommandOutput();
}
}
private Argument createPluginArgument(ArrayList plugin_list) {
Argument arg = new Argument();
arg.setName("plugin");
arg.setDescription(Dictionary.get("ReplaceSrcWithHTMLPrompt.Plugin"));
arg.setRequired(true);
arg.setType(Argument.ENUM);
for (int i=0; i 0 ? failedFiles.get(0).toString() : "";
for(int i = 1; i < failedFiles.size(); i++) {
failedFilenames = failedFilenames + ", " + failedFiles.get(i);
}
String label = Dictionary.get("ReplaceSrcWithHTMLPrompt.Failed_ReplaceSrc", failedFilenames);//srcdoc_file.getName());
SimpleResultDialog result_dialog = new SimpleResultDialog(title, label, message);
result_dialog.setVisible(true); // Blocks
result_dialog.dispose();
result_dialog = null;
}
}
private class CancelListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
self.dispose();
}
}
private class SrcReplaceListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
Gatherer.g_man.wait(true);
// update the options
updateScriptOptions();
self.dispose();
(new ReplaceSrcDocWithHtmlTask()).start();
}
}
private class ReplaceSrcDocWithHtmlTask
extends Thread
{
public ReplaceSrcDocWithHtmlTask()
{
}
public void run()
{
int exit_value = 0;
String errMsg = "";
// We're going to try replacing all selected documents and then
// display errormessages
// first run the replace process for all src files, and accumulate error exit values (0 means it's fine)
for(int i = 0; i < srcdoc_files.length; i++) {
int exit_value_this_time = replaceSrcDoc(i);
exit_value += exit_value_this_time; // if all files successfully replaced, exit_value will stay at 0
// accumulate all error and success msgs to display after processing all the files
// that are to be replaced
errMsg += error_message.toString();
error_message = null;
if(exit_value_this_time != 0) {
failedFiles.add(srcdoc_files[i].getName()); // add this file to list of failures
} else {
if (Gatherer.isGsdlRemote) {
//System.err.println("*****ReplaceSrcDocWithHtmlPrompt.java - run() - gsdl remote case");
// Conversion may have renamed the file by URL- or base64-encoding it.
// The new replacement file's tailname is the last line of the script output.
String[] lines = successfulOutput.split("\n");
String suffixlessFilename = lines[lines.length-1];
String htmlFile = suffixlessFilename+".html";
// Delete the local copy of the old source document file on the client side
// (it's already been replaced on the server side), and download the updated
// (html) file and any directory containing associated files
Utility.delete(srcdoc_files[i]); // remove the local copy of src doc
// download the generated html file from the server side to put it
// into the import directory on the client side
Gatherer.remoteGreenstoneServer.downloadCollectionFile(
CollectionManager.getLoadedCollectionName(),
new File(srcdoc_files[i].getParentFile(), htmlFile));
// download any assoc folder which is srcfilename+"_files"
File assoc_folder = new File(srcdoc_files[i].getParentFile(), suffixlessFilename+"_files");
// If an associated_folder by such a name exists, download it
if(Gatherer.remoteGreenstoneServer.exists(CollectionManager.getLoadedCollectionName(), assoc_folder)) {
Gatherer.remoteGreenstoneServer.downloadCollectionFile(
CollectionManager.getLoadedCollectionName(), assoc_folder);
}
}
// Whether remote or local case, need to refressh the GLI filemanager system to show
// what files are in the current collection space
Gatherer.g_man.refreshCollectionTree(DragTree.COLLECTION_CONTENTS_CHANGED); // refreshes coll's content view
Gatherer.g_man.wait(false);
}
} // end for loop
// Display error messages now that we finished processing the multiple files
if(exit_value != 0) {
resultPrompt(false, errMsg);
} else {
resultPrompt(true, errMsg);
}
} // end run method
} //end Task class
}