View Javadoc
1   package fr.ifremer.tutti.ui.swing.util.auth;
2   
3   /*
4    * #%L
5    * Tutti :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import fr.ifremer.tutti.ui.swing.TuttiUIContext;
28  import fr.ifremer.tutti.ui.swing.util.TuttiUI;
29  import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil;
30  import java.awt.BorderLayout;
31  import java.awt.Container;
32  import java.awt.Dialog;
33  import java.awt.Dialog.ModalityType;
34  import java.awt.Frame;
35  import java.awt.GraphicsConfiguration;
36  import java.awt.GridBagConstraints;
37  import java.awt.GridLayout;
38  import java.awt.Insets;
39  import java.awt.Window;
40  import java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.TreeMap;
45  import javax.swing.JButton;
46  import javax.swing.JDialog;
47  import javax.swing.JLabel;
48  import javax.swing.JPanel;
49  import javax.swing.JPasswordField;
50  import javax.swing.JTextField;
51  import jaxx.runtime.JAXXBinding;
52  import jaxx.runtime.JAXXContext;
53  import jaxx.runtime.JAXXObject;
54  import jaxx.runtime.JAXXObjectDescriptor;
55  import jaxx.runtime.JAXXUtil;
56  import jaxx.runtime.SwingUtil;
57  import jaxx.runtime.context.DefaultJAXXContext;
58  import jaxx.runtime.swing.Table;
59  import org.apache.commons.logging.Log;
60  import org.apache.commons.logging.LogFactory;
61  import static org.nuiton.i18n.I18n.t;
62  
63  public class LoginUI extends JDialog implements TuttiUI<TuttiUIContext, LoginUIHandler>, JAXXObject {
64  
65      /*-----------------------------------------------------------------------*/
66      /*------------------------- Other static fields -------------------------*/
67      /*-----------------------------------------------------------------------*/
68  
69      private static final String $jaxxObjectDescriptor = "H4sIAAAAAAAAAK1VQW8bRRSemNiN47qhmIZSCpi2QkWgdZAAIQVBQ4pFIgeqJlErfCjj3Yk91ezMMDPbbBUFIbhy4CfAnQsSN06IA2cOXBB/ASEOXBFvZje73mQdu4IcNsm89773zbfvffvtH6iqFXrhPo5jT0Xc0JB4m2t37344uE98c5NoX1FphELJz1wFVfqoEWTn2qCr/Z4t76TlnXURSsEJH6te7aFFbR4yokeEGIOeLVb4Wne2s/BqLCN1hJqRKkP9+q8/K18Fn31TQSiWwK4BV2lPq8pvMt9DFRoY9AR0eoA7DPMh0FCUD4Fv056tM6z1Bzgkn6BP0ZkeqkmsAMygK7Nf2WG4+lga1GBiSPlNiuG3QS/vKY/uKRIS5ZnIGOpF1NP7wMCLDGUejszI69mK3Q0pHUrNoGooAsIMuj65esf+u7uxLrghsclL6yGm/BbmtvxiQam0Dg+Yu2w9K2lQvie2iNZ4SEArK0ucZm/28IAwm7eUpS+6C2aBJ8uiXUoY6L5cwNoBoi5QrGhKkG9fqGASZJaQol4qoN4aDxYLF65tOiVWjt/KnRZzz/qY+4S9C7KCpKhVyE9ObebzeQH2fSJNHrqWxhV6pqA7zL6Xz34+nHN9VFURHMOL6p9cl9sQShbl4rFFsYAu+s9y69cffv++e7QdTeh9oTR1bLlhaqUSkihDbeulZDXsMHa2sFzto7omDJzBbf7lEmLbaRjIQb/ztjyZ5fexHgFE9cxvP/60/PEvj6FK144DDrrY5m+guhkpUEGwIJbv3HCMzu4vwPNxy82gc/dwENwhdDgyu5zCEj514BbBg7nMj6+/dBiDKpdLVMmoDeo//93a/u7GkTJzwPTpiem5OtWPUI1yRjlxzpGaQqlTNKQmUSDy5S+zAyQlWEKT2cm+Q83I8nexV9xzpUyF2shd1aDK6ytxZNNeczewf72RADYGburcGJ8KVwEvMdQwmLvziYG49fTSM+szGIxi3qiInOxVNDOZmswp1BfhRVPBN3y7QvPWVkpBx/xmGihcYMGp1xUKBuSgndtL+9ASB0+BORm/254NJn+XdR+zr0drvnRQ8KG8+6WT3Y8yywgU/W4ahyo4DX31Tb7FSSg49WEnk3a+COHAS2zLC7Nw4R3UknBGtVVSCy/ECMF2qNw5Jad5T9NQMrLm0A1672CWL1vCRSdfuHUHlQB4vt2SwzJ9Ck786PI8V6D/ADMaYEMmCpS4eCbQhdLq4xJNyvofRFpzfKaLNP71mWEzaww/FJCMzr0FVHF7QHkALN4+gT1nn4tTEe3x5/bxRTlCewZO89RPvpwTMFozsfjyFISr/xnhRUD4F1yPLCFDCwAA";
70      private static final Log log = LogFactory.getLog(LoginUI.class);
71      private static final long serialVersionUID = 1L;
72  
73      /*-----------------------------------------------------------------------*/
74      /*--------------------------- Internal states ---------------------------*/
75      /*-----------------------------------------------------------------------*/
76  
77      protected List<Object> $activeBindings = new ArrayList<Object>();
78      protected Map<String, Object> $bindingSources = new HashMap<String, Object>();
79      protected final Map<String, JAXXBinding> $bindings = new TreeMap<String, JAXXBinding>();
80      protected Map<String, Object> $objectMap = new HashMap<String, Object>();
81      protected Map<?, ?> $previousValues = new HashMap<Object, Object>();
82      private boolean allComponentsCreated;
83      protected final JAXXContext delegateContext = new DefaultJAXXContext();
84  
85      /*-----------------------------------------------------------------------*/
86      /*------------------------ Protected components  ------------------------*/
87      /*-----------------------------------------------------------------------*/
88  
89      protected JButton acceptButton;
90      protected JButton cancelButton;
91      protected final LoginUIHandler handler = createHandler();
92      protected JLabel infoMessage;
93      protected LoginUI loginDialog = this;
94      protected JTextField loginField;
95      protected JLabel loginLabel;
96      protected Table mainPanel;
97      protected TuttiUIContext model;
98      protected JPasswordField passwordField;
99      protected JLabel passwordLabel;
100 
101     /*-----------------------------------------------------------------------*/
102     /*------------------------- Private components  -------------------------*/
103     /*-----------------------------------------------------------------------*/
104 
105     private JPanel $JPanel0;
106 
107     /*-----------------------------------------------------------------------*/
108     /*---------------------- Raw body code from script ----------------------*/
109     /*-----------------------------------------------------------------------*/
110     
111     
112     public LoginUI open(String url, AuthenticationInfo authenticationInfo) {
113         handler.open(url, authenticationInfo);
114         return this;
115     }
116     
117     public AuthenticationInfo getAuthenticationInfo() { return handler.getAuthenticationInfo(); }
118 
119     /*-----------------------------------------------------------------------*/
120     /*---------------------------- Constructors  ----------------------------*/
121     /*-----------------------------------------------------------------------*/
122 
123     public LoginUI(TuttiUIContext context) {
124         super(context.getExistingActionUI());
125             TuttiUIUtil.setApplicationContext(this, context);
126             $initialize();
127     }
128 
129     public LoginUI(Frame param0, String param1, boolean param2, GraphicsConfiguration param3) {
130         super(param0 ,param1 ,param2 ,param3);
131         $initialize();
132     }
133 
134     public LoginUI(JAXXContext parentContext, Frame param1, String param2, boolean param3, GraphicsConfiguration param4) {
135         super(param1 ,param2 ,param3 ,param4);
136         JAXXUtil.initContext(this, parentContext);
137         $initialize();
138     }
139 
140     public LoginUI(Dialog param0) {
141         super(param0);
142         $initialize();
143     }
144 
145     public LoginUI(JAXXContext parentContext, Dialog param1) {
146         super(param1);
147         JAXXUtil.initContext(this, parentContext);
148         $initialize();
149     }
150 
151     public LoginUI(Frame param0, String param1, boolean param2) {
152         super(param0 ,param1 ,param2);
153         $initialize();
154     }
155 
156     public LoginUI(JAXXContext parentContext, Frame param1, String param2, boolean param3) {
157         super(param1 ,param2 ,param3);
158         JAXXUtil.initContext(this, parentContext);
159         $initialize();
160     }
161 
162     public LoginUI() {
163         $initialize();
164     }
165 
166     public LoginUI(JAXXContext parentContext) {
167         JAXXUtil.initContext(this, parentContext);
168         $initialize();
169     }
170 
171     public LoginUI(Frame param0) {
172         super(param0);
173         $initialize();
174     }
175 
176     public LoginUI(JAXXContext parentContext, Frame param1) {
177         super(param1);
178         JAXXUtil.initContext(this, parentContext);
179         $initialize();
180     }
181 
182     public LoginUI(Frame param0, boolean param1) {
183         super(param0 ,param1);
184         $initialize();
185     }
186 
187     public LoginUI(JAXXContext parentContext, Frame param1, boolean param2) {
188         super(param1 ,param2);
189         JAXXUtil.initContext(this, parentContext);
190         $initialize();
191     }
192 
193     public LoginUI(Frame param0, String param1) {
194         super(param0 ,param1);
195         $initialize();
196     }
197 
198     public LoginUI(JAXXContext parentContext, Frame param1, String param2) {
199         super(param1 ,param2);
200         JAXXUtil.initContext(this, parentContext);
201         $initialize();
202     }
203 
204     public LoginUI(Window param0) {
205         super(param0);
206         $initialize();
207     }
208 
209     public LoginUI(JAXXContext parentContext, Window param1) {
210         super(param1);
211         JAXXUtil.initContext(this, parentContext);
212         $initialize();
213     }
214 
215     public LoginUI(Window param0, ModalityType param1) {
216         super(param0 ,param1);
217         $initialize();
218     }
219 
220     public LoginUI(JAXXContext parentContext, Window param1, ModalityType param2) {
221         super(param1 ,param2);
222         JAXXUtil.initContext(this, parentContext);
223         $initialize();
224     }
225 
226     public LoginUI(Window param0, String param1) {
227         super(param0 ,param1);
228         $initialize();
229     }
230 
231     public LoginUI(JAXXContext parentContext, Window param1, String param2) {
232         super(param1 ,param2);
233         JAXXUtil.initContext(this, parentContext);
234         $initialize();
235     }
236 
237     public LoginUI(Window param0, String param1, ModalityType param2) {
238         super(param0 ,param1 ,param2);
239         $initialize();
240     }
241 
242     public LoginUI(JAXXContext parentContext, Window param1, String param2, ModalityType param3) {
243         super(param1 ,param2 ,param3);
244         JAXXUtil.initContext(this, parentContext);
245         $initialize();
246     }
247 
248     public LoginUI(Window param0, String param1, ModalityType param2, GraphicsConfiguration param3) {
249         super(param0 ,param1 ,param2 ,param3);
250         $initialize();
251     }
252 
253     public LoginUI(JAXXContext parentContext, Window param1, String param2, ModalityType param3, GraphicsConfiguration param4) {
254         super(param1 ,param2 ,param3 ,param4);
255         JAXXUtil.initContext(this, parentContext);
256         $initialize();
257     }
258 
259     public LoginUI(Dialog param0, boolean param1) {
260         super(param0 ,param1);
261         $initialize();
262     }
263 
264     public LoginUI(JAXXContext parentContext, Dialog param1, boolean param2) {
265         super(param1 ,param2);
266         JAXXUtil.initContext(this, parentContext);
267         $initialize();
268     }
269 
270     public LoginUI(Dialog param0, String param1) {
271         super(param0 ,param1);
272         $initialize();
273     }
274 
275     public LoginUI(JAXXContext parentContext, Dialog param1, String param2) {
276         super(param1 ,param2);
277         JAXXUtil.initContext(this, parentContext);
278         $initialize();
279     }
280 
281     public LoginUI(Dialog param0, String param1, boolean param2) {
282         super(param0 ,param1 ,param2);
283         $initialize();
284     }
285 
286     public LoginUI(JAXXContext parentContext, Dialog param1, String param2, boolean param3) {
287         super(param1 ,param2 ,param3);
288         JAXXUtil.initContext(this, parentContext);
289         $initialize();
290     }
291 
292     public LoginUI(Dialog param0, String param1, boolean param2, GraphicsConfiguration param3) {
293         super(param0 ,param1 ,param2 ,param3);
294         $initialize();
295     }
296 
297     public LoginUI(JAXXContext parentContext, Dialog param1, String param2, boolean param3, GraphicsConfiguration param4) {
298         super(param1 ,param2 ,param3 ,param4);
299         JAXXUtil.initContext(this, parentContext);
300         $initialize();
301     }
302 
303     /*-----------------------------------------------------------------------*/
304     /*--------------------------- Statics methods ---------------------------*/
305     /*-----------------------------------------------------------------------*/
306 
307     public static JAXXObjectDescriptor $getJAXXObjectDescriptor() {
308         return JAXXUtil.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);
309     }
310 
311     /*-----------------------------------------------------------------------*/
312     /*---------------------- JAXXObject implementation ----------------------*/
313     /*-----------------------------------------------------------------------*/
314 
315     @Override
316     public void applyDataBinding(String $binding) {
317         if (allComponentsCreated && $bindings.containsKey($binding)) {
318             getDataBinding($binding).applyDataBinding();
319         }
320         processDataBinding($binding);
321     }
322 
323     @Override
324     public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
325         super.firePropertyChange(propertyName, oldValue, newValue);
326     }
327 
328     @Override
329     public Map<String, Object> get$objectMap() {
330         return $objectMap;
331     }
332 
333     @Override
334     public JAXXBinding getDataBinding(String bindingId) {
335         return $bindings.get(bindingId);
336     }
337 
338     @Override
339     public JAXXBinding[] getDataBindings() {
340         return $bindings.values().toArray(new JAXXBinding[$bindings.size()]);
341     }
342 
343     @Override
344     public Object getObjectById(String id) {
345         return $objectMap.get(id);
346     }
347 
348     @Override
349     public void processDataBinding(String $binding, boolean $force) {
350         if (!$force && $activeBindings.contains($binding)) { 
351             return;
352         }
353         $activeBindings.add($binding);
354         try {
355             if (allComponentsCreated && $bindings.containsKey($binding)) {
356                 getDataBinding($binding).processDataBinding();
357             }
358         } finally {
359             $activeBindings.remove($binding);
360         }
361     }
362 
363     @Override
364     public void processDataBinding(String $binding) {
365         processDataBinding($binding, false);
366     }
367 
368     @Override
369     public void registerDataBinding(JAXXBinding binding) {
370         $bindings.put(binding.getId(), binding);
371     }
372 
373     @Override
374     public void removeDataBinding(String $binding) {
375         if (allComponentsCreated && $bindings.containsKey($binding)) {
376             getDataBinding($binding).removeDataBinding();
377         }
378     }
379 
380     /*-----------------------------------------------------------------------*/
381     /*--------------------- JAXXContext implementation  ---------------------*/
382     /*-----------------------------------------------------------------------*/
383 
384     @Override
385     public <T> T getContextValue(Class<T> clazz) {
386         return delegateContext.getContextValue(clazz, null);
387     }
388 
389     @Override
390     public <T> T getContextValue(Class<T> clazz, String name) {
391         return delegateContext.getContextValue(clazz, name);
392     }
393 
394     @Override
395     public JAXXContext getDelegateContext() {
396         return delegateContext;
397     }
398 
399     @Override
400     public <O extends Container> O getParentContainer(Class<O> clazz) {
401         return SwingUtil.getParentContainer(this, clazz);
402     }
403 
404     @Override
405     public <O extends Container> O getParentContainer(Object source, Class<O> clazz) {
406         return SwingUtil.getParentContainer(source, clazz);
407     }
408 
409     @Override
410     public <T> void removeContextValue(Class<T> clazz) {
411         delegateContext.removeContextValue(clazz, null);
412     }
413 
414     @Override
415     public <T> void removeContextValue(Class<T> clazz, String name) {
416         delegateContext.removeContextValue(clazz, name);
417     }
418 
419     @Override
420     public <T> void setContextValue(T o) {
421         delegateContext.setContextValue(o, null);
422     }
423 
424     @Override
425     public <T> void setContextValue(T o, String name) {
426         delegateContext.setContextValue(o, name);
427     }
428 
429     /*-----------------------------------------------------------------------*/
430     /*----------------------- Public acessor methods  -----------------------*/
431     /*-----------------------------------------------------------------------*/
432 
433     public JButton getAcceptButton() {
434         return acceptButton;
435     }
436 
437     public JButton getCancelButton() {
438         return cancelButton;
439     }
440 
441     public LoginUIHandler getHandler() {
442         return handler;
443     }
444 
445     public JLabel getInfoMessage() {
446         return infoMessage;
447     }
448 
449     public JTextField getLoginField() {
450         return loginField;
451     }
452 
453     public JLabel getLoginLabel() {
454         return loginLabel;
455     }
456 
457     public Table getMainPanel() {
458         return mainPanel;
459     }
460 
461     public TuttiUIContext getModel() {
462         return model;
463     }
464 
465     public JPasswordField getPasswordField() {
466         return passwordField;
467     }
468 
469     public JLabel getPasswordLabel() {
470         return passwordLabel;
471     }
472 
473     /*-----------------------------------------------------------------------*/
474     /*--------------------- Protected acessors methods  ---------------------*/
475     /*-----------------------------------------------------------------------*/
476 
477     protected JPanel get$JPanel0() {
478         return $JPanel0;
479     }
480 
481     /*-----------------------------------------------------------------------*/
482     /*--------------------- Components creation methods ---------------------*/
483     /*-----------------------------------------------------------------------*/
484 
485     protected void addChildrenToLoginDialog() {
486         if (!allComponentsCreated) {
487             return;
488         }
489         add(mainPanel);
490     }
491 
492     protected void addChildrenToMainPanel() {
493         if (!allComponentsCreated) {
494             return;
495         }
496         mainPanel.add(infoMessage, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
497         mainPanel.add(loginLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
498         mainPanel.add(loginField, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
499         mainPanel.add(passwordLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
500         mainPanel.add(passwordField, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
501         mainPanel.add($JPanel0, new GridBagConstraints(0, 3, 2, 1, 0.0, 0.0, 10, 1, new Insets(3, 3, 3, 3), 0, 0));
502     }
503 
504     protected void createAcceptButton() {
505         $objectMap.put("acceptButton", acceptButton = new JButton());
506         
507         acceptButton.setName("acceptButton");
508         acceptButton.setText(t("tutti.common.validate"));
509         acceptButton.setToolTipText(t("tutti.common.validate"));
510         acceptButton.putClientProperty("simpleAction", fr.ifremer.tutti.ui.swing.util.auth.actions.LoginAcceptAction.class);
511     }
512 
513     protected void createCancelButton() {
514         $objectMap.put("cancelButton", cancelButton = new JButton());
515         
516         cancelButton.setName("cancelButton");
517         cancelButton.setText(t("tutti.common.cancel"));
518         cancelButton.setToolTipText(t("tutti.common.cancel"));
519         cancelButton.putClientProperty("simpleAction", fr.ifremer.tutti.ui.swing.util.auth.actions.LoginCancelAction.class);
520     }
521 
522     protected LoginUIHandler createHandler() {
523         return new LoginUIHandler();
524     }
525 
526     protected void createInfoMessage() {
527         $objectMap.put("infoMessage", infoMessage = new JLabel());
528         
529         infoMessage.setName("infoMessage");
530     }
531 
532     protected void createLoginField() {
533         $objectMap.put("loginField", loginField = new JTextField());
534         
535         loginField.setName("loginField");
536         loginField.setColumns(15);
537     }
538 
539     protected void createLoginLabel() {
540         $objectMap.put("loginLabel", loginLabel = new JLabel());
541         
542         loginLabel.setName("loginLabel");
543         loginLabel.setText(t("tutti.login.field.login"));
544     }
545 
546     protected void createMainPanel() {
547         $objectMap.put("mainPanel", mainPanel = new Table());
548         
549         mainPanel.setName("mainPanel");
550     }
551 
552     protected void createModel() {
553         $objectMap.put("model", model = getContextValue(TuttiUIContext.class));
554     }
555 
556     protected void createPasswordField() {
557         $objectMap.put("passwordField", passwordField = new JPasswordField());
558         
559         passwordField.setName("passwordField");
560         passwordField.setColumns(15);
561     }
562 
563     protected void createPasswordLabel() {
564         $objectMap.put("passwordLabel", passwordLabel = new JLabel());
565         
566         passwordLabel.setName("passwordLabel");
567         passwordLabel.setText(t("tutti.login.field.password"));
568     }
569 
570     /*-----------------------------------------------------------------------*/
571     /*------------------------ Internal jaxx methods ------------------------*/
572     /*-----------------------------------------------------------------------*/
573 
574     private void $completeSetup() {
575         allComponentsCreated = true;
576         if (log.isDebugEnabled()) {
577             log.debug(this);
578         }
579         addChildrenToLoginDialog();
580         addChildrenToMainPanel();
581         // inline complete setup of $JPanel0
582         $JPanel0.add(cancelButton);
583         $JPanel0.add(acceptButton);
584         
585         // apply 9 property setters
586         infoMessage.setIcon(SwingUtil.createActionIcon("info"));
587         loginLabel.setLabelFor( loginField );
588         passwordLabel.setLabelFor(passwordField);
589         cancelButton.setMnemonic(SwingUtil.getFirstCharAt(t("tutti.common.cancel.mnemonic"),'Z'));
590         cancelButton.setIcon(SwingUtil.createActionIcon("cancel"));
591         acceptButton.setMnemonic(SwingUtil.getFirstCharAt(t("tutti.common.validate.mnemonic"),'Z'));
592         acceptButton.setIcon(SwingUtil.createActionIcon("accept"));
593         // late initializer
594         loginDialog.pack();
595     }
596 
597     private void $initialize() {
598         if (allComponentsCreated) {
599             return;
600         }
601         if (log.isDebugEnabled()) {
602             log.debug(this);
603         }
604         handler.beforeInit(this);
605         $objectMap.put("loginDialog", loginDialog);
606         createModel();
607         createMainPanel();
608         createInfoMessage();
609         createLoginLabel();
610         createLoginField();
611         createPasswordLabel();
612         createPasswordField();
613         // inline creation of $JPanel0
614         $objectMap.put("$JPanel0", $JPanel0 = new JPanel());
615         
616         $JPanel0.setName("$JPanel0");
617         $JPanel0.setLayout(new GridLayout(1,0));
618         createCancelButton();
619         createAcceptButton();
620         // inline creation of loginDialog
621         setName("loginDialog");
622         loginDialog.getContentPane().setLayout(new BorderLayout());
623         setTitle(t("tutti.login.title"));
624         setModal(true);
625         
626         $completeSetup();
627         handler.afterInit(this);
628     }
629 
630 }