source: trunk/gli/src/org/greenstone/gatherer/file/FileAssociationManager.java@ 6901

Last change on this file since 6901 was 6795, checked in by kjdon, 20 years ago

made the getCommand method return String[] instead of String in case there are spaces in the filename

  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 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: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.file;
28
29import java.io.*;
30import javax.swing.table.*;
31import org.greenstone.gatherer.Dictionary;
32import org.greenstone.gatherer.Gatherer;
33import org.greenstone.gatherer.gui.FileAssociationDialog;
34import org.greenstone.gatherer.gui.PreviewCommandDialog;
35import org.greenstone.gatherer.msm.MSMUtils;
36import org.greenstone.gatherer.util.ExternalProgram;
37import org.greenstone.gatherer.util.StaticStrings;
38import org.greenstone.gatherer.util.Utility;
39import org.greenstone.gatherer.util.WinRegistry;
40import org.w3c.dom.*;
41
42public class FileAssociationManager
43 extends AbstractTableModel {
44 static final public String FILENAME_ARG = "%1";
45 static final private String ESCAPE = "\\\\"; // '\'
46 static final private String ESCAPED_ESCAPE = "\\\\\\\\"; // '\\'
47 static final private String SPACE = " ";
48 static final private String ESCAPED_SPACE = "\\\\ ";
49 private Element associations_element;
50 private File data_file;
51
52 public FileAssociationManager() {
53 // Retrieve the associations_element from the config
54 associations_element = Gatherer.config.getFileAssociations();
55 // Initialize the associations. This involves looking through all current associations searching for those with a command of "".
56 if(associations_element != null) {
57 NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
58 for(int i = 0; i < entries.getLength(); i++) {
59 Element entry = (Element) entries.item(i);
60 String extension = entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
61 String command = MSMUtils.getValue(entry);
62 // If we encounter a command of ""...
63 if(command.length() == 0) {
64 // and if we are on windows, we try to automatically set this command.
65 if(Utility.isWindows()) {
66 // Create a dummy filename with the appropriate extension
67 String dummy_file = "dummy." + extension;
68 command = WinRegistry.openCommand(dummy_file);
69 // If this succeeded add the association.
70 if(command != null) {
71 // Remember to replace the dummy filename with %1
72 command = command.replaceAll(dummy_file, FILENAME_ARG);
73 // Replace the text in this node.
74 MSMUtils.setValue(entry, command);
75 }
76 dummy_file = null;
77 }
78 // and if we are on windows, we default to the open program
79 if(Utility.isMac()) {
80 MSMUtils.setValue(entry, StaticStrings.MAC_OPEN_COMMAND);
81 }
82 }
83 command = null;
84 extension = null;
85 entry = null;
86 }
87 entries = null;
88 }
89 else {
90 Gatherer.println("Didn't parse anything. About to crash.");
91 }
92 }
93
94 public void edit() {
95 FileAssociationDialog dialog = new FileAssociationDialog(this);
96 dialog.display(null);
97 dialog = null;
98 }
99
100 public String getBrowserCommand(String url) {
101 Gatherer.println("Get browser command: " + url);
102 // First off we try to retrieve one from the configuration
103 String command = Gatherer.config.getPreviewCommand();
104 // If that worked, substitute in the url and return
105 if(command != null && command.length() > 0) {
106 command = command.replaceAll("%1", url);
107 Gatherer.println("Result = " + command);
108 return command;
109 }
110 command = null;
111 // Failing that we have a guess at a sensible default
112 if(Utility.isWindows()) {
113 // we use cmd and start
114 if (Utility.isWindows9x()) {
115 command = StaticStrings.WIN_9X_OPEN_COMMAND;//"command.com /c start \""+url+"\"";
116 } else {
117 command = StaticStrings.WIN_OPEN_COMMAND;//"cmd.exe /c start \"\" \""+url+"\"";
118 }
119 } else if (Utility.isMac()) {
120 command = StaticStrings.MAC_OPEN_COMMAND; // "open %1"
121 } else {
122 // we try to look for a browser
123 String [] browsers = new String [] {"mozilla", "netscape"};
124 for (int i=0; i<browsers.length; i++) {
125 if (isAvailable(browsers[i])) {
126 command = browsers[i]+ " %1";
127 break;
128 }
129 }
130 }
131
132 // if we still haven't found something, prompt the user
133 if (command == null) {
134 PreviewCommandDialog dialog = new PreviewCommandDialog();
135 command = dialog.display();
136 dialog.dispose();
137 dialog = null;
138 }
139
140 // Store the result if any
141 if(command != null && !command.equals("")) {
142 Gatherer.config.setPreviewCommand(command);
143 command = command.replaceAll(FILENAME_ARG, url);
144 Gatherer.println("Result = " + command);
145 return command;
146 }
147 // if we haven't got a command by now, we'll never get one
148 Gatherer.println("Result = null");
149 return null;
150
151 }
152
153 public int getColumnCount() {
154 return 2;
155 }
156
157 public String getColumnName(int column) {
158 String name;
159 switch(column) {
160 case 0:
161 name = Dictionary.get("FileAssociationDialog.Table.Extension");
162 break;
163 default:
164 name = Dictionary.get("FileAssociationDialog.Table.Command");
165 }
166 return name;
167 }
168
169 public String [] getCommand(File file) {
170 String command = null;
171 String [] commands = null;
172 if(file.isFile()) {
173 // Determine extension
174 String filename = file.getAbsolutePath();
175 String extension = filename.substring(filename.lastIndexOf(".") + 1);
176 // Try to retrieve a value from cache
177 Element entry = getCommand(extension);
178 if(entry != null) {
179 ///ystem.err.println("Retrieved Value From Cache");
180 command = MSMUtils.getValue(entry);
181 }
182 if(command == null || command.length() == 0) {
183 ///ystem.err.println("No Existing Command");
184 // If command is null, and we are on windows try searching the registry.
185 if(Utility.isWindows()) {
186 ///ystem.err.println("Is Windows");
187 //command = WinRegistry.openCommand(filename);
188 //try the start command
189 if (Utility.isWindows9x()) {
190 command = StaticStrings.WIN_9X_OPEN_COMMAND;
191 } else {
192 command = StaticStrings.WIN_OPEN_COMMAND;
193 }
194
195 }
196
197 // If we are on a mac, default to using the open program
198 else if(Utility.isMac()) {
199 ///ystem.err.println("Is Mac");
200 command = StaticStrings.MAC_OPEN_COMMAND;
201 }
202
203 // Otherwise display the dialog and ask the user to enter launching command.
204 if(command == null || command.length() == 0) {
205 ///ystem.err.println("Show Dialog");
206 // Show the dialog which forces a user to select the launch command for a certain file.
207 FileAssociationDialog dialog = new FileAssociationDialog(this);
208 command = dialog.display(extension);
209 dialog = null;
210 }
211 // Hopefully by now we have a command, or else we're never going to get one. Add the association.
212 if(command != null) {
213 // If no previous entry existed create one.
214 if(entry == null) {
215 entry = associations_element.getOwnerDocument().createElement(StaticStrings.ENTRY_ELEMENT);
216 entry.setAttribute(StaticStrings.EXTENSION_ATTRIBUTE, extension);
217 associations_element.appendChild(entry);
218 }
219 // Replace the text in this node. Remember to replace the dummy filename with %1 - I dont think the filename will ever be in the comand now
220 //MSMUtils.setValue(entry, command.replaceAll(filename, FILENAME_ARG));
221 MSMUtils.setValue(entry, command);
222 }
223 }
224 if(command != null) {
225 // Make the command into a string [] just in case the filename has spaces in it
226 commands = command.split(" ");
227
228 // We have to fix filename under windows to escape the backslashes.
229 filename = filename.replaceAll(ESCAPE, ESCAPED_ESCAPE);
230 // Replace %1 with the appropriate filename
231 for(int i=0; i<commands.length; i++) {
232 if (commands[i].equals(FILENAME_ARG)) {
233 commands[i] = filename;
234 }
235 }
236 //command = command.replaceAll(FILENAME_ARG, filename);
237 }
238
239 entry = null;
240 extension = null;
241 filename = null;
242 }
243 return commands;
244 }
245
246 public Element getCommand(String target_extension) {
247 NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
248 for(int i = 0; i < entries.getLength(); i++) {
249 Element entry = (Element) entries.item(i);
250 String extension = entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
251 if(extension.equalsIgnoreCase(target_extension)) {
252 entries = null;
253 extension = null;
254 return entry;
255 }
256 }
257 entries = null;
258 return null;
259 }
260
261 public String getCommandString(String target_extension) {
262 Element entry = getCommand(target_extension);
263 if(entry != null) {
264 return MSMUtils.getValue(entry);
265 }
266 else {
267 return "";
268 }
269 }
270
271 public String getExtension(int index) {
272 NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
273 if(0 <= index && index < entries.getLength()) {
274 Element entry = (Element) entries.item(index);
275 return entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
276 }
277 return "";
278 }
279
280 public int getRowCount() {
281 return size();
282 }
283
284 public Object getValueAt(int row, int column) {
285 String extension = getExtension(row);
286 switch(column) {
287 case 0:
288 return extension;
289 default:
290 return getCommandString(extension);
291 }
292 }
293
294 public void save() {
295 }
296
297 public void setCommand(String extension, String command) {
298 Gatherer.println("Set Launch: " + extension + " with " + command);
299 // Retrieve any existing entry for this extension
300 Element entry = getCommand(extension);
301 // If no previous entry existed create one.
302 if(entry == null && command != null) {
303 entry = associations_element.getOwnerDocument().createElement(StaticStrings.ENTRY_ELEMENT);
304 entry.setAttribute(StaticStrings.EXTENSION_ATTRIBUTE, extension);
305 associations_element.appendChild(entry);
306 }
307
308 if(command != null) {
309 // Replace the text in this node. If the user has used filename instead of %1 then too bad.
310 MSMUtils.setValue(entry, command);
311 }
312 else {
313 // Remove the entry
314 associations_element.removeChild(entry);
315 }
316 entry = null;
317 fireTableDataChanged(); // Can't be anymore efficient as DOM does not gareuntee ordering of new child nodes is consistant
318 }
319
320 public int size() {
321 NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
322 return entries.getLength();
323 }
324
325
326 protected boolean isAvailable(String program) {
327 try {
328 ExternalProgram e = new ExternalProgram("which", program);
329 e.exitProgram();
330 String out = e.getLineOfProgramOutput();
331 if (out == null) {
332 return false;
333 }
334 return true;
335 } catch (Exception exc) {
336 return false;
337 }
338 }
339}
Note: See TracBrowser for help on using the repository browser.