source: gli/trunk/src/org/greenstone/gatherer/gui/ReplaceSrcDocWithHtmlPrompt.java@ 18397

Last change on this file since 18397 was 18397, checked in by ak19, 15 years ago

Changed to work with the tail filename (of the replacement file) returned by script replace_srcdoc_with_html.pl. The file by this new name is now downloaded.

File size: 16.6 KB
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: Anupama Krishnan, Greenstone Digital Library, University of Waikato
9 * Code based entirely on Katherine Don's ExplodeMetadataDatabasePrompt.java
10 * (part of the Greenstone Digital Library)
11 *
12 * Copyright (C) 2008 Greenstone Digital Library Project
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *########################################################################
28 */
29package org.greenstone.gatherer.gui;
30
31import java.awt.*;
32import java.awt.event.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import javax.swing.text.*;
36import java.io.*;
37import java.util.ArrayList;
38
39import org.w3c.dom.Document;
40
41import org.greenstone.gatherer.Dictionary;
42import org.greenstone.gatherer.Configuration;
43import org.greenstone.gatherer.Gatherer;
44import org.greenstone.gatherer.cdm.Argument;
45import org.greenstone.gatherer.cdm.ArgumentControl;
46import org.greenstone.gatherer.cdm.CollectionDesignManager;
47import org.greenstone.gatherer.cdm.Plugin;
48import org.greenstone.gatherer.collection.CollectionManager;
49import org.greenstone.gatherer.collection.ScriptOptions;
50import org.greenstone.gatherer.collection.Collection;
51import org.greenstone.gatherer.greenstone.LocalGreenstone;
52import org.greenstone.gatherer.gui.tree.DragTree;
53import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
54import org.greenstone.gatherer.shell.GShell;
55import org.greenstone.gatherer.shell.GShellEvent;
56import org.greenstone.gatherer.shell.GShellListener;
57import org.greenstone.gatherer.util.Utility;
58import org.greenstone.gatherer.util.XMLTools;
59
60public class ReplaceSrcDocWithHtmlPrompt
61 extends ModalDialog
62 implements GShellListener
63{
64 /** The size of this new collection dialog box. */
65 static private Dimension SIZE = new Dimension(675, 250);
66 private JDialog self;
67
68 /** the source document files we wil be replacing with their GS3-generated html equivalent */
69 private File[] srcdoc_files = null;
70 /** the names of the srcdoc_files that could not be replaced with their GS3-generated html equivalent */
71 private java.util.Vector failedFiles = null;
72
73 /** the list of potential plugins to be used */
74 private Argument plugin_arg = null;
75 /** holds all the available options for the src-replacing script */
76 private ScriptOptions options = null;
77 /** the pane containing the options */
78 private JPanel options_pane = null;
79 /** the error message if any */
80 private StringBuffer error_message = null;
81 /** whether we were successful or not */
82 private boolean successful;
83 /** The command output of a successful execution of the replace script
84 * containing the generated tailname of the replacement file */
85 private String successfulOutput;
86
87 public ReplaceSrcDocWithHtmlPrompt(File[] source_files) {
88 super(Gatherer.g_man, true);
89 this.self = this;
90 this.srcdoc_files = source_files;
91 failedFiles = new java.util.Vector(source_files.length); // number of failures will never be more than num source docs
92
93 // check that we actually have a src doc file which can be replaced with its GS3-generated html
94 // since all the files here have the same extension, the first file can be used to work out
95 // the necessary plugin
96 ArrayList replacer_plugins = CollectionDesignManager.plugin_manager.getSrcReplacerPlugins(source_files[0]);
97 if (replacer_plugins.size() == 0) {
98 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("ReplaceSrcWithHTMLPrompt.NotSrcReplaceable"), Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"), JOptionPane.ERROR_MESSAGE);
99 return;
100 }
101 plugin_arg = createPluginArgument(replacer_plugins);
102 setJMenuBar(new SimpleMenuBar("replacingSourceDoc"));
103 setSize(SIZE);
104 setTitle(Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"));
105
106 // set up the script options
107 // we have empty initial values
108 String dom_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Options/>";
109 Document doc = XMLTools.parseXML(new StringReader(dom_string));
110 options = new ScriptOptions(doc.getDocumentElement(), "replace_srcdoc_with_html.pl");
111
112 // Creation
113 JPanel content_pane = (JPanel) getContentPane();
114 content_pane.setOpaque(true);
115
116 options_pane = new JPanel();
117 addScriptOptions(options_pane);
118 JScrollPane middle_pane = new JScrollPane(options_pane);
119
120 JTextArea instructions_area = new JTextArea(Dictionary.get("ReplaceSrcWithHTMLPrompt.Instructions"));
121 instructions_area.setEditable(false);
122 instructions_area.setLineWrap(true);
123 instructions_area.setRows(5);
124 instructions_area.setWrapStyleWord(true);
125
126 JPanel button_pane = new JPanel();
127 JButton srcreplace_button = new GLIButton(Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc"), Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc_Tooltip"));
128 JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
129
130 // Connection
131 cancel_button.addActionListener(new CancelListener());
132 srcreplace_button.addActionListener(new SrcReplaceListener());
133
134 // Layout
135
136 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
137 button_pane.setLayout(new GridLayout(1,2));
138 button_pane.add(srcreplace_button);
139 button_pane.add(cancel_button);
140
141 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
142 content_pane.setLayout(new BorderLayout());
143 content_pane.add(instructions_area, BorderLayout.NORTH);
144 content_pane.add(middle_pane, BorderLayout.CENTER);
145 content_pane.add(button_pane, BorderLayout.SOUTH);
146
147 // Final dialog setup & positioning.
148 Dimension screen_size = Configuration.screen_size;
149 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
150 setVisible(true);
151 }
152
153 public void destroy()
154 {
155
156 }
157
158 /** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell.
159 * @param event A <strong>GShellEvent</strong> that contains, amoung other things, the message.
160 */
161 public synchronized void message(GShellEvent event) {
162 String message = event.getMessage();
163 if (message.startsWith("replace_srcdoc_with_html.pl>")) {
164 message = message.substring(28); // length of "replace_srcdoc_with_html.pl>"?
165 error_message.append(message);
166 error_message.append("\n");
167 }
168 }
169
170 /** 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.
171 * @param event A <strong>GShellEvent</strong> that contains details of the initial state of the <strong>GShell</strong> before task comencement.
172 */
173 public synchronized void processBegun(GShellEvent event) {
174 // We don't care.
175 }
176
177 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task.
178 * @param event A <strong>GShellEvent</strong> that contains details of the final state of the <strong>GShell</strong> after task completion.
179 */
180 public synchronized void processComplete(GShellEvent event) {
181 successful = false;
182 if(event.getStatus() == GShell.OK) {
183 successful = true;
184 GShell process = (GShell)event.getSource();
185 successfulOutput = process.getCommandOutput();
186 process.resetCommandOutput();
187 }
188 }
189
190 private Argument createPluginArgument(ArrayList plugin_list) {
191 Argument arg = new Argument();
192 arg.setName("plugin");
193 arg.setDescription(Dictionary.get("ReplaceSrcWithHTMLPrompt.Plugin"));
194 arg.setRequired(true);
195 arg.setType(Argument.ENUM);
196 for (int i=0; i<plugin_list.size(); i++) {
197 Plugin p = (Plugin)plugin_list.get(i);
198 arg.addOption(p.getName(), p.getName());
199 }
200 return arg;
201 }
202 private void addScriptOptions(JPanel options_pane) {
203
204 options_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
205 options_pane.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
206 options_pane.setLayout(new BoxLayout(options_pane, BoxLayout.Y_AXIS));
207
208 int current_mode = Configuration.getMode();
209 int total_argument_count = options.getArgumentCount();
210
211 // first we add the plugin arg
212 ArgumentControl argument_control = new ArgumentControl(plugin_arg, true, null);
213 argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
214 options_pane.add((JComponent)argument_control);
215 for(int i = 0; i < total_argument_count; i++) {
216 // Retrieve the argument so we know how to format the control.
217 Argument argument = options.getArgument(i);
218 if(!argument.isHiddenGLI() && argument.getModeLevel() <= current_mode) {
219 // by default, all args are disabled, and no value
220 argument_control = new ArgumentControl(argument, false, null);
221
222 // make sure they are coloured the way we want - this is not the standard arg control coloring
223 argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
224 options_pane.add((JComponent)argument_control);
225 }
226 }
227 }
228
229 private void updateScriptOptions() {
230 for(int i = 0; i < options_pane.getComponentCount(); i++) {
231 Component component = options_pane.getComponent(i);
232 if(component instanceof ArgumentControl) {
233 ArgumentControl ac = (ArgumentControl)component;
234 String name = ac.getArgumentName();
235 String value = ac.getValue();
236 boolean enabled = ac.isEnabled();
237 if (!enabled && value==null) {
238 // flag type, remove from options altogether
239 options.removeValue(name);
240 } else {
241 if (value.equals("")) {
242 // if the value is empty, we don't want it to be passed to the script
243 options.setValue(name, false, value);
244 } else {
245 options.setValue(name, enabled, value);
246 }
247 }
248
249 }
250 }
251 }
252
253 private int replaceSrcDoc(int fileNum)
254 {
255 // Generate the replace_srcdoc_with_html.pl command
256 ArrayList command_parts_list = new ArrayList();
257 if (Utility.isWindows() && (!Gatherer.isGsdlRemote)) {
258 command_parts_list.add(Configuration.perl_path);
259 command_parts_list.add("-S");
260 }
261 command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "replace_srcdoc_with_html.pl");
262
263 // Add in all the options from the user
264 String[] src_replace_options = options.getValues();
265 for (int i = 0; i < src_replace_options.length; i++) {
266 command_parts_list.add(src_replace_options[i]);
267 }
268
269 // Local case
270 if (!Gatherer.isGsdlRemote) {
271 // Add in the filename
272 command_parts_list.add(this.srcdoc_files[fileNum].getPath());
273 }
274 // Remote case
275 else {
276 // Add in the filename, relative to the collection directory
277 String collection_name = CollectionManager.getLoadedCollectionName();
278 String collection_directory_path = CollectionManager.getCollectionDirectoryPath(collection_name);
279 String srcdoc_file_relative_path = Gatherer.remoteGreenstoneServer.getPathRelativeToDirectory(
280 this.srcdoc_files[fileNum], collection_directory_path); // preserves spaces in filename
281 command_parts_list.add("-file");
282 command_parts_list.add(srcdoc_file_relative_path);
283
284 // When running remotely we also need the collection name as the last argument
285 command_parts_list.add(collection_name);
286 }
287
288 // Run the replace_srcdoc_with_html.pl command
289 String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
290 this.error_message = new StringBuffer();
291
292 GShell process = new GShell(command_parts, GShell.SRCREPLACE, 3, this, null, GShell.GSHELL_SRCREPLACE);
293 //process.start();
294 process.run();
295
296 if (successful) {
297 return 0;
298 }
299 return 1;
300 }
301
302 private void resultPrompt(boolean success, String message)
303 {
304 if (success) {
305 // !!! TO DO: Get replace_srcdoc_with_html.pl strings translated and use SimpleResultDialog below
306 JOptionPane.showMessageDialog(null, Dictionary.get("ReplaceSrcWithHTMLPrompt.Successful_ReplaceSrc"), Dictionary.get("ReplaceSrcWithHTMLPrompt.Successful_Title"), JOptionPane.INFORMATION_MESSAGE);
307 }
308 else {
309 String title = Dictionary.get("ReplaceSrcWithHTMLPrompt.Failed_Title");
310
311 // comma separated list of all the names of the files that could not be replaced
312 String failedFilenames = failedFiles.size() > 0 ? failedFiles.get(0).toString() : "";
313 for(int i = 1; i < failedFiles.size(); i++) {
314 failedFilenames = failedFilenames + ", " + failedFiles.get(i);
315 }
316
317 String label = Dictionary.get("ReplaceSrcWithHTMLPrompt.Failed_ReplaceSrc", failedFilenames);//srcdoc_file.getName());
318 SimpleResultDialog result_dialog = new SimpleResultDialog(title, label, message);
319 result_dialog.setVisible(true); // Blocks
320 result_dialog.dispose();
321 result_dialog = null;
322 }
323 }
324
325 private class CancelListener
326 implements ActionListener {
327 public void actionPerformed(ActionEvent event) {
328 self.dispose();
329 }
330 }
331
332 private class SrcReplaceListener
333 implements ActionListener {
334
335 public void actionPerformed(ActionEvent event) {
336 Gatherer.g_man.wait(true);
337 // update the options
338 updateScriptOptions();
339 self.dispose();
340 (new ReplaceSrcDocWithHtmlTask()).start();
341 }
342 }
343
344
345 private class ReplaceSrcDocWithHtmlTask
346 extends Thread
347 {
348 public ReplaceSrcDocWithHtmlTask()
349 {
350 }
351
352 public void run()
353 {
354 int exit_value = 0;
355 String errMsg = "";
356
357 // We're going to try replacing all selected documents and then
358 // display errormessages
359 // first run the replace process for all src files, and accumulate error exit values (0 means it's fine)
360 for(int i = 0; i < srcdoc_files.length; i++) {
361 int exit_value_this_time = replaceSrcDoc(i);
362 exit_value += exit_value_this_time; // if all files successfully replaced, exit_value will stay at 0
363
364 // accumulate all error and success msgs to display after processing all the files
365 // that are to be replaced
366 errMsg += error_message.toString();
367 error_message = null;
368
369 if(exit_value_this_time != 0) {
370 failedFiles.add(srcdoc_files[i].getName()); // add this file to list of failures
371 } else {
372 if (Gatherer.isGsdlRemote) {
373 //System.err.println("*****ReplaceSrcDocWithHtmlPrompt.java - run() - gsdl remote case");
374
375 // Conversion may have renamed the file by URL- or base64-encoding it.
376 // The new replacement file's tailname is the last line of the script output.
377 String[] lines = successfulOutput.split("\n");
378 String suffixlessFilename = lines[lines.length-1];
379 String htmlFile = suffixlessFilename+".html";
380
381 // Delete the local copy of the old source document file on the client side
382 // (it's already been replaced on the server side), and download the updated
383 // (html) file and any directory containing associated files
384 Utility.delete(srcdoc_files[i]); // remove the local copy of src doc
385
386 // download the generated html file from the server side to put it
387 // into the import directory on the client side
388 Gatherer.remoteGreenstoneServer.downloadCollectionFile(
389 CollectionManager.getLoadedCollectionName(),
390 new File(srcdoc_files[i].getParentFile(), htmlFile));
391
392 // download any assoc folder which is srcfilename+"_files"
393 File assoc_folder = new File(srcdoc_files[i].getParentFile(), suffixlessFilename+"_files");
394 // If an associated_folder by such a name exists, download it
395 if(Gatherer.remoteGreenstoneServer.exists(CollectionManager.getLoadedCollectionName(), assoc_folder)) {
396 Gatherer.remoteGreenstoneServer.downloadCollectionFile(
397 CollectionManager.getLoadedCollectionName(), assoc_folder);
398 }
399 }
400 // Whether remote or local case, need to refressh the GLI filemanager system to show
401 // what files are in the current collection space
402 Gatherer.g_man.refreshCollectionTree(DragTree.COLLECTION_CONTENTS_CHANGED); // refreshes coll's content view
403 Gatherer.g_man.wait(false);
404 }
405 } // end for loop
406
407 // Display error messages now that we finished processing the multiple files
408 if(exit_value != 0) {
409 resultPrompt(false, errMsg);
410 } else {
411 resultPrompt(true, errMsg);
412 }
413 } // end run method
414
415 } //end Task class
416}
Note: See TracBrowser for help on using the repository browser.