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

Last change on this file since 15163 was 15163, checked in by ak19, 16 years ago

method run() modified to work properly in those cases where GSDL is remote

File size: 16.4 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
84
85 public ReplaceSrcDocWithHtmlPrompt(File[] source_files) {
86 super(Gatherer.g_man, true);
87 this.self = this;
88 this.srcdoc_files = source_files;
89 failedFiles = new java.util.Vector(source_files.length); // number of failures will never be more than num source docs
90
91 // check that we actually have a src doc file which can be replaced with its GS3-generated html
92 // since all the files here have the same extension, the first file can be used to work out
93 // the necessary plugin
94 ArrayList replacer_plugins = CollectionDesignManager.plugin_manager.getSrcReplacerPlugins(source_files[0]);
95 if (replacer_plugins.size() == 0) {
96 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("ReplaceSrcWithHTMLPrompt.NotSrcReplaceable"), Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"), JOptionPane.ERROR_MESSAGE);
97 return;
98 }
99 plugin_arg = createPluginArgument(replacer_plugins);
100 setJMenuBar(new SimpleMenuBar("replacingSourceDoc"));
101 setSize(SIZE);
102 setTitle(Dictionary.get("ReplaceSrcWithHTMLPrompt.Title"));
103
104 // set up the script options
105 // we have empty initial values
106 String dom_string = "<Options/>";
107 Document doc = XMLTools.parseXML(new StringReader(dom_string));
108 options = new ScriptOptions(doc.getDocumentElement(), "replace_srcdoc_with_html.pl");
109
110 // Creation
111 JPanel content_pane = (JPanel) getContentPane();
112 content_pane.setOpaque(true);
113
114 options_pane = new JPanel();
115 addScriptOptions(options_pane);
116 JScrollPane middle_pane = new JScrollPane(options_pane);
117
118 JTextArea instructions_area = new JTextArea(Dictionary.get("ReplaceSrcWithHTMLPrompt.Instructions"));
119 instructions_area.setEditable(false);
120 instructions_area.setLineWrap(true);
121 instructions_area.setRows(5);
122 instructions_area.setWrapStyleWord(true);
123
124 JPanel button_pane = new JPanel();
125 JButton srcreplace_button = new GLIButton(Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc"), Dictionary.get("ReplaceSrcWithHTMLPrompt.ReplaceSrc_Tooltip"));
126 JButton cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));
127
128 // Connection
129 cancel_button.addActionListener(new CancelListener());
130 srcreplace_button.addActionListener(new SrcReplaceListener());
131
132 // Layout
133
134 button_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
135 button_pane.setLayout(new GridLayout(1,2));
136 button_pane.add(srcreplace_button);
137 button_pane.add(cancel_button);
138
139 content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
140 content_pane.setLayout(new BorderLayout());
141 content_pane.add(instructions_area, BorderLayout.NORTH);
142 content_pane.add(middle_pane, BorderLayout.CENTER);
143 content_pane.add(button_pane, BorderLayout.SOUTH);
144
145 // Final dialog setup & positioning.
146 Dimension screen_size = Configuration.screen_size;
147 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
148 setVisible(true);
149 }
150
151 public void destroy()
152 {
153
154 }
155
156 /** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell.
157 * @param event A <strong>GShellEvent</strong> that contains, amoung other things, the message.
158 */
159 public synchronized void message(GShellEvent event) {
160 String message = event.getMessage();
161 if (message.startsWith("replace_srcdoc_with_html.pl>")) {
162 message = message.substring(28); // length of "replace_srcdoc_with_html.pl>"?
163 error_message.append(message);
164 error_message.append("\n");
165 }
166 }
167
168 /** 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.
169 * @param event A <strong>GShellEvent</strong> that contains details of the initial state of the <strong>GShell</strong> before task comencement.
170 */
171 public synchronized void processBegun(GShellEvent event) {
172 // We don't care.
173 }
174
175 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task.
176 * @param event A <strong>GShellEvent</strong> that contains details of the final state of the <strong>GShell</strong> after task completion.
177 */
178 public synchronized void processComplete(GShellEvent event) {
179 successful = false;
180 if(event.getStatus() == GShell.OK) {
181 successful = true;
182 }
183 }
184
185 private Argument createPluginArgument(ArrayList plugin_list) {
186 Argument arg = new Argument();
187 arg.setName("plugin");
188 arg.setDescription(Dictionary.get("ReplaceSrcWithHTMLPrompt.Plugin"));
189 arg.setRequired(true);
190 arg.setType(Argument.ENUM);
191 for (int i=0; i<plugin_list.size(); i++) {
192 Plugin p = (Plugin)plugin_list.get(i);
193 arg.addOption(p.getName(), p.getName());
194 }
195 return arg;
196 }
197 private void addScriptOptions(JPanel options_pane) {
198
199 options_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
200 options_pane.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
201 options_pane.setLayout(new BoxLayout(options_pane, BoxLayout.Y_AXIS));
202
203 int current_mode = Configuration.getMode();
204 int total_argument_count = options.getArgumentCount();
205
206 // first we add the plugin arg
207 ArgumentControl argument_control = new ArgumentControl(plugin_arg, true, null);
208 argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
209 options_pane.add((JComponent)argument_control);
210 for(int i = 0; i < total_argument_count; i++) {
211 // Retrieve the argument so we know how to format the control.
212 Argument argument = options.getArgument(i);
213 if(!argument.isHiddenGLI() && argument.getModeLevel() <= current_mode) {
214 // by default, all args are disabled, and no value
215 argument_control = new ArgumentControl(argument, false, null);
216
217 // make sure they are coloured the way we want - this is not the standard arg control coloring
218 argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
219 options_pane.add((JComponent)argument_control);
220 }
221 }
222 }
223
224 private void updateScriptOptions() {
225 for(int i = 0; i < options_pane.getComponentCount(); i++) {
226 Component component = options_pane.getComponent(i);
227 if(component instanceof ArgumentControl) {
228 ArgumentControl ac = (ArgumentControl)component;
229 String name = ac.getArgumentName();
230 String value = ac.getValue();
231 boolean enabled = ac.isEnabled();
232 if (!enabled && value==null) {
233 // flag type, remove from options altogether
234 options.removeValue(name);
235 } else {
236 if (value.equals("")) {
237 // if the value is empty, we don't want it to be passed to the script
238 options.setValue(name, false, value);
239 } else {
240 options.setValue(name, enabled, value);
241 }
242 }
243
244 }
245 }
246 }
247
248 private int replaceSrcDoc(int fileNum)
249 {
250 // Generate the replace_srcdoc_with_html.pl command
251 ArrayList command_parts_list = new ArrayList();
252 if (Utility.isWindows() && (!Gatherer.isGsdlRemote)) {
253 command_parts_list.add(Configuration.perl_path);
254 command_parts_list.add("-S");
255 }
256 command_parts_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "replace_srcdoc_with_html.pl");
257
258 // Add in all the options from the user
259 String[] src_replace_options = options.getValues();
260 for (int i = 0; i < src_replace_options.length; i++) {
261 command_parts_list.add(src_replace_options[i]);
262 }
263
264 // Local case
265 if (!Gatherer.isGsdlRemote) {
266 // Add in the filename
267 command_parts_list.add(this.srcdoc_files[fileNum].getPath());
268 }
269 // Remote case
270 else {
271 // Add in the filename, relative to the collection directory
272 String collection_name = CollectionManager.getLoadedCollectionName();
273 String collection_directory_path = CollectionManager.getCollectionDirectoryPath(collection_name);
274 String srcdoc_file_relative_path = RemoteGreenstoneServer.getPathRelativeToDirectory(
275 this.srcdoc_files[fileNum], collection_directory_path); // preserves spaces in filename
276 command_parts_list.add("-file");
277 command_parts_list.add(srcdoc_file_relative_path);
278
279 // When running remotely we also need the collection name as the last argument
280 command_parts_list.add(collection_name);
281 }
282
283 // Run the replace_srcdoc_with_html.pl command
284 String[] command_parts = (String[]) command_parts_list.toArray(new String[0]);
285 this.error_message = new StringBuffer();
286
287 GShell process = new GShell(command_parts, GShell.SRCREPLACE, 3, this, null, GShell.GSHELL_SRCREPLACE);
288 //process.start();
289 process.run();
290
291 if (successful) {
292 return 0;
293 }
294 return -1;
295 }
296
297 private void resultPrompt(boolean success, String message)
298 {
299 if (success) {
300 // !!! TO DO: Get replace_srcdoc_with_html.pl strings translated and use SimpleResultDialog below
301 JOptionPane.showMessageDialog(null, Dictionary.get("ReplaceSrcWithHTMLPrompt.Successful_ReplaceSrc"), Dictionary.get("ReplaceSrcWithHTMLPrompt.Successful_Title"), JOptionPane.INFORMATION_MESSAGE);
302 }
303 else {
304 String title = Dictionary.get("ReplaceSrcWithHTMLPrompt.Failed_Title");
305
306 // comma separated list of all the names of the files that could not be replaced
307 String failedFilenames = failedFiles.size() > 0 ? failedFiles.get(0).toString() : "";
308 for(int i = 1; i < failedFiles.size(); i++) {
309 failedFilenames = failedFilenames + ", " + failedFiles.get(i);
310 }
311
312 String label = Dictionary.get("ReplaceSrcWithHTMLPrompt.Failed_ReplaceSrc", failedFilenames);//srcdoc_file.getName());
313 SimpleResultDialog result_dialog = new SimpleResultDialog(title, label, message);
314 result_dialog.setVisible(true); // Blocks
315 result_dialog.dispose();
316 result_dialog = null;
317 }
318 }
319
320 private class CancelListener
321 implements ActionListener {
322 public void actionPerformed(ActionEvent event) {
323 self.dispose();
324 }
325 }
326
327 private class SrcReplaceListener
328 implements ActionListener {
329
330 public void actionPerformed(ActionEvent event) {
331 Gatherer.g_man.wait(true);
332 // update the options
333 updateScriptOptions();
334 self.dispose();
335 (new ReplaceSrcDocWithHtmlTask()).start();
336 }
337 }
338
339
340 private class ReplaceSrcDocWithHtmlTask
341 extends Thread
342 {
343 public ReplaceSrcDocWithHtmlTask()
344 {
345 }
346
347 public void run()
348 {
349 int exit_value = 0;
350 String errMsg = "";
351
352 // We're going to try replacing all selected documents and then
353 // display errormessages
354 // first run the replace process for all src files, and accumulate error exit values (0 means it's fine)
355 for(int i = 0; i < srcdoc_files.length; i++) {
356 int exit_value_this_time = replaceSrcDoc(i);
357 exit_value += exit_value_this_time; // if all files successfully replaced, exit_value will stay at 0
358
359 // accumulate all error and success msgs to display after processing all the files
360 // that are to be replaced
361 errMsg += error_message.toString();
362 error_message = null;
363
364 if(exit_value_this_time != 0) {
365 failedFiles.add(srcdoc_files[i].getName()); // add this file to list of failures
366 } else {
367 if (Gatherer.isGsdlRemote) {
368 // Delete the local copy of the old source document file on the client side
369 // (it's already been replaced on the server side), and download the updated
370 // (html) file and any directory containing associated files
371 System.err.println("*****ReplaceSrcDocWithHtmlPrompt.java - run() - gsdl remote case");
372 // not sure what the new file is renamed to, so at present still delete entire
373 // containing directory and get the updated copy of this directory from remote server
374 Utility.delete(srcdoc_files[i]); // remove the local copy of src doc
375
376 // let's get just the filename without the suffix
377 String htmlFile = srcdoc_files[i].getName();
378 int lastperiod = htmlFile.lastIndexOf('.');
379 String suffixlessFilename = htmlFile.substring(0, lastperiod); // cut off suffix
380 htmlFile = suffixlessFilename+".html"; // html filename
381
382 // download the generated html file from the server side to put it
383 // into the import directory on the client side
384 RemoteGreenstoneServer.downloadCollectionFile(
385 CollectionManager.getLoadedCollectionName(),
386 new File(srcdoc_files[i].getParentFile(), htmlFile));
387
388 // download any assoc folder which is srcfilename+"_files"
389 File assoc_folder = new File(srcdoc_files[i].getParentFile(), suffixlessFilename+"_files");
390 // If an associated_folder by such a name exists, download it
391 if(RemoteGreenstoneServer.exists(CollectionManager.getLoadedCollectionName(), assoc_folder)) {
392 RemoteGreenstoneServer.downloadCollectionFile(
393 CollectionManager.getLoadedCollectionName(), assoc_folder);
394 }
395 }
396 // Whether remote or local case, need to refressh the GLI filemanager system to show
397 // what files are in the current collection space
398 Gatherer.g_man.refreshCollectionTree(DragTree.COLLECTION_CONTENTS_CHANGED); // refreshes coll's content view
399 Gatherer.g_man.wait(false);
400 }
401 } // end for loop
402
403 // Display error messages now that we finished processing the multiple files
404 if(exit_value != 0) {
405 resultPrompt(false, errMsg);
406 } else {
407 resultPrompt(true, errMsg);
408 }
409 } // end run method
410
411 } //end Task class
412}
Note: See TracBrowser for help on using the repository browser.