[Webfunds-commits] java/webfunds/client/utils Backup.java BinaryButtons.java Startup.java

Ian Grigg iang@cypherpunks.ai
Sun, 24 Sep 2000 17:51:10 -0400 (AST)


iang        00/09/24 17:51:10

  Added:       webfunds/client/utils Backup.java BinaryButtons.java
                        Startup.java
  Log:
  Written to do backups and recovery of WebFunds user directory.
  Original backup code taken from AccountBrowserImpl, recovery
  code is new, as is BinaryButtons (select One ExOR Two) and
  Startup.  Missing user directory on startup can now be interpreted
  as recovery opportunity as well as new user case.
  Swing in Startup is ... clumsy.

Revision  Changes    Path
1.1                  java/webfunds/client/utils/Backup.java

Index: Backup.java
===================================================================
/*
 * $Id: Backup.java,v 1.1 2000/09/24 21:51:09 iang Exp $
 *
 * Copyright (C) 2000 Systemics Inc. on behalf of 
 * the WebFunds Development Team. All rights reserved.
 */

package webfunds.client.utils;


import java.io.*;
import javax.swing.*;

import webfunds.client.UInterface;


/**
 * Helper functions dealing with Backups and Restores
 *
 */
public final class Backup
{
    /** Static methods only. */
    private Backup() {}

    private static final String B = "    B/r: ";
    protected static void logmsg(String s) { System.err.println( B + s); }

    public static final String BACKUP_DIR = "WF_";

    /**
     *  Kludge attempt at making a backup.
     *
     *  None of this belongs here, it needs a home elsewhere...
     *
     *  @param srcDir is the current directory where entire app is installed
     */
    public static void backup(UInterface ui, File srcDir)
    {
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        fc.setDialogTitle("Select Directory where you wish to Backup into");

        //
        //  Make a directory.  If we fail to make, keep trying!
        //
        boolean ok = false;
        File targetDir = null;
        while (!ok)
        {
            int res = fc.showDialog(new JFrame(), "Select Backup Dir");
            if (res != JFileChooser.APPROVE_OPTION)
                return ;

            File choice = fc.getSelectedFile();

            String name = choice.getName();
            if (name.startsWith(BACKUP_DIR))
            {
                ui.errorMessage("This is a Backup Directory already: " +
                                "\n\n      " + name +
                                "\n\nPlease select another!" +
                                "");
                continue ;
            }

            logmsg("Chose backup dir: " + choice);
            targetDir =
                new File(choice, BACKUP_DIR + System.currentTimeMillis());

            ok = targetDir.mkdir();
            if (!ok)
                ui.errorMessage("could not make Directory: " +
                                "\n\n      " + targetDir +
                                "\n\nPlease select another!" +
                                "");
        }

        //
        //  Now copy the source directory into the backup directory.
        //
        try
        {
            webfunds.client.utils.FileUtils.copyTree(srcDir, targetDir);

            ui.infoMessage("Backup Complete");
            return ;
        }
        catch (IOException ex)
        {
            ui.errorMessage("BACKUP FAILED!" +
                            "\n\n      " + ex +
                            "\n\nCheck " + targetDir + " for remains.");
        }
    }

    /**
     *  Generate a string in a sequence of name-[A-Z] where the new
     *  name is the first that doesn't already exist.
     */
    private static String getSaveName(String name)
    {
        final char separator = '-';
        char       letter    = 'A';

        while (letter <= 'Z')
        {
            String tryMe = name + separator + letter++;
            File f = new File(tryMe);
            if (!f.exists())
                return tryMe ;
        }
        return null ;
    }

    /**
     *  Kludge attempt at recovering a backup.
     *  Note that targetDir is not the same as the backup() paramater.
     *
     *  @param targetDir is the user directory where data is stored
     */
    public static void recover(UInterface ui, File targetDir)
    {
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        fc.setDialogTitle("Select Directory where you wish to Recover from");

        String userName = targetDir.getName();
        //
        //  Find a backup source directory.  If we fail to make, keep trying!
        //
        boolean ok = false;
        File backupDir = null;
        File parent;
        File child = null;
        while (child == null)
        {
            int res = fc.showDialog(new JFrame(), "Select Backup Dir");
            if (res != JFileChooser.APPROVE_OPTION)
                return ;

            File choice = fc.getSelectedFile();

            logmsg("Selecting backup dir: " + choice);
            String name = choice.getName();
            if (name.startsWith(BACKUP_DIR))
            {
                parent = choice;
                child = new File(parent, userName);
            }
            else if (name.equals(userName))
            {
                String parentPath = choice.getParent();
                parent = new File(parentPath);
                String parentName = parent.getName(); 
                if (!parentName.startsWith(BACKUP_DIR))
                {
                    String q = "Parent is not recognised as a WebFunds backup?"+
                               "\n\n" +
                               "        " + parentName +
                               "\n\n" +
                               "Continue recovery from selected directory?";
                    if (ui.getYesNo(q) != UInterface.YES)
                        continue ;
                }
                child = choice;
            }
            else
            {
                ui.errorMessage("not a recognised WebFunds Backup: " +
                                "\n\n      " + choice.getPath() +
                                "\n\nPlease select another!" +
                                "");
            }
        }

        /*
         *  At this stage, we should have identified an acceptable
         *  'user' directory in child, all within the parent backup,
         *  which hopefully represents a good backup.
         *
         *  Now, identify the target directory, which is where we
         *  recover the backup into.  If there is already something
         *  there, move it.
         *
         *  Gotta be careful here, might be a Windows user doing this.
         */
        String ouch = "\n\nPlease clean up and try again!";
        String saveName = getSaveName(targetDir.getPath());
        if (saveName == null)
        {
            ui.errorMessage("can not save existing " +
                                  userName + " directory, " +
                            ouch);
            return ;
        }

        if (targetDir.exists())
        {
            targetDir.renameTo(new File(saveName));
            logmsg("hmm, what is targetDir ... " + targetDir);
            if (targetDir.exists())
            {
                ui.errorMessage("could not move existing " +
                                      userName + " directory to " +
                                      saveName + " ," +
                                ouch);
                return ;
            }
        }

        String targetParentName = targetDir.getParent();
        if (targetParentName == null && (userName.indexOf(File.separator) < 0))
        {
            logmsg("userName " + userName + " has no parent, using dot");
            targetParentName = ".";
        }

        //
        //  Now copy the source backup user directory into local dir.
        //
        try {
            FileUtils.copyTree(child, new File(targetParentName));

        } catch (IOException ex) {
            ui.errorMessage("RECOVERY FAILED!" +
                            "\n\n      " + ex +
                            "\n\nCheck " + targetDir.getName() +
                                           " for remnants." +
                            "\n\nCheck " + saveName +
                                           " for your pre-existing data." +
                            ouch);
            return ;
        }

        ui.infoMessage("Recovery Complete");
        return ;
    }

}



1.1                  java/webfunds/client/utils/BinaryButtons.java

Index: BinaryButtons.java
===================================================================
/*
 * $Id: BinaryButtons.java,v 1.1 2000/09/24 21:51:09 iang Exp $
 *
 * Copyright (c) 2000 Systemics Inc. on behalf of
 * the WebFunds Development Team. All rights reserved.
 */

package webfunds.client.utils;
import java.io.File;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class BinaryButtons
    extends JPanel
{
    static JFrame frame;

    protected JRadioButton oneButton;
    protected JRadioButton twoButton;

    protected boolean oneDefault = false;
    protected boolean twoDefault = false;

    protected boolean isFixed = false;

    protected String oneLabel;
    protected int    oneLetter;
    protected String twoLabel;
    protected int    twoLetter;

    RadioListener myListener;



    public BinaryButtons(
                   String oneLabel, int oneLetter, boolean oneDefault,
                   String twoLabel, int twoLetter, boolean twoDefault)
    {
        this.oneLabel = oneLabel;
        this.oneLetter = oneLetter;
        this.oneDefault = oneDefault;
        this.twoLabel = twoLabel;
        this.twoLetter = twoLetter;
        this.twoDefault = twoDefault;

        makeStuff();
    }



    public JRadioButton newButton(String s, int letter)
    {
        JRadioButton button = new JRadioButton(s);
        button.setMnemonic(letter);
        button.setActionCommand(s);
        button.addActionListener(myListener);

        return button ;
    }


    public void setDefaults()
    {
        oneButton.setSelected(oneDefault);
        one = oneDefault;
        twoButton.setSelected(twoDefault);
        two = twoDefault;
    }

    /** Can never change. */
    public void setFixed()
    {
        isFixed = true;
    }


    public void makeStuff()
    {

        myListener = new RadioListener();
        // Create the radio buttons.
        oneButton = newButton(oneLabel, oneLetter);
        twoButton = newButton(twoLabel, twoLetter);

        setDefaults();

        // Group the radio buttons.
        ButtonGroup group = new ButtonGroup();

        group.add(oneButton);
        group.add(twoButton);

        // Put the radio buttons in a column in a panel
        // panel = new JPanel();
        this.setLayout(new GridLayout(0, 1));
        this.add(oneButton);
        this.add(twoButton);
    }   
    
    public void init()
    {
        setDefaults();
    }

    public boolean ready()     { return (one||two); }
    public boolean isOne()     { return one ; }
    public boolean isTwo()     { return two ; }

    protected boolean one = false;
    protected boolean two = false;

    protected void setButton(String button)
    {
        if (oneLabel.equals(button))
            { one = true; two = false; }
        if (twoLabel.equals(button))
            { two = true; one = false; }
    }

    protected void logmsg(String s) { System.err.println("         bb: " + s); }

    /** Listens to the radio buttons. */
    class RadioListener
        implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String button = e.getActionCommand();
            // logmsg("e: " + button);

            if (isFixed)
            {
                setDefaults();
                logmsg("ignored.");
            }
            else
                setButton(button);
        }
    }

    public static void main(String s[])
    {
         frame = new JFrame("Binary Buttons Demo");
         frame.addWindowListener(new WindowAdapter()
         {
             public void windowClosing(WindowEvent e) {System.exit(0);}
         });
 
         JPanel pane = (JPanel)frame.getContentPane();
         BinaryButtons butt = new BinaryButtons(
                                "Primero", KeyEvent.VK_P, true,
                                "Segundo", KeyEvent.VK_S, false);

         butt.setFixed();
         butt.init();

         pane.add(butt, BorderLayout.CENTER);
         frame.pack();
         frame.setVisible(true);
    }
}




1.1                  java/webfunds/client/utils/Startup.java

Index: Startup.java
===================================================================
/*
 * $Id: Startup.java,v 1.1 2000/09/24 21:51:09 iang Exp $
 *
 * Copyright (C) 2000 Systemics Inc. on behalf of 
 * the WebFunds Development Team. All rights reserved.
 */

package webfunds.client.utils;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import webfunds.client.UInterface;


/**
 *  Startup dialog to recover a user directory from a backup,
 *  (or, indicates this is a new user).
 *
 *  Inspired by ContractChooser.
 */
public final class Startup
    extends JDialog implements ActionListener
{

    protected void logmsg(String s) { System.err.println("Startup: " + s); }


    public static final String        CANCEL    = "Cancel",
                                      OK        = "OK",
                                      RECOVER   = "Recover",
                                      NEW_USER  = "New User";


    JButton buttonOK     = new JButton(OK);
    JButton buttonCancel = new JButton(CANCEL);

    BinaryButtons choice = null;

    public Startup()
    {
        super (new JFrame(), "Startup - Select User Recovery", true);

        choice = new BinaryButtons(
                           RECOVER, KeyEvent.VK_R, false,
                           NEW_USER, KeyEvent.VK_N, false
                           );

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(buttonCancel);
        buttonPanel.add(buttonOK);

        JLabel lab = new JLabel("<html><font size='-1'><b>"+
                "<p>"+
                "</p><p>"+
                "There is no user directory."+
                "</p><p>"+
                "</p><p>"+
                "Do you wish to start with a new user, "+
                "or to recover from an existing user?"+
                "</p>"+
                         "</b></font></html>");
        
        Container pane = this.getContentPane();
        pane.setLayout(new BorderLayout());
        pane.add("North", lab);
        pane.add("Center", choice);
        pane.add("South", buttonPanel);

        // this.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));

        buttonOK.addActionListener(this);
        buttonCancel.addActionListener(this);


        this.pack();
        this.setSize(400, 200);
    }


    public void actionPerformed(ActionEvent e)
    {
        result = e.getActionCommand();
        if (result.equals(OK))
        {
            if (!choice.ready())
                return ;

            if (choice.isOne())
            {
                logmsg(" recovery");
                result = RECOVER;
                // warning - this "knows" about the file structure.
                Backup.recover(new webfunds.client.UInterfaceImpl(),
                              webfunds.client.Core.userDir);
            }
            else
            {
                result = NEW_USER;
                logmsg(" new user");
            }
        }
        else if (result.equals(CANCEL))
        {
             logmsg(" Cancel!");
        }
        else
        {
             logmsg(" what is this: " + result);
             return ;
        }

        dispose();
    }

    String result;

    /**
     *
     *  @return a string indicating what choice the user has taken
     *          CANCEL - expect to shutdown forthwith.
     *          NEW_USER - caller to set up a fresh user.
     *          RECOVER - those method has completed a recovery.
     */
    public final String showDialog()
    {
        this.setVisible(true);
        return this.result;
    }

// Test / Debugging
// ...........................................................................

    public static void main(String[] argv) throws Exception
    {
        System.err.println("Startup Test");
        System.err.println();

        String result = OK;
        while (!CANCEL.equals(result))
        {
            Startup startup = new Startup();
            result = startup.showDialog();
            System.err.println("Chosen: " + result);
        }
        System.exit(0);
    }

}