001    package users.stdforms;
002    
003    import users.*;
004    import users.swing.*;
005    import util.swing.JOptionPanel;
006    
007    import sale.*;
008    
009    import javax.swing.*;
010    import javax.swing.event.*;
011    
012    import java.awt.*;
013    import java.awt.event.*;
014    
015    import java.util.*;
016    
017    /**
018     * FormSheet that can be used for log on procedures. The FormSheet will contain a
019     * {@link javax.swing.JComboBox} allowing to select from a range of user names and optionally a password
020     * input line.
021     *
022     * When the user clicks the "OK" button, the FormSheet checks if the password entered equals the
023     * password of the user selected. Prior to this, the password will be garbled using
024     * {@link User#garblePassWD the current global password garbler}. If the checking was successful,
025     * {@link #getResult} will return the selected user, otherwise it will return <code>null</code>.<p>
026     *
027     * <p>A typical use sequence would look something like that:</p>
028     *
029     * <pre>
030     *
031     * ...
032     * <b>LogOnForm lof = new LogOnForm ("Please log on",
033     *                                "Select your user name:",
034     *                                "Enter your password:",
035     *                                true,
036     *                                {@link UserManager#getGlobalUM UserManager.getGlobalUM()},
037     *                                null,
038     *                                null);</b>
039     *
040     * ...setFormSheet (lof);
041     *
042     * if (<b>lof.getResult() != null</b>) {
043     *   // do log on of user lof.getResult
044     * }
045     * ...
046     *
047     * </pre>
048     *
049     * @author Steffen Zschaler
050     * @version 2.0 28/07/1999
051     * @since v2.0
052     */
053    public class LogOnForm extends FormSheet {
054    
055        /**
056             * ID for serialization.
057             */
058            private static final long serialVersionUID = 562705348163092614L;
059    
060            /**
061         * The current user
062         *
063         * @serial
064         */
065        private User m_uCurrent;
066    
067        /**
068         * The current password.
069         *
070         * @serial
071         */
072        private char[] m_sPassword;
073    
074        /**
075         * True, if we asked a password.
076         *
077         * @serial
078         */
079        private boolean m_fAskPassWd;
080    
081        /**
082         * Resulting user.
083         *
084         * @serial
085         */
086        private User m_uLogOnUser;
087        
088        /**
089         * Converst a String to char[]-Array
090         * @param strValue the String to be converted
091         * @return the converted value as char[]-Array
092         */
093        public static char[] getCharFromString(String strValue) {
094            char[] chReturn = new char[strValue.length()];
095            int i;
096            for(i=0;i<strValue.length();i++) {
097                chReturn[i] = strValue.charAt(i);
098            }
099            return chReturn;
100        }
101    
102        /**
103         * Create a new LogOnForm. Uses a {@link FormSheetContentCreator}.
104         *
105         * @param sCaption the caption of the {@link FormSheet}.
106         * @param sUserPrompt a string prompting the user to select his/her user name.
107         * @param sPassWdPrompt  a string prompting the user to enter his/her password. May be <code>null</code>
108         * only if <i>fAskPassWd</i> is false.
109         * @param fAskPassWd if false no password is needed and selection of the user name is sufficient.
110         * @param um the UserManager that manages the users to select from. Normally the
111         * {@link UserManager#getGlobalUM global UserManager}.
112         * @param cmp a comparator that defines the order in which the user names appear. If <code>null</code>,
113         * users will be ordered by their names.
114         * @param uf a filter that allows only a subset of the users to be selected from. If <code>null</code>,
115         * no filtering will occur.
116         */
117        public LogOnForm(String sCaption, final String sUserPrompt, final String sPassWdPrompt,
118                boolean fAskPassWd, final UserManager um, final Comparator<User> cmp, final UserFilter uf) {
119            super(sCaption, (JComponent)null, true);
120    
121            m_fAskPassWd = fAskPassWd;
122    
123            addContentCreator(new FormSheetContentCreator() {
124                            private static final long serialVersionUID = -7167963803488450869L;
125    
126                            protected void createFormSheetContent(FormSheet fs) {
127                    JOptionPanel jop = new JOptionPanel("", 16, 4, JOptionPanel.CENTER, JOptionPanel.CENTER);
128    
129                    UserComboBoxModel ucbmModel = new UserComboBoxModel(um, uf, cmp);
130    
131                    JComboBox jcb = new JComboBox(ucbmModel);
132                    jcb.setRenderer(new JUserList.UserListCellRenderer());
133                    jcb.addItemListener(new ItemListener() {
134                        public void itemStateChanged(ItemEvent e) {
135                            if (e.getStateChange() == ItemEvent.SELECTED) {
136                                m_uCurrent = (User)e.getItem();
137                            } else {
138                                m_uCurrent = null;
139                            }
140                        }
141                    });
142                    jcb.setPreferredSize(new Dimension(120, 20));
143                    
144                    jop.addOption(sUserPrompt, jcb);
145    
146                    if (m_fAskPassWd) {
147                        JTextField jtf = new JPasswordField();
148                        jtf.getDocument().addDocumentListener(new DocumentListener() {
149                            public void changedUpdate(DocumentEvent e) {
150                                try {
151                                    m_sPassword = getCharFromString(e.getDocument().getText(0, e.getDocument().getLength()));
152                                }
153                                catch (javax.swing.text.BadLocationException ex) {}
154                            }
155    
156                            public void insertUpdate(DocumentEvent e) {
157                                try {
158                                    m_sPassword = getCharFromString(e.getDocument().getText(0, e.getDocument().getLength()));
159                                }
160                                catch (javax.swing.text.BadLocationException ex) {}
161                            }
162    
163                            public void removeUpdate(DocumentEvent e) {
164                                try {
165                                    m_sPassword = getCharFromString(e.getDocument().getText(0, e.getDocument().getLength()));
166                                }
167                                catch (javax.swing.text.BadLocationException ex) {}
168                            }
169                        });
170                        jtf.setPreferredSize(new Dimension(120, 20));
171    
172                        jop.addOption(sPassWdPrompt, jtf);
173                    }
174    
175                    fs.setComponent(jop);
176                }
177            });
178        }
179    
180        /**
181         * Return the user that was selected if any. Return <code>null</code> if no user was selected, the password
182         * was wrong or the FormSheet was cancelled. The value is only valid after the FormSheet was closed!
183         *
184         * @override Never
185         */
186        public User getResult() {
187            return m_uLogOnUser;
188        }
189    
190        /**
191         * Overridden to check the password input and make sure the selected user can be returned by
192         * {@link #getResult}.
193         *
194         * @override Never
195         */
196        public void ok() {
197            if (m_uCurrent != null) {
198                // If no input occurred, the password string is null. We don't want to run into a
199                // NullPointerException, so we come up with a dummy password.
200                if (m_sPassword == null) {
201                    m_sPassword = new char[0];
202                }
203                if ((!m_fAskPassWd) || (m_uCurrent.isPassWd(User.garblePassWD(m_sPassword)))) {
204                    m_uLogOnUser = m_uCurrent;
205                }
206            }
207    
208            super.ok();
209        }
210    }