Changeset 4670
- Timestamp:
- 2003-06-16T09:59:49+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/file/FileAssociationManager.java
r4366 r4670 1 package org.greenstone.gatherer.file;2 1 /** 3 2 *######################################################################### … … 7 6 * University of Waikato, New Zealand. 8 7 * 9 * <BR><BR>10 *11 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 12 9 * 13 * <BR><BR>14 *15 10 * Copyright (C) 1999 New Zealand Digital Library Project 16 *17 * <BR><BR>18 11 * 19 12 * This program is free software; you can redistribute it and/or modify … … 22 15 * (at your option) any later version. 23 16 * 24 * <BR><BR>25 *26 17 * This program is distributed in the hope that it will be useful, 27 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 20 * GNU General Public License for more details. 30 *31 * <BR><BR>32 21 * 33 22 * You should have received a copy of the GNU General Public License … … 36 25 *######################################################################## 37 26 */ 27 package org.greenstone.gatherer.file; 28 38 29 import java.io.*; 39 import java.lang.*;40 import java.nio.charset.*;41 import java.util.*;42 import javax.swing.*;43 30 import org.greenstone.gatherer.Gatherer; 44 31 import org.greenstone.gatherer.gui.FileAssociationDialog; … … 47 34 import org.greenstone.gatherer.util.WinRegistry; 48 35 import org.w3c.dom.*; 49 /** Provides a manager for relating a filetype to a command to open that filetype, and an optional icon. Under windows this will attempt to leverage the Windows Registry. If this fails, or under other platforms, the user will be prompted to enter the required details manually. This information will then be stored for any further sessions of the Gatherer. Of course the ability to edit these settings must also be provided. */ 50 public class FileAssociationManager 51 extends HashMap { 52 53 static private final File ASSOC_FILE = new File(Utility.BASE_DIR, "associations.xml"); 36 37 public class FileAssociationManager { 38 static final public String FILENAME_ARG = "%1"; 39 static final private String DATA_FILENAME = "associations.xml"; 40 static final private String ENTRY_ELEMENT = "Entry"; 41 static final private String ESCAPE = "\\\\"; // '\' 42 static final private String ESCAPED_ESCAPE = "\\\\\\\\"; // '\\' 43 static final private String EXTENSION_ATTRIBUTE = "extension"; 44 private Document document; 45 private File data_file; 54 46 55 47 public FileAssociationManager() { 56 // Attempt to load any previous file associations 57 if(ASSOC_FILE.exists()) { 58 load(); 59 } 60 } 61 62 public void destroy() { 63 save(); 64 } 65 66 public String getCommand(File file) { 67 String command = null; 68 String filename = file.toString(); 69 // Determine extension 70 int index = -1; 71 if((index = filename.lastIndexOf(".")) != -1) { 72 String extension = filename.substring(index + 1); 73 command = getCommand(file, extension); 74 } 75 return command; 76 } 77 78 public String getCommand(File file, String extension) { 79 // We first check to see if we already know the answer to how to run this program. 80 String command = (String) get(extension); 81 if(command != null) { 82 command = command + " " + file.getAbsolutePath(); 83 } 84 // If not, and we are on windows, try the registry. 85 if(command == null && Utility.isWindows()) { 86 command = WinRegistry.openCommand(file.getAbsolutePath()); 87 } 88 // Failing all that prompt the user to select the program to open this with. 89 if(command == null) { 90 FileAssociationDialog dialog = new FileAssociationDialog(this); 91 command = dialog.display(extension); 92 dialog.destroy(); 93 dialog = null; 94 if(command != null) { 95 put(extension, command); 96 command = command + " " + file.getAbsolutePath(); 48 // If a associations.xml is available in the GLI install directory load it. 49 data_file = new File(Utility.BASE_DIR + DATA_FILENAME); 50 if(data_file.exists()) { 51 document = Utility.parse(data_file, true); 52 } 53 // Load the default associations xml data file. This can be done using the classloader. 54 else { 55 document = Utility.parse(Utility.XML_DIRECTORY + DATA_FILENAME, true); 56 } 57 // Initialize the associations. This involves looking through all current associations searching for those with a command of "". 58 if(document != null) { 59 NodeList entries = (document.getDocumentElement()).getElementsByTagName(ENTRY_ELEMENT); 60 for(int i = 0; i < entries.getLength(); i++) { 61 Element entry = (Element) entries.item(i); 62 String extension = entry.getAttribute(EXTENSION_ATTRIBUTE); 63 String command = MSMUtils.getValue(entry); 64 // If we encounter a command of "", and we are on windows, we try to automatically set this command. 65 if(command.length() == 0 && 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 command = null; 79 extension = null; 80 entry = null; 97 81 } 98 } 99 ///ystem.err.println("Get command: " + extension + " = " + command); 100 return command; 101 } 102 103 public String getCommandImmediately(String extension) { 104 return (String) get(extension); 105 } 106 82 entries = null; 83 } 84 else { 85 Gatherer.println("Didn't parse anything. About to crash."); 86 } 87 } 88 107 89 public void edit() { 108 90 FileAssociationDialog dialog = new FileAssociationDialog(this); 109 91 dialog.display(null); 110 dialog.destroy();111 92 dialog = null; 112 93 } 113 94 114 private void load() { 115 // Read in and parse the document. 116 Document document = Utility.parse(ASSOC_FILE, false); 117 if(document != null) { 118 // Recover all the entry nodes of the association root. 119 for(Node entry_n = document.getDocumentElement().getFirstChild(); entry_n != null; entry_n = entry_n.getNextSibling()) { 120 if(entry_n.getNodeName().equals("Entry")) { 121 Element entry_e = (Element) entry_n; 122 String extension = entry_e.getAttribute("extension"); 123 String command = MSMUtils.getValue(entry_e); 124 put(extension, command); 125 extension = null; 126 command = null; 127 entry_e = null; 95 public String getCommand(File file) { 96 String command = null; 97 if(file.isFile()) { 98 // Determine extension 99 String filename = file.getAbsolutePath(); 100 String extension = filename.substring(filename.lastIndexOf(".") + 1); 101 // Try to retrieve a value from cache 102 Element entry = getCommand(extension); 103 if(entry != null) { 104 command = MSMUtils.getValue(entry); 105 if(command == null || command.length() == 0) { 106 // If command is null, and we are on windows try searching the registry. 107 if(Utility.isWindows()) { 108 command = WinRegistry.openCommand(filename); 109 } 110 // Otherwise display the dialog and ask the user to enter launching command. 111 if(command == null || command.length() == 0) { 112 // Show the dialog which forces a user to select the launch command for a certain file. 113 FileAssociationDialog dialog = new FileAssociationDialog(this); 114 command = dialog.display(extension); 115 dialog = null; 116 } 117 // Hopefully by now we have a command, or else we're never going to get one. Add the association. 118 if(command != null) { 119 // If no previous entry existed create one. 120 if(entry == null) { 121 entry = document.createElement(ENTRY_ELEMENT); 122 entry.setAttribute(EXTENSION_ATTRIBUTE, extension); 123 document.getDocumentElement().appendChild(entry); 124 } 125 // Replace the text in this node. Remember to replace the dummy filename with %1 126 MSMUtils.setValue(entry, command.replaceAll(filename, FILENAME_ARG)); 127 } 128 } 129 if(command != null) { 130 // We have to fix filename under windows to escape the backslashes. 131 filename = filename.replaceAll(ESCAPE, ESCAPED_ESCAPE); 132 // Replace %1 with the appropriate filename 133 command = command.replaceAll(FILENAME_ARG, filename); 128 134 } 129 135 } 130 } 131 } 132 133 private void save() { 134 // Only save if there is something to save. 135 if(size() > 0) { 136 StringBuffer assoc = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 137 assoc.append("<!DOCTYPE Associations [\n"); 138 assoc.append(" <!ELEMENT Associations (Entry*)>\n"); 139 assoc.append(" <!ELEMENT Entry (#PCDATA)>\n"); 140 assoc.append(" <!ATTLIST Entry\n"); 141 assoc.append(" extension CDATA #REQUIRED>\n"); 142 assoc.append("]>\n"); 143 assoc.append("\n"); 144 assoc.append("<Associations>\n"); 145 for(Iterator keys = keySet().iterator(); keys.hasNext(); ) { 146 String extension = (String) keys.next(); 147 String command = (String) get(extension); 148 assoc.append("\t<Entry extension=\""); 149 assoc.append(extension); 150 assoc.append("\">"); 151 assoc.append(command); 152 assoc.append("</Entry>\n"); 136 entry = null; 137 extension = null; 138 filename = null; 139 } 140 return command; 141 } 142 143 public Element getCommand(String target_extension) { 144 NodeList entries = document.getDocumentElement().getElementsByTagName(ENTRY_ELEMENT); 145 for(int i = 0; i < entries.getLength(); i++) { 146 Element entry = (Element) entries.item(i); 147 String extension = entry.getAttribute(EXTENSION_ATTRIBUTE); 148 if(extension.equalsIgnoreCase(target_extension)) { 149 entries = null; 150 extension = null; 151 return entry; 153 152 } 154 assoc.append("</Associations>"); 155 156 String assoc_str = assoc.toString(); 157 assoc = null; 158 try { 159 FileOutputStream fos = new FileOutputStream(ASSOC_FILE); 160 OutputStreamWriter osw = new OutputStreamWriter(fos, Charset.forName("UTF-8")); 161 int position = 0; 162 int BLOCK_SIZE = 1024; 163 // Write x block sized chunks to file. 164 while(position + BLOCK_SIZE < assoc_str.length()) { 165 osw.write(assoc_str, position, BLOCK_SIZE); 166 position = position + BLOCK_SIZE; 167 } 168 // Write the remainder of the buffer. 169 if(position < assoc_str.length()) { 170 osw.write(assoc_str, position, assoc_str.length() - position); 171 } 172 osw.flush(); 173 osw.close(); 174 osw = null; 175 fos.close(); 176 fos = null; 177 assoc_str = null; 178 } 179 catch (Exception error) { 180 Gatherer.printStackTrace(error); 181 } 182 } 153 } 154 entries = null; 155 return null; 156 } 157 158 public String getCommandString(String target_extension) { 159 Element entry = getCommand(target_extension); 160 if(entry != null) { 161 return MSMUtils.getValue(entry); 162 } 163 else { 164 return ""; 165 } 166 } 167 168 public String getExtension(int index) { 169 NodeList entries = document.getDocumentElement().getElementsByTagName(ENTRY_ELEMENT); 170 if(0 <= index && index < entries.getLength()) { 171 Element entry = (Element) entries.item(index); 172 return entry.getAttribute(EXTENSION_ATTRIBUTE); 173 } 174 return ""; 175 } 176 177 public void save() { 178 Utility.export(document, data_file); 183 179 } 184 180 185 181 public void setCommand(String extension, String command) { 186 ///ystem.err.println("Set command: " + extension + " = " + command); 187 if(command == null || command.length() == 0) { 188 remove(extension); 189 } 190 else { 191 put(extension, command); 192 } 182 Gatherer.println("Set Launch: " + extension + " with " + command); 183 // Retrieve any existing entry for this extension 184 Element entry = getCommand(extension); 185 // If no previous entry existed create one. 186 if(entry == null) { 187 entry = document.createElement(ENTRY_ELEMENT); 188 entry.setAttribute(EXTENSION_ATTRIBUTE, extension); 189 document.getDocumentElement().appendChild(entry); 190 } 191 // Replace the text in this node. If the user has used filename instead of %1 then too bad. 192 MSMUtils.setValue(entry, command); 193 entry = null; 194 } 195 196 public int size() { 197 NodeList entries = document.getDocumentElement().getElementsByTagName(ENTRY_ELEMENT); 198 return entries.getLength(); 193 199 } 194 200 } 195 196 197
Note:
See TracChangeset
for help on using the changeset viewer.