Ignore:
Timestamp:
2003-08-18T14:10:31+12:00 (21 years ago)
Author:
jmt12
Message:

I can't remember what has changed, but I bet it was for the better

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java

    r5033 r5164  
    4242import javax.swing.*;
    4343import javax.swing.event.*;
     44import javax.swing.text.*;
    4445import org.greenstone.gatherer.Gatherer;
    4546import org.greenstone.gatherer.cdm.Argument;
     
    4950import org.greenstone.gatherer.collection.CollectionManager;
    5051import org.greenstone.gatherer.msm.ElementWrapper;
     52import org.greenstone.gatherer.util.AppendLineOnlyFileDocument;
     53import org.greenstone.gatherer.util.AppendLineOnlyFileDocumentOwner;
    5154import org.greenstone.gatherer.util.Utility;
    5255//import org.w3c.dom.*;
     
    5558 * @version 2.2
    5659 */
    57 final public class OptionsPane
    58     extends JPanel {
     60public class OptionsPane
     61    extends JPanel
     62    implements AppendLineOnlyFileDocumentOwner {
     63
     64    static final public char SUCCESSFUL = 's';
     65    static final public char UNSUCCESSFUL = 'u';
     66    static final public char CANCELLED = 'c';
     67    static final public char UNKNOWN = 'x';
     68
     69    /** All process messages are written to this log text area. */
     70    public JTextArea log_textarea = null;
     71
    5972    /** The <strong>BuildOptions</strong> data object contains all the option settings we wish to persist between Gatherer sessions (and thus is stored in <strong>Collection</strong>). */
    6073    private BuildOptions build_options = null;
     74
     75    private FileEntry file_entry = null;
    6176    /** the log pane - we only create it once now, not each time */
    6277    private JPanel log_pane = null;
    6378    /** the list of previous log messages */
    6479    private JList log_list = null;
    65     /** whether that currently showing log is changed or not */
    66     private boolean is_log_changed = false;
    67     /** the list entry that is currently displayed */
    68     private FileEntry displayed_log = null;
    69     /** a listener for changes in the log text */
    70     private LogChangeListener log_change_listener = null;
    71     /** All process messages are written to this log text area. */
    72     private JTextArea log_display = null;
    73 
    74     static final public char SUCCESSFUL = 's';
    75     static final public char UNSUCCESSFUL = 'u';
    76     static final public char CANCELLED = 'c';
     80    private Vector writing_documents;
    7781
    7882    static private int BUILD = 0;
     
    8892
    8993     /** The default constructor creates the few session length options, but either retrieves the rest from the current collection, or creates a default set of options. */
    90     public OptionsPane(JTextArea message_log, BuildOptions build_options) {
    91     this.log_display = new JTextArea(message_log.getDocument());
     94    public OptionsPane(BuildOptions build_options) {
    9295    this.build_options = build_options;
    93     this.log_change_listener = new LogChangeListener();
    94     //this.target_pane = target_pane;
    95     }
    96 
    97     /** creates a new log from the text in log. The new file is named
    98      * build_log.<current time>.txt. A new FileEntry is added to teh log list
    99      * and made selected. A fresh listener is added to teh document */
    100     public void addNewLog(char success) {
    101     ///ystem.out.println("add new log");
    102 
    103     // create the file name
    104     long time = System.currentTimeMillis();
    105     StringBuffer name = new StringBuffer();
    106     name.append("build_log.");
    107     name.append(time);
    108     name.append(success);
    109     name.append(".txt");
    110     File f = new File(Gatherer.c_man.getCollectionLog()+name.toString());
    111     // just in case there is no log directory
    112     File parent_file = f.getParentFile();
    113     parent_file.mkdirs();
    114 
    115     // save the log text to the file
    116     saveLogFile(f);
    117     is_log_changed=false;
    118     log_display.getDocument().addDocumentListener(log_change_listener);
    119 
    120     // create the file entry and add it to the list at pos 0 - it will always be the newest one created
    121     FileEntry fe = new FileEntry(f);
    122     ((DefaultListModel)log_list.getModel()).add(0, fe);
    123     log_list.setSelectedIndex(0);
    124     displayed_log = fe;
    125 
     96    this.writing_documents = new Vector();
     97
     98    // Have to do this here, not in display, as the message log view may not have been displayed yet.
     99    log_textarea = new JTextArea();
     100    log_textarea.setEditable(false);
    126101    }
    127102
     
    134109    pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    135110    int build_argument_count = build_options.getBuildArgumentCount();
    136     pane.setLayout(new GridLayout(build_argument_count, 1, 0, 0));
    137     int total_height = PANE_SIZE.height;
     111    pane.setPreferredSize(new Dimension(ROW_SIZE.width, ROW_SIZE.height * build_argument_count));
    138112    for(int i = 0; i < build_argument_count; i++) {
    139113        // Retrieve the argument so we know how to format the control.
     
    143117        String value = build_options.getBuildValue(argument.getName());
    144118        ArgumentControl argument_control = new ArgumentControl(BUILD, argument, enabled, value);
    145         total_height = total_height - argument_control.getPreferredSize().height;
    146119        pane.add(argument_control);
    147     }
    148     if(total_height > 0) {
    149         JPanel filler = new JPanel();
    150         filler.setPreferredSize(new Dimension(100, total_height));
    151         filler.setSize(filler.getPreferredSize());
    152         pane.add(filler);
    153120    }
    154121    return pane;
     
    162129    pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    163130    int import_argument_count = build_options.getImportArgumentCount();
    164     pane.setLayout(new GridLayout(import_argument_count, 1, 0, 0));
    165     int total_height = PANE_SIZE.height;
     131    pane.setPreferredSize(new Dimension(ROW_SIZE.width, ROW_SIZE.height * import_argument_count));
    166132    for(int i = 0; i < import_argument_count; i++) {
    167133        // Retrieve the argument so we know how to format the control.
     
    171137        String value = build_options.getImportValue(argument.getName());
    172138        ArgumentControl argument_control = new ArgumentControl(IMPORT, argument, enabled, value);
    173         total_height = total_height - argument_control.getPreferredSize().height;
    174139        pane.add(argument_control);
    175     }
    176     if(total_height > 0) {
    177         JPanel filler = new JPanel();
    178         filler.setPreferredSize(new Dimension(100, total_height));
    179         filler.setSize(filler.getPreferredSize());
    180         pane.add(filler);
    181140    }
    182141    return pane;
     
    195154        File children[] = log_directory.listFiles();
    196155        for(int i = 0; children != null && i < children.length; i++) {
    197         if(children[i].getName().startsWith("build_log")&&children[i].getName().endsWith(".txt") ) {
    198             FileEntry entry = new FileEntry(children[i]);
     156        if(children[i].getName().startsWith("build_log") && children[i].getName().endsWith(".txt") ) {
     157            FileEntry entry = new FileEntry(children[i].getName(), children[i].getAbsolutePath());
    199158            // We are about to insert it. But where.
    200159            boolean found = false;
    201             for(int j = 0; j < contents.size(); j++) {
     160            for(int j = 0; !found && j < contents.size(); j++) {
    202161            FileEntry sibling = (FileEntry) contents.getElementAt(j);
    203162            int order = entry.compareTo(sibling);
     
    205164                contents.insertElementAt(entry, j);
    206165                found = true;
    207                 break;
    208166            }
    209167            }
     
    217175        log_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    218176        log_list.setLayoutOrientation(JList.VERTICAL);
     177        log_list.setPreferredSize(new Dimension(600, 100));
    219178        log_list.setVisibleRowCount(3);
    220179        log_list.addListSelectionListener(new LogListListener());
    221180
    222         JScrollPane list_scroller = new JScrollPane(log_list);
    223 
    224         // If log is not empty and we have something in displayed_log - make that element selected
    225         if (log_display.getText().length()>0 && displayed_log != null) {
    226         int index = contents.indexOf(displayed_log);
    227         if (index != -1) {
    228             log_list.setSelectedIndex(index);
    229         }
    230 
    231         }
    232 
    233         log_pane.add(new JScrollPane(log_display), BorderLayout.CENTER);
    234181        JLabel log_history_label = new JLabel(get("LogHistory"));
    235182        JPanel log_history_pane = new JPanel();
    236 
     183        log_history_pane.setPreferredSize(new Dimension(600, 100));
    237184        log_history_pane.setLayout(new BorderLayout());
    238185        log_history_pane.add(log_history_label, BorderLayout.NORTH);
    239         log_history_pane.add(list_scroller, BorderLayout.SOUTH);
     186        log_history_pane.add(new JScrollPane(log_list), BorderLayout.CENTER);
    240187       
     188        log_pane.add(new JScrollPane(log_textarea), BorderLayout.CENTER);
    241189        log_pane.add(log_history_pane, BorderLayout.SOUTH);
    242190    }
    243191    return log_pane;
     192    }
     193
     194    public AppendLineOnlyFileDocument createNewLogDocument() {
     195    long time = System.currentTimeMillis();
     196    StringBuffer name = new StringBuffer();
     197    name.append("build_log.");
     198    name.append(time);
     199    name.append(".txt");
     200    // just in case there is no log directory
     201    File file = new File(Gatherer.c_man.getCollectionLog() + name.toString());
     202    File parent_file = file.getParentFile();
     203    parent_file.mkdirs();
     204    parent_file = null;
     205    // create the file entry and add it to the list at pos 0 - it will always be the newest one created
     206    file_entry = new FileEntry(name.toString(), file.getAbsolutePath());
     207    ((DefaultListModel)log_list.getModel()).add(0, file_entry);
     208    log_list.setSelectedIndex(0);
     209    // Finally retrieve and return the document associated with this file entry
     210    return file_entry.getDocument();
    244211    }
    245212
     
    265232    }
    266233    /** Attempts to discover the latest document count.
    267       * @return An <strong>int</strong> detailing the number of documents in this collection.
    268     */
     234     * @return An <strong>int</strong> detailing the number of documents in this collection.
     235    */
    269236    public int getDocumentCount() {
    270237    if(Gatherer.c_man.ready()) {
     
    277244    }
    278245
    279     /** Loads a new log into the log text - saves the currently showing one,
    280      * and loads the new one, adding a fresh listener to the document
    281      * Note, we need to remove any listener before making the changes, then
    282      * add a listener back in
    283      */
    284     public void loadSelectedLog(FileEntry fe) {
    285     ///ystem.out.println("load selected log");
    286     if(displayed_log != null) {
    287         if (is_log_changed) {
    288         saveLogFile(displayed_log.getFile());
    289         } else {
    290         log_display.getDocument().removeDocumentListener(log_change_listener);
    291         }
    292     }
    293 
    294     displayed_log = fe;
    295     if (fe != null) {
    296         log_display.setText(fe.getFileText());
    297     } else {
    298         log_display.setText("");
    299     }
    300     is_log_changed=false;
    301     log_display.getDocument().addDocumentListener(log_change_listener);
    302 
    303     }
    304 
    305     /** Neutralizes the log list - saves any unsaved changes to the current log
    306      * clears the log text, unselects the log list, and adds a fresh listener
    307      * to the log's document
    308      * Note, we need to remove any listener before making the changes, then
    309      * add a listener back in */
    310     public void resetLogList() {
    311     ///ystem.out.println("reset log");
    312     if (is_log_changed) {
    313         saveLogFile(displayed_log.getFile());
    314     } else {
    315         log_display.getDocument().removeDocumentListener(log_change_listener);
    316     }
    317     log_display.setText("");
    318     displayed_log = null;
    319     if (log_list != null) {
    320         log_list.clearSelection();
    321     }
    322     is_log_changed=false;
    323     log_display.getDocument().addDocumentListener(log_change_listener);
    324 
    325     }
    326 
    327     /** saves the current text in log to the File specified */
    328     public void saveLogFile(File file) {
    329 
    330     try {
    331         BufferedWriter out = new BufferedWriter(new FileWriter(file)); // uses the default encoding
    332         String log_text = log_display.getText();
    333         // set teh return delims to true, then swap them for newLine() (platform dependent) - having return delims set to false seemed to not get empty strings so that empty lines were not preserved.
    334         StringTokenizer t = new StringTokenizer(log_text, "\n", true);
    335         while (t.hasMoreTokens()) {
    336         String token = t.nextToken();
    337         if (token.equals("\n")) {
    338             out.newLine();
    339         } else {
    340             out.write(token, 0, token.length());
    341         }
    342 
    343         }
    344         out.close();
    345 
    346     } catch(Exception e) {
    347         System.out.println("Error in saving log file: "+file.toString());
    348         e.printStackTrace();
    349     }
    350 
    351 
    352     }
    353 
     246    /** Called by our magic log documents after they have finished writing themselves to file, whereapon it is no longer necessary to hold a reference to them. */
     247    public void remove(AppendLineOnlyFileDocument document) {
     248    writing_documents.remove(document);
     249    }
     250
     251    public void resetFileEntry() {
     252    if(file_entry != null) {
     253        file_entry.reset();
     254    }
     255    }
    354256
    355257    /** Given a panel containing ArgumentControls, update the values associated with them. */
     
    591493    }
    592494
    593     /** holds a File which has a particular naming convention
    594      * build_log.date.txt
    595      * also keeps a Date corresponding to the date in its name*/
     495    /** Holds a File which has a particular naming convention build_log.date.txt also keeps a Date corresponding to the date in its name*/
    596496    private class FileEntry {
    597497
    598     private Date date=null;
    599     private File file=null;
    600     private String display=null;
    601     public FileEntry(File f) {
    602         this.file=f;
    603         this.date = getDateFromFileName();
    604         this.display = createDisplayText();
    605 
     498    private Date date;
     499    private long last_modified;
     500    private String display;
     501    private String filename;
     502    private String filepath;
     503
     504    public FileEntry(String filename, String filepath) {
     505        this.date = null;
     506        this.display = null;
     507        this.filename = filename;
     508        this.filepath = filepath;
     509        this.last_modified = 0L;
    606510    }
    607511
    608512    /** returns 0 if the dates are the same, -ve number if the current FileEntry is earlier than the fe FileEntry ...*/
    609     public int compareTo(FileEntry fe) {
    610         Date d = fe.getDate();
    611         return date.compareTo(d);
     513    public int compareTo(FileEntry file_entry) {
     514        Date our_date = getDate();
     515        Date other_date = file_entry.getDate();
     516        return our_date.compareTo(other_date);
    612517    }
    613518
    614519    public Date getDate() {
    615         return this.date;
    616     }
    617     public File getFile() {
    618         return this.file;
    619     }
    620     /** returns the contents of the file */
    621     public String getFileText() {
    622         if (!this.file.exists()) {
    623         return "";
    624         }
    625         StringBuffer contents = new StringBuffer();
    626         try {
    627         BufferedReader in = new BufferedReader(new FileReader(this.file));
    628         String line;
    629 
    630         while ((line = in.readLine()) != null) {
    631             contents.append(line);
    632             contents.append("\n");
    633         }
    634         } catch (FileNotFoundException fnfe) {
    635         Gatherer.println("Error: log file not found: "+ this.file.toString());
    636         return "";
    637         } catch (IOException ioe) {
    638         Gatherer.println("Error: exception occurred when trying to read in file "+this.file.toString()+", "+ioe.getMessage());
    639 
    640         }
    641 
    642         return contents.toString();
    643     }
     520        if(date == null) {
     521        // Need to exclude first '.'
     522        int first_index = filename.indexOf(".") + 1;
     523        // Need to exclude the last '.'
     524        int last_index = filename.lastIndexOf(".");
     525        if(first_index > 0 && last_index > 0 && first_index < last_index) {
     526            String date_string = filename.substring(first_index, last_index);
     527            date = new Date(Long.parseLong(date_string));
     528        }
     529        else {
     530            date = new Date(); // Current date
     531        }
     532        }
     533        return date;
     534    }
     535
     536    public AppendLineOnlyFileDocument getDocument() {
     537        return new AppendLineOnlyFileDocument(filepath);
     538    }
     539
     540    public void reset() {
     541        display = null;
     542    }
     543
    644544    /** we only want the date out of the file name, not the whole path */
    645545    public String toString() {
    646         return this.display;
    647     }
    648     /** creates the display text for the list */
    649     private String createDisplayText() {
    650         StringBuffer d = new StringBuffer();
    651         d.append(date.toString());
    652         //char success= this.file.getName().charAt(23);
    653         String filename = this.file.getName();
    654         int index = filename.lastIndexOf(".") - 1;
    655         if(index >= 0) {
    656             char success = filename.charAt(index);
    657             switch (success) {
    658             case OptionsPane.SUCCESSFUL:
    659             d.append(get("Successful"));
    660             break;
    661             case OptionsPane.UNSUCCESSFUL:
    662             d.append(get("Unsuccessful"));
    663             break;
    664             case OptionsPane.CANCELLED:
    665             d.append(get("Cancelled"));
    666             break;
    667             }
    668         }
    669         return d.toString();
    670     }
    671     /** extracts the date from the file name, which is of the form 'build_log.'<long>[scu]'.txt' */
    672     private Date getDateFromFileName() {
    673         String name = this.file.getName();
    674         // Need to exclude first '.'
    675         int first_index = name.indexOf(".") + 1;
    676         // Need to exclude state letter before last '.'
    677         int last_index = name.lastIndexOf(".") - 1;
    678         if(first_index > 0 && last_index > 0 && first_index < last_index) {
    679         String date_string = name.substring(first_index, last_index);
    680         return new Date(Long.parseLong(date_string));
    681         }
    682         else {
    683         return new Date(); // Current date
    684         }
    685     }
    686 
    687 
    688     }
    689 
    690     /** A DocumentListener that listens for changes in the log_display document
    691      * if a change is registered, the flag is_log_changed is set to true,
    692      * and the listener removes itself from log_display
    693      * Because we only want to register user's changes, the listener must be removed before the system makes any changes, and then put back. For example, each time we switchlogs to display, a remove event and an insert event are sent. We dont want to register these as changes to the document, so the listener must be removed before the switch, and added back afterwards */
    694     private class LogChangeListener implements DocumentListener {
    695 
    696     public void changedUpdate(DocumentEvent e) {
    697         ///ystem.out.println("changed update");
    698         registerChange();
    699     }
    700     public void insertUpdate(DocumentEvent e) {
    701         ///ystem.out.println("insert update");
    702         registerChange();
    703     }
    704     public void removeUpdate(DocumentEvent e) {
    705         ///ystem.out.println("remove update");
    706         registerChange();
    707     }
    708 
    709     private void registerChange() {
    710         ///ystem.err.println("a change in the doc occurred, removing the listener");
    711         is_log_changed = true;
    712         log_display.getDocument().removeDocumentListener(this);
    713     }
    714     }
    715 
    716     /** a ListSelectionListener that triggers the load of a newly selected
    717     log */
     546        File file = new File(filename);
     547        if(display == null) {
     548        last_modified = file.lastModified();
     549        StringBuffer d = new StringBuffer();
     550        Date date = getDate();
     551        d.append(date.toString());
     552        char success = UNKNOWN;
     553        try {
     554            FileInputStream in = new FileInputStream(new File(filepath));
     555            success = (char) in.read();
     556            in.close();
     557            in = null;
     558        }
     559        catch(Exception error) {
     560            error.printStackTrace();
     561        }
     562        switch (success) {
     563        case SUCCESSFUL:
     564            d.append(get("Successful"));
     565            break;
     566        case UNSUCCESSFUL:
     567            d.append(get("Unsuccessful"));
     568            break;
     569        case CANCELLED:
     570            d.append(get("Cancelled"));
     571            break;
     572        default:
     573            d.append(get("Unknown"));
     574        }
     575        display = d.toString();
     576        }
     577        return display;
     578    }
     579    }
     580
     581    /** a ListSelectionListener that triggers the load of a newly selected log */
    718582    private class LogListListener implements ListSelectionListener {
    719583
     
    721585        if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
    722586        JList source  = (JList)e.getSource();
    723         FileEntry fe = (FileEntry) source.getSelectedValue();
    724         loadSelectedLog(fe);
     587        file_entry = (FileEntry) source.getSelectedValue();
     588        // First we determine if the old log has been completely written to file
     589        Document document = log_textarea.getDocument();
     590        if(document instanceof AppendLineOnlyFileDocument) {
     591            AppendLineOnlyFileDocument append_line_only_file_document = (AppendLineOnlyFileDocument) document;
     592            if(append_line_only_file_document.isStillWriting()) {
     593                writing_documents.add(append_line_only_file_document); // We have to maintain a reference until they are all done.
     594                append_line_only_file_document.setOwner(OptionsPane.this);
     595                append_line_only_file_document.setExit();
     596            }
     597        }
     598        // Load the new log
     599        log_textarea.setDocument(file_entry.getDocument());
    725600        }
    726601    }
Note: See TracChangeset for help on using the changeset viewer.