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