[6035] | 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 | */
|
---|
| 27 | package org.greenstone.gatherer.file;
|
---|
| 28 |
|
---|
| 29 | import java.io.*;
|
---|
| 30 | import javax.swing.table.*;
|
---|
| 31 | import org.greenstone.gatherer.Dictionary;
|
---|
| 32 | import org.greenstone.gatherer.Gatherer;
|
---|
| 33 | import org.greenstone.gatherer.gui.FileAssociationDialog;
|
---|
[6748] | 34 | import org.greenstone.gatherer.gui.PreviewCommandDialog;
|
---|
[6035] | 35 | import org.greenstone.gatherer.msm.MSMUtils;
|
---|
[6786] | 36 | import org.greenstone.gatherer.util.ExternalProgram;
|
---|
[6260] | 37 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
[6035] | 38 | import org.greenstone.gatherer.util.Utility;
|
---|
| 39 | import org.greenstone.gatherer.util.WinRegistry;
|
---|
| 40 | import org.w3c.dom.*;
|
---|
| 41 |
|
---|
| 42 | public 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 = "\\\\\\\\"; // '\\'
|
---|
[6795] | 47 | static final private String SPACE = " ";
|
---|
| 48 | static final private String ESCAPED_SPACE = "\\\\ ";
|
---|
[6630] | 49 | private Element associations_element;
|
---|
[6035] | 50 | private File data_file;
|
---|
| 51 |
|
---|
| 52 | public FileAssociationManager() {
|
---|
[6630] | 53 | // Retrieve the associations_element from the config
|
---|
| 54 | associations_element = Gatherer.config.getFileAssociations();
|
---|
[6035] | 55 | // Initialize the associations. This involves looking through all current associations searching for those with a command of "".
|
---|
[6630] | 56 | if(associations_element != null) {
|
---|
| 57 | NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
|
---|
[6035] | 58 | for(int i = 0; i < entries.getLength(); i++) {
|
---|
| 59 | Element entry = (Element) entries.item(i);
|
---|
[6630] | 60 | String extension = entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
|
---|
[6035] | 61 | String command = MSMUtils.getValue(entry);
|
---|
[6260] | 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;
|
---|
[6035] | 77 | }
|
---|
[6260] | 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 | }
|
---|
[6035] | 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) {
|
---|
[6622] | 101 | Gatherer.println("Get browser command: " + url);
|
---|
[6539] | 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);
|
---|
[6622] | 107 | Gatherer.println("Result = " + command);
|
---|
[6539] | 108 | return command;
|
---|
| 109 | }
|
---|
[6748] | 110 | command = null;
|
---|
| 111 | // Failing that we have a guess at a sensible default
|
---|
[6035] | 112 | if(Utility.isWindows()) {
|
---|
| 113 | // we use cmd and start
|
---|
| 114 | if (Utility.isWindows9x()) {
|
---|
[6313] | 115 | command = StaticStrings.WIN_9X_OPEN_COMMAND;//"command.com /c start \""+url+"\"";
|
---|
[6035] | 116 | } else {
|
---|
[6313] | 117 | command = StaticStrings.WIN_OPEN_COMMAND;//"cmd.exe /c start \"\" \""+url+"\"";
|
---|
[6035] | 118 | }
|
---|
[6748] | 119 | } else if (Utility.isMac()) {
|
---|
| 120 | command = StaticStrings.MAC_OPEN_COMMAND; // "open %1"
|
---|
| 121 | } else {
|
---|
| 122 | // we try to look for a browser
|
---|
[6786] | 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 | }
|
---|
[6035] | 130 | }
|
---|
[6748] | 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 | }
|
---|
[6539] | 139 |
|
---|
| 140 | // Store the result if any
|
---|
[6748] | 141 | if(command != null && !command.equals("")) {
|
---|
[6539] | 142 | Gatherer.config.setPreviewCommand(command);
|
---|
[6748] | 143 | command = command.replaceAll(FILENAME_ARG, url);
|
---|
| 144 | Gatherer.println("Result = " + command);
|
---|
| 145 | return command;
|
---|
[6539] | 146 | }
|
---|
[6035] | 147 | // if we haven't got a command by now, we'll never get one
|
---|
[6748] | 148 | Gatherer.println("Result = null");
|
---|
| 149 | return null;
|
---|
| 150 |
|
---|
[6035] | 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 |
|
---|
[6795] | 169 | public String [] getCommand(File file) {
|
---|
[6035] | 170 | String command = null;
|
---|
[6795] | 171 | String [] commands = null;
|
---|
[6035] | 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) {
|
---|
[6260] | 179 | ///ystem.err.println("Retrieved Value From Cache");
|
---|
[6035] | 180 | command = MSMUtils.getValue(entry);
|
---|
| 181 | }
|
---|
| 182 | if(command == null || command.length() == 0) {
|
---|
[6260] | 183 | ///ystem.err.println("No Existing Command");
|
---|
[6035] | 184 | // If command is null, and we are on windows try searching the registry.
|
---|
| 185 | if(Utility.isWindows()) {
|
---|
[6260] | 186 | ///ystem.err.println("Is Windows");
|
---|
[6313] | 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 |
|
---|
[6035] | 195 | }
|
---|
[6313] | 196 |
|
---|
[6260] | 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 |
|
---|
[6035] | 203 | // Otherwise display the dialog and ask the user to enter launching command.
|
---|
| 204 | if(command == null || command.length() == 0) {
|
---|
[6260] | 205 | ///ystem.err.println("Show Dialog");
|
---|
[6035] | 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) {
|
---|
[6630] | 215 | entry = associations_element.getOwnerDocument().createElement(StaticStrings.ENTRY_ELEMENT);
|
---|
| 216 | entry.setAttribute(StaticStrings.EXTENSION_ATTRIBUTE, extension);
|
---|
| 217 | associations_element.appendChild(entry);
|
---|
[6035] | 218 | }
|
---|
[6314] | 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);
|
---|
[6035] | 222 | }
|
---|
| 223 | }
|
---|
| 224 | if(command != null) {
|
---|
[7092] | 225 | // We have to fix filename under windows to escape the backslashes
|
---|
[6035] | 226 | filename = filename.replaceAll(ESCAPE, ESCAPED_ESCAPE);
|
---|
| 227 | // Replace %1 with the appropriate filename
|
---|
[7092] | 228 | command = command.replaceAll(FILENAME_ARG, filename);
|
---|
| 229 |
|
---|
| 230 | // Make the command into a string [] in case the filename has spaces in it
|
---|
| 231 | commands = command.split(" ");
|
---|
[6035] | 232 | }
|
---|
| 233 |
|
---|
| 234 | entry = null;
|
---|
| 235 | extension = null;
|
---|
| 236 | filename = null;
|
---|
| 237 | }
|
---|
[6795] | 238 | return commands;
|
---|
[6035] | 239 | }
|
---|
| 240 |
|
---|
| 241 | public Element getCommand(String target_extension) {
|
---|
[6630] | 242 | NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
|
---|
[6035] | 243 | for(int i = 0; i < entries.getLength(); i++) {
|
---|
| 244 | Element entry = (Element) entries.item(i);
|
---|
[6630] | 245 | String extension = entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
|
---|
[6035] | 246 | if(extension.equalsIgnoreCase(target_extension)) {
|
---|
| 247 | entries = null;
|
---|
| 248 | extension = null;
|
---|
| 249 | return entry;
|
---|
| 250 | }
|
---|
| 251 | }
|
---|
| 252 | entries = null;
|
---|
| 253 | return null;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | public String getCommandString(String target_extension) {
|
---|
| 257 | Element entry = getCommand(target_extension);
|
---|
| 258 | if(entry != null) {
|
---|
| 259 | return MSMUtils.getValue(entry);
|
---|
| 260 | }
|
---|
| 261 | else {
|
---|
| 262 | return "";
|
---|
| 263 | }
|
---|
| 264 | }
|
---|
| 265 |
|
---|
| 266 | public String getExtension(int index) {
|
---|
[6630] | 267 | NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
|
---|
[6035] | 268 | if(0 <= index && index < entries.getLength()) {
|
---|
| 269 | Element entry = (Element) entries.item(index);
|
---|
[6630] | 270 | return entry.getAttribute(StaticStrings.EXTENSION_ATTRIBUTE);
|
---|
[6035] | 271 | }
|
---|
| 272 | return "";
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | public int getRowCount() {
|
---|
[6630] | 276 | return size();
|
---|
[6035] | 277 | }
|
---|
| 278 |
|
---|
| 279 | public Object getValueAt(int row, int column) {
|
---|
| 280 | String extension = getExtension(row);
|
---|
| 281 | switch(column) {
|
---|
| 282 | case 0:
|
---|
| 283 | return extension;
|
---|
| 284 | default:
|
---|
| 285 | return getCommandString(extension);
|
---|
| 286 | }
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 | public void save() {
|
---|
| 290 | }
|
---|
| 291 |
|
---|
| 292 | public void setCommand(String extension, String command) {
|
---|
| 293 | Gatherer.println("Set Launch: " + extension + " with " + command);
|
---|
| 294 | // Retrieve any existing entry for this extension
|
---|
| 295 | Element entry = getCommand(extension);
|
---|
| 296 | // If no previous entry existed create one.
|
---|
| 297 | if(entry == null && command != null) {
|
---|
[6630] | 298 | entry = associations_element.getOwnerDocument().createElement(StaticStrings.ENTRY_ELEMENT);
|
---|
| 299 | entry.setAttribute(StaticStrings.EXTENSION_ATTRIBUTE, extension);
|
---|
| 300 | associations_element.appendChild(entry);
|
---|
[6035] | 301 | }
|
---|
| 302 |
|
---|
| 303 | if(command != null) {
|
---|
| 304 | // Replace the text in this node. If the user has used filename instead of %1 then too bad.
|
---|
| 305 | MSMUtils.setValue(entry, command);
|
---|
| 306 | }
|
---|
| 307 | else {
|
---|
| 308 | // Remove the entry
|
---|
[6630] | 309 | associations_element.removeChild(entry);
|
---|
[6035] | 310 | }
|
---|
| 311 | entry = null;
|
---|
| 312 | fireTableDataChanged(); // Can't be anymore efficient as DOM does not gareuntee ordering of new child nodes is consistant
|
---|
| 313 | }
|
---|
| 314 |
|
---|
| 315 | public int size() {
|
---|
[6630] | 316 | NodeList entries = associations_element.getElementsByTagName(StaticStrings.ENTRY_ELEMENT);
|
---|
[6035] | 317 | return entries.getLength();
|
---|
| 318 | }
|
---|
[6786] | 319 |
|
---|
| 320 |
|
---|
| 321 | protected boolean isAvailable(String program) {
|
---|
| 322 | try {
|
---|
| 323 | ExternalProgram e = new ExternalProgram("which", program);
|
---|
| 324 | e.exitProgram();
|
---|
| 325 | String out = e.getLineOfProgramOutput();
|
---|
| 326 | if (out == null) {
|
---|
| 327 | return false;
|
---|
| 328 | }
|
---|
| 329 | return true;
|
---|
| 330 | } catch (Exception exc) {
|
---|
| 331 | return false;
|
---|
| 332 | }
|
---|
| 333 | }
|
---|
[6035] | 334 | }
|
---|