001    /** =====================================================================       
002    *
003    *  File Name : $Id: LoginPanel.java,v 1.10 2008/01/15 11:08:16 cb Exp $
004    *
005    *  Description
006    *  -----------
007    *
008    *  See javadoc comment 
009    * 
010    *  =====================================================================
011    *
012    *   @Author : Craige Bevil 
013    *             Control Software Group
014    *             Isaac Newton Group of Telescopes
015    *
016    *  =====================================================================
017    *
018    *     Modification Log
019    *
020    *     Vers         Date        Author       Reason
021    *     ----         ----        ------       ------
022    *      1                       C.Bevil      First Release
023    *
024    *     Commissioning Notes
025    *     -------------------
026    *
027    *     None
028    *     
029    *  =====================================================================
030    *
031    *     @Version   : $Id: LoginPanel.java,v 1.10 2008/01/15 11:08:16 cb Exp $
032    *
033    *     @Author    : $Author: cb $
034    *
035    *     Header     : $Header: /opt/INGsrc/src/CVS/softproj/FaultDatabase/src/FaultDatabase/FaultDatabase/src/GWTApplication/client/LoginPanel.java,v 1.10 2008/01/15 11:08:16 cb Exp $
036    *
037    *     Log        : $Log: LoginPanel.java,v $
038    *     Log        : Revision 1.10  2008/01/15 11:08:16  cb
039    *     Log        : Ran through PMD and sorted out the javadoc so that we could export the
040    *     Log        : javadoc to the javadoc repository.
041    *     Log        :
042    *     Log        : Revision 1.9  2007/10/19 08:52:14  cb
043    *     Log        : Updated so that the cookie storing the printer name does not expire at
044    *     Log        : the end of the browser session.
045    *     Log        :
046    *     Log        : Revision 1.8  2007/09/05 08:16:28  cb
047    *     Log        : Tidied up a little, no functional change
048    *     Log        :
049    *     Log        : Revision 1.7  2007/08/23 15:28:41  cb
050    *     Log        : Sorted out the tabs
051    *     Log        :
052    *     Log        : Revision 1.6  2007/08/16 12:44:54  cb
053    *     Log        : Removed cookies if the user has requested that the credentials are not
054    *     Log        : stored on the client.
055    *     Log        :
056    *     Log        : Revision 1.5  2007/08/14 09:27:43  cb
057    *     Log        : Modified so that the state of the remember credential box is stored as
058    *     Log        : a cookie
059    *     Log        :
060    *     Log        : Revision 1.4  2007/08/14 09:03:36  cb
061    *     Log        : Changed after PMD session. Responds to <return> key now when the user
062    *     Log        : presses it.
063    *     Log        :
064    *     Log        : Revision 1.3  2007/08/01 13:00:06  cb
065    *     Log        : First prototype after import
066    *     Log        :
067    *     Log        : Revision 1.2  2007/07/13 10:54:06  cb
068    *     Log        : Complete interface prototype
069    *     Log        :
070    *     Log        : Revision 1.1.1.1  2007/06/01 08:33:26  cb
071    *     Log        : Imported using TkCVS
072    *     Log        :
073    *
074    * =====================================================================*/
075    
076    package GWTApplication.client;
077    
078    import com.google.gwt.user.client.*;
079    import com.google.gwt.user.client.rpc.*;
080    import com.google.gwt.user.client.ui.*;
081    import com.google.gwt.user.client.ui.DockPanel.*;
082    
083    import com.gwtext.client.core.EventObject;
084    import com.gwtext.client.util.Format;
085    import com.gwtext.client.widgets.MessageBox;
086    import com.gwtext.client.widgets.MessageBoxConfig;
087    
088    import com.google.gwt.user.client.ui.FlexTable.*;
089    import java.util.*;
090    
091    /**
092     * This class will be used to permit the user to authenticate himself
093     * with the new system. It presents an interface which the user can
094     * use to input the details of his userid and password. The
095     * credentials will then be authenticated by the servlet and his
096     * priviledges will be returned.
097     * 
098     * @author Craige Bevil 
099     * @version $Id: LoginPanel.java,v 1.10 2008/01/15 11:08:16 cb Exp $
100     */
101    
102    class LoginPanel extends FaultDBForm implements ClickListener, KeyboardListener {
103    
104        /**
105         * Widget which is used to allow the user to store the details of
106         * his logon id as a cookie on his machine
107         */
108        
109        private CheckBox StoreLoginCredentialsCheckBox;
110        
111        /**
112         * This is the authentication data which is associated with the
113         * user which will be returned by the sevlet once the user has
114         * authenticated himself.
115         */
116        
117        private AuthenticationDetails UserAuthentication;
118    
119        /**
120         * This is the button which the user will use to log onto the
121         * system. 
122         */
123        
124        final private Button LoginButton;
125    
126        /**
127         * The user can press this button to log into the system if he
128         * does not have a user id or password
129         */
130    
131        final private Button LoginNoIdButton;
132         
133        /** 
134         * This is the service which will be used to access the database.
135         */
136    
137        final private FaultServiceAsync svc;
138        
139        /**
140         * This will contain all of the fields in which the user will
141         * enter his log on credentials
142         */
143    
144        final private FlexTable LoginTable = new FlexTable();
145        
146        /**
147         * This is the main panel into which we will pack everything 
148         */
149        
150        final private VerticalPanel UserLoginPanel = new VerticalPanel();
151        
152        /**
153         * This is the dock panel which will be used for holding all of
154         * elements in the display
155         */
156        
157        final private DockPanel MainPanel = new DockPanel();
158    
159        /**
160         * This is the text box widget which the user will use to enter
161         * his user name
162         */
163        
164        TextBox UserIdentifierWidget;
165    
166        /**
167         * This is the text box widget which the user will use to enter
168         * his password
169         */
170        
171        PasswordTextBox PasswordWidget;
172    
173        /**
174         * This is an object which implements the FDBLoginListener
175         * interface which will be informed when the user has
176         * authenticated himself with the system and what the level of the
177         * priviledge is
178         */
179        
180        FDBLoginListener LoginListener;
181    
182        /**
183         * Used to check the database intermittingly and report back to
184         * listeners which faults they are displaying have changed so that
185         * they may update their view accordingly. 
186         */
187        
188        private FaultUpdateMonitor faultUpdateMonitor = null;
189        
190        /**
191         * Constructor which will create a panel into which the user enter
192         * the details of his username and password.
193         */
194    
195        LoginPanel (final FaultServiceAsync svc,final FDBLoginListener LoginListener) {
196    
197            this.svc = svc;
198            this.LoginListener = LoginListener;
199            
200            initWidget(MainPanel);
201    
202            MainPanel.setWidth("95%");
203            MainPanel.setStyleName("MainLoginPanel");
204            
205            // Set the style of the login panel 
206            
207            final Label title = new Label("ING Fault Management System");
208            title.setStyleName("titleStyle");
209            
210            final HTML introduction = new HTML(internationalizationConstants.introduction());
211            introduction.setStyleName("introduction");
212                    
213            final HTML language = new HTML(internationalizationConstants.changeInterface() + " : <a href=\"Main.html?locale=en\">English</a> <a href=\"Main.html?locale=sp\">" + internationalizationConstants.espanol() + "</a>");
214            language.setStyleName("creditStyle");
215    
216            MainPanel.add(language,DockPanel.SOUTH);                
217            MainPanel.add(title ,DockPanel.NORTH);
218            MainPanel.add(introduction,DockPanel.WEST); 
219            MainPanel.add(UserLoginPanel,DockPanel.CENTER);         
220            
221            MainPanel.setCellHorizontalAlignment(language,HasHorizontalAlignment.ALIGN_LEFT);
222            MainPanel.setCellWidth(language,"95%");
223    
224            UserLoginPanel.setStyleName("LoginPanel");
225    
226            // Now create the fields into which the user will enter his
227            // name and password.
228    
229            // The fields into which the user enters the uid 
230    
231            LoginTable.setWidget(1,0, new Label(internationalizationConstants.userIdentifier()));
232    
233            UserIdentifierWidget = new TextBox ();
234            UserIdentifierWidget.addKeyboardListener(this);
235    
236            UserIdentifierWidget.setVisibleLength(20);
237            
238            LoginTable.setWidget(1,1,UserIdentifierWidget);
239                    
240            // Now for the password field 
241            
242            LoginTable.setWidget(2,0, new Label(internationalizationConstants.userPassword()));
243            
244            PasswordWidget = new PasswordTextBox();
245            PasswordWidget.addKeyboardListener(this);
246                    
247            LoginTable.setWidget(2,1,PasswordWidget);
248                                                   
249            // Now add the check box which will be used to allow the user
250            // to indicate whether or not he would like the login
251            // credentials stored on the client computer
252    
253            StoreLoginCredentialsCheckBox = new CheckBox(internationalizationConstants.storeCredentialsOnComputer(),true);
254    
255            // If the user has already saved his credentials in a cookie
256            // then we should grab them and drop them into the fields
257    
258            resetUserCredentialFields();
259    
260            // Now we need to add blank row 
261    
262            LoginTable.setWidget(3,1, StoreLoginCredentialsCheckBox);
263            
264            // Now for a login button at the foot of the table for those with and without passwords
265            
266            final HorizontalPanel tmp = new HorizontalPanel();
267            LoginTable.setWidget(4,1,tmp);
268    
269            tmp.setSpacing(5);
270    
271            LoginButton     = new Button(internationalizationConstants.loginButton(),this); 
272            LoginNoIdButton = new Button(internationalizationConstants.loginNoIdButton(),this);     
273                    
274            tmp.add(LoginButton);
275            tmp.add(LoginNoIdButton);
276            
277            // Now drop the table into the panel 
278            
279            UserLoginPanel.add(LoginTable);
280    
281            // Set the tab index 
282            
283            UserIdentifierWidget.setTabIndex(1);
284            PasswordWidget.setTabIndex(2);
285            StoreLoginCredentialsCheckBox.setTabIndex(3);
286            LoginButton.setTabIndex(4);
287            LoginNoIdButton.setTabIndex(5);
288            
289            // Add a deferred command to set the focus to the user name
290            // field. Not that cannot do this until the widgets are
291            // realised. 
292    
293            DeferredCommand.add(new Command() { 
294    
295                    public void execute() {
296                        
297                        // Now set the focus to the username entry field. 
298    
299                        UserIdentifierWidget.setFocus(true);
300                    }
301                });
302        }
303    
304        /*
305         * Will reset the login fields to their default values. The method
306         * will access the cookies which are holding the user identifier
307         * and the password in the users account.
308         */
309        
310        private void resetUserCredentialFields () {
311            
312            UserIdentifierWidget.setText(Cookies.getCookie(FaultDatabaseConstants.USERIDCOOKIE));
313            PasswordWidget.setText(Cookies.getCookie(FaultDatabaseConstants.PASSWORDCOOKIE));
314            
315            // If the user has requested that he can store the details of
316            // his uid/pwd by default then we tick the box. 
317    
318            final String storeCredentials = Cookies.getCookie(FaultDatabaseConstants.STOREPASSWORDCOOKIE);
319            
320            if (storeCredentials != null && storeCredentials.equals(FaultDatabaseConstants.STORECREDENTIALS)) {
321                StoreLoginCredentialsCheckBox.setChecked(true);
322            } else {
323                StoreLoginCredentialsCheckBox.setChecked(false);
324            }
325        }
326        
327        /**
328         * Implements the interface which is associated with the
329         * ClickListener interface and is called when the user presses
330         * buttons in the Login panel interface
331         * @param sender The widget that was clicked. 
332         */
333    
334        public void onClick (final Widget sender) {
335            
336            // If the user has pressed the reset form button then reset
337            // the contents of the form to the default values
338    
339            if (sender.equals(LoginButton)) {
340             
341                // If the user has pressed the login button then we need
342                // to establish what level of priviledge that the user is
343                // afforded. If the user has not provided a user name and
344                // password he gets the default level of priviledge which
345                // only allows him to enter faults and search the database
346                
347                if (UserIdentifierWidget.getText().equals("") && PasswordWidget.getText().equals("")) {
348                    
349                    UserAuthentication = new AuthenticationDetails();
350                    
351                    LoginListener.userLoggedIn(UserAuthentication);
352    
353                    return;
354                }
355                
356                // If either of the fields are empty then complain to the
357                // user that he has not filled in both of the fields
358    
359                if (UserIdentifierWidget.getText().equals("") || PasswordWidget.getText().equals("")) {
360                    MessageBox.alert(internationalizationConstants.information(),internationalizationConstants.allFieldsMustBeFilledIn());
361                    return;
362                }
363                
364                // The user has entered a user name and a password and we
365                // need to ask the servlet what level of privilege this
366                // user is to be afforded. An exception will be returned
367                // in the case that the we were unable to log into the
368                // system. 
369    
370                busyIndicator.showBusy(true,internationalizationConstants.loading());
371                
372                svc.authenticateUser (UserIdentifierWidget.getText(), PasswordWidget.getText(),new AsyncCallback() {
373                        
374                        /**
375                         * On success we get back the authentication data
376                         * from the servlet container
377                         */
378                        
379                        public void onSuccess (final Object result) {
380    
381                            UserAuthentication = (AuthenticationDetails)result;
382    
383                            busyIndicator.showBusy(false);
384                                                    
385                            // If the user has requested that his login
386                            // credentials should be stored on the local
387                            // machine then we should store them now.
388                            
389                            if (StoreLoginCredentialsCheckBox.isChecked()) {
390    
391                                Cookies.setCookie(FaultDatabaseConstants.USERIDCOOKIE,UserIdentifierWidget.getText(),new Date(150,11,31));
392                                Cookies.setCookie(FaultDatabaseConstants.PASSWORDCOOKIE,PasswordWidget.getText(),new Date (150,11,31));                         
393                                Cookies.setCookie(FaultDatabaseConstants.STOREPASSWORDCOOKIE,FaultDatabaseConstants.STORECREDENTIALS,new Date (150,11,31));
394                            
395                            } else {
396    
397                                Cookies.setCookie(FaultDatabaseConstants.STOREPASSWORDCOOKIE,FaultDatabaseConstants.DONOTSTORECREDENTIALS,new Date (150,11,31));
398                                
399                                // If the user has requested that we do
400                                // not store cookies then ensure that we
401                                // delete whatever may be stored on the
402                                // computer currently.
403    
404                                Cookies.removeCookie(FaultDatabaseConstants.USERIDCOOKIE);
405                                Cookies.removeCookie(FaultDatabaseConstants.PASSWORDCOOKIE);
406                            }
407                            
408                            // Now tell the listener that the user has logged on 
409                            
410                            if (LoginListener != null) {
411                                LoginListener.userLoggedIn(UserAuthentication);
412                            }
413                        }
414                        
415                        public void onFailure (Throwable ex)
416                        {
417                            MessageBox.alert(internationalizationConstants.information(),internationalizationConstants.loginFailed());
418                            busyIndicator.showBusy(false);
419                                        
420                        }
421                    });
422                
423                return;
424    
425            } else if (sender.equals(LoginNoIdButton)) {
426             
427                // If the user is attempting to log onto the system without
428                // any credentials then he gets the basic functionality
429    
430                svc.authenticateUser ("guest","",new AsyncCallback() {
431                        
432                        /**
433                         * On success we get back the authentication data
434                         * from the servlet container
435                         */
436                        
437                        public void onSuccess (final Object result) {
438    
439                            UserAuthentication = (AuthenticationDetails)result;
440                            
441                            // Now tell the listener that the user has logged on 
442                            
443                            if (LoginListener != null) {
444                                LoginListener.userLoggedIn(UserAuthentication);
445                            }
446                        }
447                        
448                        public void onFailure (Throwable ex)
449                        {
450                            MessageBox.alert(internationalizationConstants.information(),internationalizationConstants.loginFailed());
451                        }
452                    });
453                
454                return;
455    
456                
457            }
458        }
459    
460    
461        /**
462         * An obligation to the KeyboardListener interface. Not Used. 
463         */
464        
465        public void onKeyDown(Widget sender, char  keyCode, int modifiers) {
466            
467        }
468    
469        /**
470         * Called when the user presses the return key in the login
471         * panel. We automatically attempt to log the user on if he
472         * presses the return key
473         */
474        
475        public void onKeyPress(Widget sender, final char  keyCode, int modifiers) {
476            
477            if (keyCode == KeyboardListener.KEY_ENTER) {
478                onClick(LoginButton);
479            }
480        }
481    
482        /**
483         * An obligation to the KeyboardListener interface. Not Used. 
484         */
485        
486        public void onKeyUp(final Widget sender, final char  keyCode, final int modifiers) {
487            
488        }
489    
490    }