Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

/**
 * AntShield - A project release tool for ant.
 */
package com.erggroup.mass.ant;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.util.*;
import java.awt.*;
import java.awt.event.*;

/**
 * AntShieldReleaseFrame
 * A dialog box that allows users to select an allowed project
 * and release for a specified package.
 */
public class AntShieldReleaseFrame extends JFrame {

    private String name = null;
    private String type = null;
    private String project = new String();
    private String release = new String();
    private String releaseLabelString;
    private String titleString;
    private ArrayList projects = new ArrayList();
    private ArrayList releases = new ArrayList();
    private JComboBox projectBox = new JComboBox();
    private JComboBox releaseBox = new JComboBox();

    private boolean ok = false;
    private boolean undo = false;
    private AntShieldLock lock = new AntShieldLock();

    /**
     * Constructor.  Populate projects and releases with supplied
     * parameters, build the dialog box, and display self.
     * @param pkgname
     * @param reltype
     * @param rellist
     */
    public AntShieldReleaseFrame(String pkgname, String reltype, ArrayList rellist, boolean undoflag)
    {
        name = pkgname;
        type = reltype;
        undo = undoflag;

        if (undo)
        {
            titleString = new String("Antshield Existing Release - Package \"" + name + "\"");
            releaseLabelString = new String("Existing release");
        }
        else
        {
            titleString = new String("Antshield New Release - Package \"" + name + "\"");
            releaseLabelString = new String("New release");
        }
        Iterator i = rellist.iterator();
        while (i.hasNext())
        {
            String rel = (String)i.next();
            String proj = rel.substring(rel.lastIndexOf(".")+1).trim();
            releases.add(rel);
            int n = projects.size();
            boolean haveIt = false;
            for (int j = 0; j < n; j++)
            {
                String s = (String)projects.get(j);
                if (s.equals(proj))
                {
                    haveIt = true;
                    break;
                }
            }
            if (!haveIt)
            {
                projects.add(proj);
            }
        }

        init();
        setPosition();
        updateProjects();
        updateReleases();
        pack();
        setVisible(true);
        lock.acquire();
    }

    /**
     * Build this frame from components.
     */
    private void init()
    {
        setTitle(titleString);

        // Proper close if the user closes the window.
        addWindowListener(new AntShieldReleaseWindowClose(this));

        // OK button.
        JButton okButton = new JButton();
        okButton.setActionCommand("OK");
        okButton.setText("OK");
        okButton.addActionListener(new AntShieldReleaseOKAction(this));

        // Cancel button.
        JButton cancelButton = new JButton();
        cancelButton.setActionCommand("Cancel");
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new AntShieldReleaseCancelAction(this));

        // Labels.
        JLabel projectLabel = new JLabel("Project");
        projectLabel.setPreferredSize(new Dimension(120, 25));
        JLabel typeLabel = new JLabel("Release Type");
        typeLabel.setPreferredSize(new Dimension(120, 25));
        JLabel releaseLabel = new JLabel(releaseLabelString);
        releaseLabel.setPreferredSize(new Dimension(120, 25));

        // Handle changes in project combo box.
        projectBox.addActionListener(new AntShieldReleaseProjectAdapter(this));

        // Allow user entry in project combo box.
        projectBox.setEditable(true);

        // Allow user entry in release combo box.
        releaseBox.setEditable(true);

        // Release-type radio buttons.
        JRadioButton majorButton = new JRadioButton("Major");
        majorButton.addActionListener(new AntShieldReleaseMajorAdapter(this));

        JRadioButton minorButton = new JRadioButton("Minor");
        minorButton.addActionListener(new AntShieldReleaseMinorAdapter(this));

        JRadioButton patchButton = new JRadioButton("Patch");
        patchButton.addActionListener(new AntShieldReleasePatchAdapter(this));

        ButtonGroup typeGroup = new ButtonGroup();
        typeGroup.add(majorButton);
        typeGroup.add(minorButton);
        typeGroup.add(patchButton);
        if (type.equals("major"))
          majorButton.setSelected(true);
        else if (type.equals("minor"))
          minorButton.setSelected(true);
        else
          patchButton.setSelected(true);

        // Release-type panel.
        JPanel typePanel = new JPanel();
        typePanel.setLayout(new GridLayout(3,1));
        typePanel.setBorder(new EtchedBorder());
        typePanel.add(majorButton);
        typePanel.add(minorButton);
        typePanel.add(patchButton);

        // South-east panel - holds the OK and Cancel buttons.
        JPanel sePanel = new JPanel();
        sePanel.add(okButton, null);
        sePanel.add(cancelButton, null);

        // South panel - holds south-east panel
        JPanel southPanel = new JPanel();
        southPanel.setLayout(new BorderLayout());
        southPanel.setBorder(new EtchedBorder());
        southPanel.add(sePanel, BorderLayout.EAST);

        // Format everything with nice indentation
        Box box2 = new Box(BoxLayout.X_AXIS);
        box2.add(Box.createHorizontalStrut(50));
        box2.add(projectLabel);
        box2.add(Box.createHorizontalStrut(10));
        box2.add(projectBox);
        box2.add(Box.createHorizontalStrut(50));

        Box box3 = new Box(BoxLayout.X_AXIS);
        if (!undo)
        {
            box3.add(Box.createHorizontalStrut(50));
            box3.add(typeLabel);
            box3.add(Box.createHorizontalStrut(10));
            box3.add(typePanel);
            box3.add(Box.createHorizontalStrut(50));
        }

        Box box4 = new Box(BoxLayout.X_AXIS);
        box4.add(Box.createHorizontalStrut(50));
        box4.add(releaseLabel);
        box4.add(Box.createHorizontalStrut(10));
        box4.add(releaseBox);
        box4.add(Box.createHorizontalStrut(50));

        Box box5 = new Box(BoxLayout.Y_AXIS);
        box5.add(Box.createVerticalStrut(50));
        box5.add(box2);
        box5.add(Box.createVerticalStrut(10));
        box5.add(box3);
        box5.add(Box.createVerticalStrut(10));
        box5.add(box4);
        box5.add(Box.createVerticalStrut(50));

        // Keep our components centred and top-justified
        JPanel centrePanel = new JPanel();
        centrePanel.setLayout(new BorderLayout());
        centrePanel.setBorder(new EtchedBorder());
        centrePanel.add(box5, BorderLayout.NORTH);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(southPanel, BorderLayout.SOUTH);
        getContentPane().add(centrePanel, BorderLayout.CENTER);

        // Hitting ENTER activates the OK button
        getRootPane().setDefaultButton(okButton);

        pack();
    } // init

    /**
     * Position this frame in the centre of the screen,
     * resizing if necessary.
     */
    private void setPosition()
    {
        int scrnWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int scrnHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        int width = getWidth();
        int height = getHeight();
        if (width > scrnWidth/2)
        {
            width = scrnWidth/2;
        }
        if (width < scrnWidth/8)
        {
            width = scrnWidth/8;
        }
        if (height > scrnHeight/2)
        {
            height = scrnHeight/2;
        }
        if (height < scrnHeight/8)
        {
            height = scrnHeight/8;
        }
        setSize(width, height);
        int xpos = scrnWidth/2 - width/2;
        int ypos = scrnHeight/2 - height/2;
        setLocation(xpos, ypos);
    } // setPosition

    /**
     * Handle the OK button by verifying everything.  Pop up
     * a dialog if all isn't well.
     */
    public void handleOk()
    {
        String proj = (String)projectBox.getSelectedItem();
        String rel = (String)releaseBox.getSelectedItem();
        if ((proj == null) || (proj.trim().length() < 1))
        {
            new AntShieldRetryDialog("A project must be specified.");
        }
        else if ((rel == null) || (rel.trim().length() < 1))
        {
            new AntShieldRetryDialog("A release must be specified.");
        }
        else if (!verifyReleaseNumber()) //ignore this if in undo mode
        {
            String msg = new String("Release '");
            msg += rel;
            msg += "' is invalid for project '";
            msg += proj;
            msg += "'.";
            new AntShieldRetryDialog(msg);
        }
        else
        {
            ok = true;
            close();
        }
    } // handleOk

    /**
     * Handle the cancel button.
     */
    public void handleCancel()
    {
        ok = false;
        close();
    } // handleCancel

    /**
     * Handle changes to the project combo box, especially
     * trimming any manually entered project to 3 characters max.
     */
    public void handleProject() {
        project = ((String)projectBox.getSelectedItem()).trim();
        if (!projects.contains(project) && (project.length() > 3))
        {
            project = project.substring(0, 3);
            projectBox.setSelectedItem(project);
        }
        updateReleases();
    } // handleProject

    /**
     * Handle the major radio button.
     * Change the release type to major.
     */
    public void handleMajor() {
        type = "major";
        updateReleases();
    } // handleMajor

    /**
     * Handle the minor radio button.
     * Change the release type to minor.
     */
    public void handleMinor() {
        type = "minor";
        updateReleases();
    } // handleMinor

    /**
     * Handle the patch radio button.
     * Change the release type to patch.
     */
    public void handlePatch() {
        type = "patch";
        updateReleases();
    } // handlePatch

    /**
     * Return the selected release in the form "x.y.z.proj".
     * @return
     */
    public String getRelease()
    {
        return release;
    } // getRelease

    /**
     * Did we exit successfully?
     * @return
     */
    public boolean isOk()
    {
        return ok;
    } // isOk

    /**
     * Close this frame.
     */
    public void close()
    {
        lock.release();
        setVisible(false);
    } // close

    /**
     * Check that the currently selected release is of the form
     * "<int>.<int>.<int>", and that it isn't already in the list
     * of existing releases (unless undo is true).
     * @return
     */
    private boolean verifyReleaseNumber()
    {
        boolean status = false;
        String s = (String)releaseBox.getSelectedItem();
        int i1 = s.indexOf('.');
        int i2 = s.indexOf('.', i1+1);
        if ((i1 > 0) && (i2 > i1) && (s.lastIndexOf('.') == i2))
        {
            try
            {
                Integer major = new Integer(s.substring(0, i1).trim());
                Integer minor = new Integer(s.substring(i1+1, i2).trim());
                Integer patch = new Integer(s.substring(i2+1).trim());
                release = new String();
                release += major.toString();
                release += ".";
                release += minor.toString();
                release += ".";
                release += patch.toString();
                release += ".";
                release += project;

                if (undo)
                {

//                     if ((release.indexOf('-') < 0) && releases.contains(release))
//                     {
                         status = true;
//                     }
                }
                else
                {
                    if ((release.indexOf('-') < 0) && !releases.contains(release) && !release.substring(0,5).equals("0.0.0"))
                    {
                        status = true;
                    }

                }
            }
            catch (NumberFormatException e)
            {
                ;  // do nothing
            }
        }
        return status;
    } // verifyReleaseNumber

    /**
     * Populate the project combo box.
     */
    private void updateProjects()
    {
        projectBox.removeAllItems();
        Iterator i = projects.iterator();
        while (i.hasNext())
        {
            projectBox.addItem(i.next());
        }
        project = (String)projectBox.getSelectedItem();
    } // updateProjects

    /**
     * Populate the release combo box with the allowed releases
     * (if any) for the current project and release type.  Select
     * the highest release by default.
     */
    private void updateReleases()
    {
        releaseBox.removeAllItems();
        if ((project != null) && (project.length() > 0))
        {
            if (undo)
                updateUndoReleases();
            else if (type.equals("major"))
                updateMajorReleases();
            else if (type.equals("minor"))
                updateMinorReleases();
            else
                updatePatchReleases();
        }
        if (releaseBox.getItemCount() > 0)
        {
            releaseBox.setSelectedIndex(releaseBox.getItemCount()-1);
        }
    } // updateReleases

    /**
     * Populate the release combo box with the allowed undo releases
     * for the current project.
     */
    private void updateUndoReleases()
    {
        TreeSet set = new TreeSet();
        Iterator i = releases.iterator();
        while (i.hasNext())
        {
            String s = (String)i.next();
            int j = s.lastIndexOf('.')+1;
            String proj = s.substring(j).trim();
            if (proj.equals(project))
            {
                set.add(s.substring(0, j-1).trim());
                //releaseBox.addItem(s.substring(0, j-1).trim());
            }
        }
        i = set.iterator();
        while (i.hasNext())
        {
            releaseBox.addItem(i.next());
        }
    } // updateUndoReleases

    /**
     * Populate the release combo box with the allowed major release
     * for the current project.
     */
    private void updateMajorReleases()
    {
        int currentMajor = 0;
        Iterator i = releases.iterator();
        while (i.hasNext())
        {
            String s = (String)i.next();
            String proj = s.substring(s.lastIndexOf('.')+1).trim();
            if (proj.equals(project))
            {
                int m = new Integer(s.substring(0,s.indexOf('.')).trim()).intValue();
                if (m > currentMajor)
                    currentMajor = m;
            }
        }
        String r = new String(new Integer(currentMajor+1).toString());
        r += ".0.0";
        releaseBox.addItem(r);
    } // updateMajorReleases

    /**
     * Populate the release combo box with the allowed minor releases
     * for the current project.
     */
    private void updateMinorReleases()
    {
        TreeMap majors = new TreeMap();
        Iterator i = releases.iterator();
        while (i.hasNext())
        {
            String s = (String)i.next();
            String proj = s.substring(s.lastIndexOf('.')+1).trim();
            if (proj.equals(project))
            {
                int i1 = s.indexOf('.');
                int i2 = s.indexOf('.', i1+1);
                Integer k = new Integer(s.substring(0, i1).trim());
                Integer v = new Integer(s.substring(i1+1, i2).trim());
                if (majors.containsKey(k))
                {
                    Integer w = (Integer)majors.get(k);
                    if (w.intValue() < v.intValue())
                    {
                        majors.put(k, v);
                    }
                }
                else
                {
                    majors.put(k, v);
                }
            }
        }
        Set kset = majors.keySet();
        Iterator j = kset.iterator();
        while (j.hasNext())
        {
            Integer k = (Integer)j.next();
            String r = k.toString();
            r += ".";
            r += new Integer(((Integer)majors.get(k)).intValue() + 1).toString();
            r += ".0";
            releaseBox.addItem(r);
        }
        if (releaseBox.getItemCount() == 0)
        {
            releaseBox.addItem(new String("0.1.0"));
        }
    } // updateMinorReleases

    /**
     * Populate the release combo box with the allowed patch releases
     * (if any) for the current project.
     */
    private void updatePatchReleases()
    {
        TreeMap majors = new TreeMap();
        Iterator i = releases.iterator();
        while (i.hasNext())
        {
            String s = (String)i.next();
            String proj = s.substring(s.lastIndexOf('.')+1).trim();
            if (proj.equals(project))
            {
                int i1 = s.indexOf('.');
                int i2 = s.indexOf('.', i1+1);
                int i3 = s.indexOf('.', i2+1);
                Integer maj = new Integer(s.substring(0, i1).trim());
                Integer min = new Integer(s.substring(i1+1, i2).trim());
                Integer pat = new Integer(s.substring(i2+1, i3).trim());
                if (majors.containsKey(maj))
                {
                    TreeMap minors = (TreeMap)majors.get(maj);
                    if (minors.containsKey(min))
                    {
                        Integer w = (Integer)minors.get(min);
                        if (w.intValue() < pat.intValue())
                        {
                            minors.put(min, pat);
                        }
                    }
                    else
                    {
                        minors.put(min, pat);
                    }
                }
                else
                {
                    TreeMap minors = new TreeMap();
                    minors.put(min, pat);
                    majors.put(maj, minors);
                }
            }
        }
        Set kset1 = majors.keySet();
        Iterator j1 = kset1.iterator();
        while (j1.hasNext())
        {
            Integer maj = (Integer)j1.next();
            TreeMap minors = (TreeMap)majors.get(maj);
            Set kset2 = minors.keySet();
            Iterator j2 = kset2.iterator();
            while (j2.hasNext())
            {
                Integer min = (Integer)j2.next();
                String r = new String(maj.toString());
                r += ".";
                r += min.toString();
                r += ".";
                r += new Integer(((Integer)minors.get(min)).intValue() + 1).toString();
                releaseBox.addItem(r);
            }
        }
        if (releaseBox.getItemCount() == 0)
        {
            releaseBox.addItem(new String("0.0.1"));
        }
    } // updatePatchReleases
}

class AntShieldReleaseMajorAdapter implements ActionListener
{
    private AntShieldReleaseFrame adaptee;

    public AntShieldReleaseMajorAdapter(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handleMajor();
    }
}

class AntShieldReleaseMinorAdapter implements ActionListener
{
    private AntShieldReleaseFrame adaptee;

    public AntShieldReleaseMinorAdapter(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handleMinor();
    }
}

class AntShieldReleasePatchAdapter implements ActionListener
{
    private AntShieldReleaseFrame adaptee;

    public AntShieldReleasePatchAdapter(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handlePatch();
    }
}

class AntShieldReleaseProjectAdapter implements ActionListener
{
    private AntShieldReleaseFrame adaptee;

    public AntShieldReleaseProjectAdapter(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handleProject();
    }
}

class AntShieldReleaseOKAction implements ActionListener
{
    AntShieldReleaseFrame adaptee;

    public AntShieldReleaseOKAction(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handleOk();
    }
}

class AntShieldReleaseCancelAction implements ActionListener
{
    AntShieldReleaseFrame adaptee;

    public AntShieldReleaseCancelAction(AntShieldReleaseFrame a)
    {
        adaptee = a;
    }

    public void actionPerformed(ActionEvent e)
    {
        adaptee.handleCancel();
    }
}

class AntShieldReleaseWindowClose extends WindowAdapter
{
    private AntShieldReleaseFrame parent;

    public AntShieldReleaseWindowClose(AntShieldReleaseFrame a)
    {
        parent = a;
    }

    public void windowClosing(WindowEvent e)
    {
        parent.close();
    }
}