source: main/trunk/gli/src/org/greenstone/gatherer/gui/ConfigFileEditor.java@ 30854

Last change on this file since 30854 was 30854, checked in by ak19, 8 years ago

As per Kathy's suggestion, after editing the collectionConfig file with the ConfigFileEditor, need to close and reopen the collection in order for the changes to take effect.

File size: 9.9 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 * Copyright (C) 1999 New Zealand Digital Library Project
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *########################################################################
24 */
25
26package org.greenstone.gatherer.gui;
27
28import org.greenstone.gatherer.Configuration;
29import org.greenstone.gatherer.Dictionary;
30import org.greenstone.gatherer.Gatherer;
31import org.greenstone.gatherer.cdm.CollectionConfigXMLReadWrite;
32import org.greenstone.gatherer.util.Codec;
33import org.greenstone.gatherer.util.InputStreamGobbler;
34import org.greenstone.gatherer.util.OutputStreamGobbler;
35import org.greenstone.gatherer.util.StaticStrings;
36import org.greenstone.gatherer.util.Utility;
37import org.greenstone.gatherer.util.XMLTools;
38
39import org.w3c.dom.*;
40
41
42import java.io.File;
43import java.io.IOException;
44
45import java.awt.*;
46import java.awt.event.*;
47import java.util.*;
48import javax.swing.*;
49import javax.swing.border.*;
50import javax.swing.event.*;
51
52
53public class ConfigFileEditor extends ModalDialog
54 implements ActionListener, DocumentListener
55{
56 public final File config_file;
57
58 private GLIButton cancel_button = null;
59 private GLIButton save_button = null;
60 private NumberedJTextArea editor = null;
61 private JTextArea editor_msgarea;
62
63 //private final String DEFAULT_PROCESSING_INSTRUCTION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
64
65 private static final Dimension SIZE = new Dimension(640,480);
66
67 public ConfigFileEditor() {
68
69 String collection_folder_path = Gatherer.getCollectDirectoryPath();
70 String collectionName = Gatherer.c_man.getCollection().getName(); // we won't be in this constructor if collection is null.
71 this.config_file = new File(collection_folder_path + File.separator + collectionName, Utility.CONFIG_GS3_FILE); // col config editing is a GS3 feature
72
73
74 // Most of the validation_msg_panel code is from Format4gs3Manager.java
75 JPanel validation_msg_panel = new JPanel();
76 JLabel validation_label = new JLabel(Dictionary.get("CDM.FormatManager.MessageBox"));
77 validation_label.setBorder(new EmptyBorder(10,10,10,10)); // add some margin
78 editor_msgarea = new JTextArea();
79
80 editor_msgarea.setCaretPosition(0);
81 editor_msgarea.setLineWrap(true);
82 editor_msgarea.setRows(3);
83 editor_msgarea.setWrapStyleWord(false);
84 editor_msgarea.setEditable(false);
85 editor_msgarea.setToolTipText(Dictionary.get("CDM.FormatManager.MessageBox_Tooltip"));
86 validation_msg_panel.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
87 validation_msg_panel.setLayout(new BorderLayout(5, 0));
88 validation_msg_panel.add(validation_label, BorderLayout.WEST);
89 validation_msg_panel.add(new JScrollPane(editor_msgarea), BorderLayout.CENTER);
90
91 // the all important XML editor
92 editor = new NumberedJTextArea(Dictionary.get("ConfigFileEditor.Tooltip"));
93 editor.getDocument().addDocumentListener(this);
94
95 save_button = new GLIButton(Dictionary.get("General.Save"), Dictionary.get("ConfigFileEditor.Save_Tooltip"));
96 cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("ConfigFileEditor.Cancel_Tooltip")); // tooltip is the same
97 cancel_button.addActionListener(this);
98 save_button.addActionListener(this);
99
100 // LAYOUT
101 JPanel button_panel = new JPanel(new FlowLayout());
102 button_panel.setComponentOrientation(Dictionary.getOrientation());
103 button_panel.add(editor.undoButton);
104 button_panel.add(editor.redoButton);
105 button_panel.add(cancel_button);
106 button_panel.add(save_button);
107
108 JPanel content_pane = (JPanel) getContentPane();
109 content_pane.setComponentOrientation(Dictionary.getOrientation());
110 content_pane.setLayout(new BorderLayout());
111 content_pane.add(validation_msg_panel, BorderLayout.NORTH);
112 content_pane.add(new JScrollPane(editor), BorderLayout.CENTER); // make editor scrollable
113 content_pane.add(button_panel, BorderLayout.SOUTH);
114
115
116 // NOW WE CAN PREPARE THE ACTUAL CONTENT TO GO INTO THE XML EDITOR TEXTAREA
117 Document xmlDoc = null;
118 xmlDoc = XMLTools.parseXMLFile(config_file);
119
120 if(xmlDoc != null) {
121
122 // Save the collectionConfig.xml before loading it.
123 String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
124 XMLTools.writeXMLFile(this.config_file, xmlDoc, nonEscapingTagNames); //prepends proc instruction
125
126 // now load the contents
127 editor_msgarea.setBackground(Color.white);
128 StringBuffer sb = new StringBuffer();
129 XMLTools.xmlNodeToString(sb, xmlDoc.getDocumentElement(), true, " ", 0);
130 editor.setText(sb.toString());
131 //editor.setText(elementToString(xmlDoc.getDocumentElement(), true)); // reading in file this way adds processing instruction, which the parser doesn't like.
132
133 } else { // parsing failed
134 // so read in file as text and display as text and show the validation box in red
135
136 // Won't re-save file that is already invalid before it's even been edited through this Editor
137 System.err.println("*** Warning: Parsing error in file " + config_file + ".");
138 System.err.println("*** Not saving ahead of editing.");
139
140 String xml_str = Utility.readFile(config_file);
141
142 // re-parse to get error msg to display in validation field
143
144 // but first get rid of the preprocessing instruction, as this will fail parsing
145 String processingInstruction = getProcessingInstruction(xml_str);
146 xml_str = xml_str.replace(processingInstruction, "").trim(); // also trim newline at start
147
148 if(!xml_str.equals("")) {
149
150 String msg = XMLTools.parse(xml_str); // re-parse
151 editor_msgarea.setBackground(Color.red);
152 editor_msgarea.setText(msg); // display the parsing error
153 save_button.setEnabled(false);
154
155 editor.setText(xml_str); // display the xml contents with error and all
156
157 } else {
158 editor.setText("");
159 editor_msgarea.setText("Empty collection config file");
160 }
161 }
162
163
164 // Final dialog setup & positioning.
165 setDefaultCloseOperation(DISPOSE_ON_CLOSE); // get rid of this dialog when it's closed (on dispose())
166 getRootPane().setDefaultButton(save_button);
167 Dimension screen_size = Configuration.screen_size;
168 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
169
170 }
171
172 public void actionPerformed(ActionEvent e) {
173
174 if(e.getSource() == cancel_button) {
175 this.dispose(); // get rid of this dialog, we're done
176 }
177 else if(e.getSource() == save_button) {
178 // write out the XML to the collectionConfig.xml file and we're done.
179
180 // already know the xml in the textarea is valid, else the save_button would have been inactive
181 Document xml_file_doc = XMLTools.getDOM(editor.getText());
182 // This code from FormatConversionDialog.dispose()
183 // saves the XML, prepending the processing instruction (<?xml ... ?>)
184 String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
185 XMLTools.writeXMLFile(this.config_file, xml_file_doc, nonEscapingTagNames);
186
187 this.dispose(); // get rid of this dialog, we're done
188
189 // close and reopen the collection in GLI
190 String current_collection_filepath = Gatherer.c_man.getCollection().getCollectionPath();
191 Gatherer.c_man.closeCollection();
192 Gatherer.c_man.loadCollection(current_collection_filepath);
193 }
194 }
195
196
197
198 // This method returns a proper processing instruction (starts with <?xml and ends with ?>)
199 // else the empty string is returned
200 public String getProcessingInstruction(String xmlStr) {
201 String processingInstruction = "";
202
203 xmlStr = xmlStr.trim();
204 if(xmlStr.startsWith("<?xml")) {
205 int endIndex = xmlStr.indexOf("?>"); // end of processing instruction
206
207 if(endIndex != -1) {
208 endIndex += 2;
209 processingInstruction = xmlStr.substring(0, endIndex);
210 }
211 }
212 return processingInstruction;
213 }
214
215
216 // THE FOLLOWING FUNCTIONS ARE LARGELY FROM Format4gs3Manager.java.EditorListener
217 public void changedUpdate(DocumentEvent e)
218 {
219 update();
220 }
221
222 public void insertUpdate(DocumentEvent e)
223 {
224 update();
225 updateUndo("insert");
226
227 }
228
229 public void removeUpdate(DocumentEvent e)
230 {
231 update();
232 updateUndo("remove");
233
234 }
235
236 private void updateUndo(String from)
237 {
238
239 editor.undoButton.setEnabled(true);
240 }
241
242 public void update()
243 {
244
245 String xml_str = editor.getText();
246
247 // Processing instructions "<?xml...?>" are no longer displayed in the editor (but
248 // they are written out to the file on save) so we don't need to deal with them here.
249
250 // can't parse with processing instruction <?xml...?>, so remove that
251 ///String processingInstruction = getProcessingInstruction(xml_str);
252 ///xml_str = xml_str.replace(processingInstruction, "");
253 // now can parse the XML portion without the processing instruction,
254 // while the original XML remains unchanged in the editor area
255 // If the processing instruction was incomplete, then xml_str would still
256 // include the incomplete processing instruction, and parsing below will catch the error.
257
258 String msg = XMLTools.parse(xml_str);
259 editor_msgarea.setText(msg);
260
261 if (msg.startsWith(XMLTools.WELLFORMED))
262 {
263 editor_msgarea.setBackground(Color.white);
264 save_button.setEnabled(true);
265 }
266 else
267 {
268 editor_msgarea.setBackground(Color.red);
269 save_button.setEnabled(false);
270 }
271 }
272
273}
Note: See TracBrowser for help on using the repository browser.