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

Last change on this file since 24707 was 24707, checked in by ak19, 13 years ago

Reverting code committed last time which started using xdg-open as the default FileAssociation command for Linux. This doesn't work on the CentOS here which doesn't recognise xdg-open and says it can't find it (installed). The old code used to popup the FileAssociation dialog instead for Linux, so that the user could choose something that would work, rather than what the code does now: fail quietly.

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