Changeset 4670


Ignore:
Timestamp:
2003-06-16T09:59:49+12:00 (21 years ago)
Author:
jmt12
Message:

Reimplemented file associations to properly handle %1 arguments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/file/FileAssociationManager.java

    r4366 r4670  
    1 package org.greenstone.gatherer.file;
    21/**
    32 *#########################################################################
     
    76 * University of Waikato, New Zealand.
    87 *
    9  * <BR><BR>
    10  *
    118 * Author: John Thompson, Greenstone Digital Library, University of Waikato
    129 *
    13  * <BR><BR>
    14  *
    1510 * Copyright (C) 1999 New Zealand Digital Library Project
    16  *
    17  * <BR><BR>
    1811 *
    1912 * This program is free software; you can redistribute it and/or modify
     
    2215 * (at your option) any later version.
    2316 *
    24  * <BR><BR>
    25  *
    2617 * This program is distributed in the hope that it will be useful,
    2718 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2819 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2920 * GNU General Public License for more details.
    30  *
    31  * <BR><BR>
    3221 *
    3322 * You should have received a copy of the GNU General Public License
     
    3625 *########################################################################
    3726 */
     27package org.greenstone.gatherer.file;
     28
    3829import java.io.*;
    39 import java.lang.*;
    40 import java.nio.charset.*;
    41 import java.util.*;
    42 import javax.swing.*;
    4330import org.greenstone.gatherer.Gatherer;
    4431import org.greenstone.gatherer.gui.FileAssociationDialog;
     
    4734import org.greenstone.gatherer.util.WinRegistry;
    4835import 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
     37public 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;   
    5446
    5547    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;
    9781        }
    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   
    10789    public void edit() {
    10890    FileAssociationDialog dialog = new FileAssociationDialog(this);
    10991    dialog.display(null);
    110     dialog.destroy();
    11192    dialog = null;       
    11293    }
    11394
    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);
    128134        }
    129135        }
    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;
    153152        }
    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);
    183179    }
    184180
    185181    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();
    193199    }
    194200}
    195 
    196 
    197 
Note: See TracChangeset for help on using the changeset viewer.