1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.wizards.document;
24 
25 import com.sun.star.awt.Point;
26 import com.sun.star.awt.Size;
27 import com.sun.star.awt.VclWindowPeerAttribute;
28 import com.sun.star.awt.XControlModel;
29 import com.sun.star.awt.XDevice;
30 import com.sun.star.beans.XPropertySet;
31 import com.sun.star.container.NoSuchElementException;
32 import com.sun.star.container.XChild;
33 import com.sun.star.container.XNameAccess;
34 import com.sun.star.container.XNameContainer;
35 import com.sun.star.lang.WrappedTargetException;
36 import com.sun.star.view.XControlAccess;
37 import com.sun.star.wizards.common.*;
38 
39 import com.sun.star.sdbc.DataType;
40 import com.sun.star.text.XTextDocument;
41 import com.sun.star.uno.Exception;
42 import com.sun.star.uno.Type;
43 import com.sun.star.uno.UnoRuntime;
44 import com.sun.star.uno.AnyConverter;
45 import com.sun.star.uno.XInterface;
46 import com.sun.star.drawing.XControlShape;
47 import com.sun.star.drawing.XDrawPage;
48 import com.sun.star.drawing.XDrawPageSupplier;
49 import com.sun.star.drawing.XShape;
50 import com.sun.star.drawing.XShapeGrouper;
51 import com.sun.star.drawing.XShapes;
52 import com.sun.star.form.XFormsSupplier;
53 import com.sun.star.lang.IllegalArgumentException;
54 import com.sun.star.lang.XComponent;
55 import com.sun.star.lang.XMultiServiceFactory;
56 import com.sun.star.lang.XServiceInfo;
57 import com.sun.star.container.XNamed;
58 import java.util.logging.Level;
59 import java.util.logging.Logger;
60 
61 public class FormHandler
62 {
63     private static final String CHECKBOX = "CheckBox";
64     private static final String DATEFIELD = "DateField";
65     private static final String FORMATTEDFIELD = "FormattedField";
66     private static final String IMAGECONTROL = "ImageControl";
67     private static final String TEXTFIELD = "TextField";
68     private static final String TIMEFIELD = "TimeField";
69 
70     public XFormsSupplier xFormsSupplier;
71     public XMultiServiceFactory xMSFDoc;
72     public XMultiServiceFactory xMSF;
73     public XDrawPage xDrawPage;
74     private XDrawPageSupplier xDrawPageSupplier;
75     public String[] sModelServices = new String[8];
76     public static ControlData[] oControlData;
77 
78     public final static int SOLABEL = 0;
79     public final static int SOTEXTBOX = 1;
80     public final static int SOCHECKBOX = 2;
81     public final static int SODATECONTROL = 3;
82     public final static int SOTIMECONTROL = 4;
83     public final static int SONUMERICCONTROL = 5;
84     public final static int SOGRIDCONTROL = 6;
85     public final static int SOIMAGECONTROL = 7;
86     public final static int SODATETIMECONTROL = 8;
87     int iImageControlHeight = 2000;
88     public static String SOSIZETEXT = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.";
89     int iXPixelFactor = -1;
90     int iYPixelFactor = -1;
91     int iXNirwanaPos = 50000;
92     int iYNirwanaPos = 50000;
93     public int nLabelHeight = -1;
94     public int nDBRefHeight = -1;
95     public int BasicLabelDiffHeight = -1;
96     XNameAccess xNamedForms;
97     XControlAccess xControlAccess;
98     XShapeGrouper xShapeGrouper;
99     XNameContainer xNamedFormContainer;
100 
101     public class ControlData
102     {
103 
104         int DataType;
105         int ControlType;
106         String ControlService;
107         String GridColumnName;
108         boolean bIsText;
109     }
110 
111     /** Creates a new instance of FormHandler */
FormHandler(XMultiServiceFactory _xMSF, XTextDocument xTextDocument)112     public FormHandler(XMultiServiceFactory _xMSF, XTextDocument xTextDocument)
113     {
114         this.xMSF = _xMSF;
115         xDrawPageSupplier = UnoRuntime.queryInterface(XDrawPageSupplier.class, xTextDocument);
116         xDrawPage = xDrawPageSupplier.getDrawPage();
117         xFormsSupplier = UnoRuntime.queryInterface(XFormsSupplier.class, xDrawPage);
118         xShapeGrouper = UnoRuntime.queryInterface(XShapeGrouper.class, xDrawPage);
119         xControlAccess = UnoRuntime.queryInterface(XControlAccess.class, xTextDocument.getCurrentController());
120         xMSFDoc = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
121         sModelServices[SOLABEL] = "com.sun.star.form.component.FixedText";
122         sModelServices[SOTEXTBOX] = "com.sun.star.form.component.TextField";
123         sModelServices[SOCHECKBOX] = "com.sun.star.form.component.CheckBox";
124         sModelServices[SODATECONTROL] = "com.sun.star.form.component.DateField";
125         sModelServices[SOTIMECONTROL] = "com.sun.star.form.component.TimeField";
126         sModelServices[SONUMERICCONTROL] = "com.sun.star.form.component.FormattedField";
127         sModelServices[SOGRIDCONTROL] = "com.sun.star.form.component.GridControl";
128         sModelServices[SOIMAGECONTROL] = "com.sun.star.form.component.DatabaseImageControl";
129 
130         oControlData = new ControlData[22];
131         oControlData[0] = createControlData(DataType.BIT,          SOCHECKBOX, CHECKBOX, CHECKBOX, false);
132         oControlData[1] = createControlData(DataType.BOOLEAN,      SOCHECKBOX, CHECKBOX, CHECKBOX, false);
133         oControlData[2] = createControlData(DataType.TINYINT,      SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
134         oControlData[3] = createControlData(DataType.SMALLINT,     SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
135         oControlData[4] = createControlData(DataType.INTEGER,      SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
136         oControlData[5] = createControlData(DataType.BIGINT,       SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
137         oControlData[6] = createControlData(DataType.FLOAT,        SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
138         oControlData[7] = createControlData(DataType.REAL,         SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
139         oControlData[8] = createControlData(DataType.DOUBLE,       SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
140         oControlData[9] = createControlData(DataType.NUMERIC,      SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
141         oControlData[10] = createControlData(DataType.DECIMAL,     SONUMERICCONTROL, FORMATTEDFIELD, FORMATTEDFIELD, false);
142         oControlData[11] = createControlData(DataType.CHAR,        SOTEXTBOX, TEXTFIELD, TEXTFIELD, false);
143         oControlData[12] = createControlData(DataType.VARCHAR,     SOTEXTBOX, TEXTFIELD, TEXTFIELD, true);
144         oControlData[13] = createControlData(DataType.LONGVARCHAR, SOTEXTBOX, TEXTFIELD, TEXTFIELD, true);
145         oControlData[14] = createControlData(DataType.DATE,        SODATECONTROL, DATEFIELD, DATEFIELD, false);
146         oControlData[15] = createControlData(DataType.TIME,        SOTIMECONTROL, TIMEFIELD, TIMEFIELD, false);
147         oControlData[16] = createControlData(DataType.TIMESTAMP,   SODATECONTROL, DATEFIELD, TEXTFIELD, false);
148         // oImageControlData = new ControlData[4];
149         oControlData[17] = createControlData(DataType.BINARY,      SOIMAGECONTROL, IMAGECONTROL, TEXTFIELD, false);
150         oControlData[18] = createControlData(DataType.VARBINARY,   SOIMAGECONTROL, IMAGECONTROL, TEXTFIELD, false);
151         oControlData[19] = createControlData(DataType.LONGVARBINARY, SOIMAGECONTROL, IMAGECONTROL, TEXTFIELD, false);
152         oControlData[20] = createControlData(DataType.BLOB,        SOIMAGECONTROL, IMAGECONTROL, TEXTFIELD, false);
153 
154         oControlData[21] = createControlData(DataType.OTHER,       SOIMAGECONTROL, IMAGECONTROL, TEXTFIELD, false);
155     }
156 
getControlType(int _fieldtype)157     public int getControlType(int _fieldtype)
158     {
159         for (int i = 0; i < oControlData.length; i++)
160         {
161             if (oControlData[i].DataType == _fieldtype)
162             {
163                 return oControlData[i].ControlType;
164             }
165         }
166         return -1;
167     }
168 
setglobalMultiServiceFactory(XMultiServiceFactory _xMSF)169     public void setglobalMultiServiceFactory(XMultiServiceFactory _xMSF)
170     {
171         xMSF = _xMSF;
172     }
173 
getModelServiceName(int _fieldtype)174     public String getModelServiceName(int _fieldtype)
175     {
176         int icontroltype = getControlType(_fieldtype);
177         if (icontroltype > -1)
178         {
179             return sModelServices[icontroltype];
180         }
181         else
182         {
183             return null;
184         }
185     }
186 
initializeBasicControlValues()187     public void initializeBasicControlValues()
188     {
189         Control oLabelControl = new Control(this, SOLABEL, new Point(), new Size());
190         XDevice xDevice = UnoRuntime.queryInterface(XDevice.class, oLabelControl.xWindowPeer);
191         iXPixelFactor = (int) (100000 / xDevice.getInfo().PixelPerMeterX);
192         iYPixelFactor = (int) (100000 / xDevice.getInfo().PixelPerMeterY);
193 
194         nLabelHeight = (oLabelControl.getPreferredHeight("The quick brown fox...") + 1);
195         Control oTextControl = new Control(this, SOTEXTBOX, new Point(), new Size());
196         nDBRefHeight = (oTextControl.getPreferredHeight("The quick brown fox...") + 1);
197         BasicLabelDiffHeight = (nDBRefHeight - nLabelHeight) / 2;
198         xDrawPage.remove(oLabelControl.xShape);
199         xDrawPage.remove(oTextControl.xShape);
200     }
201 
createControlData(int _datatype, int _controltype, String _scontrolservicename, String _gridcolumnname, boolean _bIsTextControl)202     public ControlData createControlData(int _datatype, int _controltype, String _scontrolservicename, String _gridcolumnname, boolean _bIsTextControl)
203     {
204         ControlData curControlData = new ControlData();
205         curControlData.DataType = _datatype;
206         curControlData.ControlType = _controltype;
207         curControlData.ControlService = _scontrolservicename;
208         curControlData.GridColumnName = _gridcolumnname;
209         curControlData.bIsText = _bIsTextControl;
210         return curControlData;
211     }
212 
getDocumentForms()213     public XNameContainer getDocumentForms()
214     {
215         return xFormsSupplier.getForms();
216     }
217 
getValueofHiddenControl(XNameAccess xNamedForm, String ControlName)218     public String getValueofHiddenControl(XNameAccess xNamedForm, String ControlName)
219     {
220         String value = "";
221         try
222         {
223             if (xNamedForm.hasByName(ControlName))
224             {
225                 value = AnyConverter.toString(com.sun.star.wizards.common.Helper.getUnoPropertyValue(xNamedForm.getByName(ControlName), "HiddenValue"));
226             }
227         }
228         catch (Exception ex)
229         {
230             Logger.getLogger( FormHandler.class.getName() ).log( Level.SEVERE, null, ex );
231         }
232         return value;
233     }
234 
insertHiddenControl(XNameAccess xNameAccess, XNameContainer xNamedForm, String ControlName, String ControlValue)235     public void insertHiddenControl(XNameAccess xNameAccess, XNameContainer xNamedForm, String ControlName, String ControlValue)
236     {
237         try
238         {
239             XInterface xHiddenControl;
240             if (xNameAccess.hasByName(ControlName))
241             {
242                 xHiddenControl = (XInterface) AnyConverter.toObject(new Type(XInterface.class), xNameAccess.getByName(ControlName));
243             }
244             else
245             {
246                 xHiddenControl = (XInterface) xMSFDoc.createInstance("com.sun.star.form.component.HiddenControl");
247                 xNamedForm.insertByName(ControlName, xHiddenControl);
248             }
249             Helper.setUnoPropertyValue(xHiddenControl, "HiddenValue", ControlValue);
250         }
251         catch (Exception ex)
252         {
253             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, ex);
254         }
255     }
256 
hasFormByName(String _FormName)257     public boolean hasFormByName(String _FormName)
258     {
259         xNamedFormContainer = getDocumentForms();
260         xNamedForms = UnoRuntime.queryInterface(XNameAccess.class, xNamedFormContainer);
261         return xNamedForms.hasByName(_FormName);
262     }
263 
removeFormByName(String _FormName)264     public void removeFormByName(String _FormName)
265     {
266         try
267         {
268             if (hasFormByName(_FormName))
269             {
270                 removeControlsofForm(_FormName);
271                 xNamedFormContainer.removeByName(_FormName);
272             }
273         }
274         catch (com.sun.star.uno.Exception ex)
275         {
276             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, ex);
277         }
278     }
279 
removeControlsofForm(String _FormName)280     public void removeControlsofForm(String _FormName)
281     {
282         try
283         {
284             for (int i = xDrawPage.getCount() - 1; i >= 0; i--)
285             {
286                 if (belongsToForm(xDrawPage.getByIndex(i), _FormName))
287                 {
288                     XShape xShape = UnoRuntime.queryInterface(XShape.class, xDrawPage.getByIndex(i));
289                     xDrawPage.remove(xShape);
290                 }
291             }
292         }
293         catch (Exception e)
294         {
295             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
296         }
297     }
298 
removeElement( XNameContainer _parentContainer, String _formName )299     public void removeElement( XNameContainer _parentContainer, String _formName )
300     {
301         try
302         {
303             _parentContainer.removeByName( _formName );
304         }
305         catch ( WrappedTargetException e )
306         {
307             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
308         }
309         catch( final NoSuchElementException e )
310         {
311             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
312         }
313     }
314 
belongsToForm(Object _oDrawPageElement, String _FormName)315     public boolean belongsToForm(Object _oDrawPageElement, String _FormName)
316     {
317         XServiceInfo xServiceInfo = UnoRuntime.queryInterface(XServiceInfo.class, _oDrawPageElement);
318         if (xServiceInfo.supportsService("com.sun.star.drawing.ControlShape"))
319         {
320             XControlShape xControlShape = UnoRuntime.queryInterface(XControlShape.class, _oDrawPageElement);
321             XControlModel xControlModel = xControlShape.getControl();
322             xServiceInfo = UnoRuntime.queryInterface(XServiceInfo.class, xControlShape.getControl());
323             if (xServiceInfo.supportsService("com.sun.star.form.FormComponent"))
324             {
325                 XChild xChild = UnoRuntime.queryInterface(XChild.class, xControlModel);
326                 XNamed xNamed = UnoRuntime.queryInterface(XNamed.class, xChild.getParent());
327                 String sName = xNamed.getName();
328                 return _FormName.equals(sName);
329             }
330         }
331         return false;
332     }
333 
insertFormbyName(String _FormName, XNameContainer _xNamedFormContainer)334     public XNameContainer insertFormbyName(String _FormName, XNameContainer _xNamedFormContainer)
335     {
336         try
337         {
338             Object oDBForm;
339             if (!hasFormByName(_FormName))
340             {
341                 oDBForm = xMSFDoc.createInstance("com.sun.star.form.component.Form");
342                 _xNamedFormContainer.insertByName(_FormName, oDBForm);
343                 XNameContainer xNamedForm;
344                 xNamedForm = UnoRuntime.queryInterface(XNameContainer.class, oDBForm);
345                 return xNamedForm;
346             }
347             else
348             {
349                 return getFormByName(_FormName);
350             }
351         }
352         catch (com.sun.star.uno.Exception e)
353         {
354             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
355             return null;
356         }
357     }
358 
insertSubFormbyName(String _FormName, XNameContainer _xNamedFormContainer)359     public XNameContainer insertSubFormbyName(String _FormName, XNameContainer _xNamedFormContainer)
360     {
361         return insertFormbyName(_FormName, _xNamedFormContainer);
362     }
363 
insertFormbyName(String _FormName)364     public XNameContainer insertFormbyName(String _FormName)
365     {
366         return insertFormbyName(_FormName, getDocumentForms());
367     }
368 
getFormByName(String _sname)369     public XNameContainer getFormByName(String _sname)
370     {
371         XNameContainer xNamedForm = null;
372         try
373         {
374             if (xNamedForms.hasByName(_sname))
375             {
376                 Object oDBForm = AnyConverter.toObject(new Type(XInterface.class), Helper.getUnoObjectbyName(xNamedForms, _sname));
377                 xNamedForm = UnoRuntime.queryInterface(XNameContainer.class, oDBForm);
378             }
379         }
380         catch (IllegalArgumentException e)
381         {
382             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
383         }
384         return xNamedForm;
385     }
386 
387     /**
388      * @return
389      */
getXPixelFactor()390     public int getXPixelFactor()
391     {
392         if (iXPixelFactor == -1)
393         {
394             initializeBasicControlValues();
395         }
396         return iXPixelFactor;
397     }
398 
399     /**
400      * @return
401      */
getYPixelFactor()402     public int getYPixelFactor()
403     {
404         if (iYPixelFactor == -1)
405         {
406             initializeBasicControlValues();
407         }
408         return iYPixelFactor;
409     }
410 
411     /**
412      * @param i
413      */
setXPixelFactor(int i)414     public void setXPixelFactor(int i)
415     {
416         iXPixelFactor = i;
417     }
418 
419     /**
420      * @param i
421      */
setYPixelFactor(int i)422     public void setYPixelFactor(int i)
423     {
424         iYPixelFactor = i;
425     }
426 
427     /**
428      * @return
429      */
getImageControlHeight()430     public int getImageControlHeight()
431     {
432         return iImageControlHeight;
433     }
434 
435     /**
436      * @param i
437      */
setImageControlHeight(int i)438     public void setImageControlHeight(int i)
439     {
440         iImageControlHeight = i;
441     }
442     // Note: as Shapes cannot be removed from the DrawPage without destroying
443     // the object we have to park them somewhere beyond the visible area of the page
moveShapesToNirwana(Control[] ControlList)444     public void moveShapesToNirwana(Control[] ControlList)
445     {
446         if (ControlList != null)
447         {
448             for (int i = 0; i < ControlList.length; i++)
449             {
450                 if (ControlList[i] != null)
451 //              try {
452 //                  this.xDrawPage.remove(ControlList[i].xShape);
453                 {
454                     ControlList[i].setPosition(new Point(this.iXNirwanaPos, this.iYNirwanaPos));
455 //                  String sControlName = (String) ControlList[i].xPropertySet.getPropertyValue(PropertyNames.PROPERTY_NAME);
456 //
457 //                  if (_xNamedForm.hasByName(sControlName))
458 //                      _xNamedForm.removeByName(sControlName);
459 //              } catch (Exception e) {
460 //                  e.printStackTrace(System.out);
461 //              }
462                 }
463             }
464         }
465     }
466 
moveShapesToNirwana()467     public void moveShapesToNirwana()
468     {
469         try
470         {
471             for (int i = 0; i < this.xDrawPage.getCount(); i++)
472             {
473                 XShape xShape = UnoRuntime.queryInterface(XShape.class, xDrawPage.getByIndex(i));
474                 xShape.setPosition(new Point(this.iXNirwanaPos, this.iYNirwanaPos));
475             }
476         }
477         catch (Exception e)
478         {
479             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
480         }
481     }
482 
removeAllShapes()483     public void removeAllShapes() throws Exception
484     {
485         for (int i = this.xDrawPage.getCount(); i > -1; i--)
486         {
487             XShape xShape = UnoRuntime.queryInterface(XShape.class, xDrawPage.getByIndex(i));
488             removeShape(xShape);
489         }
490     }
491 
492     /**
493      * By removing the shape the whole control is disposed too
494      *
495      */
removeShape(XShape _xShape)496     public void removeShape(XShape _xShape)
497     {
498         xDrawPage.remove(_xShape);
499         XComponent xComponent = UnoRuntime.queryInterface(XComponent.class, _xShape);
500         xComponent.dispose();
501     }
502     // Destroy all Shapes in Nirwana
removeNirwanaShapes()503     public void removeNirwanaShapes() throws Exception
504     {
505         for (int i = this.xDrawPage.getCount(); i > -1; i--)
506         {
507             XShape xShape = UnoRuntime.queryInterface(XShape.class, xDrawPage.getByIndex(i));
508             if (xShape.getPosition().Y < this.iYNirwanaPos)
509             {
510                 xDrawPage.remove(xShape);
511             }
512         }
513     }
514 
groupShapesTogether(XMultiServiceFactory _xMSF, XShape _xLabelShape, XShape _xControlShape)515     public XShape groupShapesTogether(XMultiServiceFactory _xMSF, XShape _xLabelShape, XShape _xControlShape)
516     {
517         try
518         {
519             Object oGroupShape = _xMSF.createInstance("com.sun.star.drawing.ShapeCollection");
520             XShapes xShapes = UnoRuntime.queryInterface(XShapes.class, oGroupShape);
521             xShapes.add(_xLabelShape);
522             xShapes.add(_xControlShape);
523             return this.xShapeGrouper.group(xShapes);
524         }
525         catch (Exception e)
526         {
527             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
528             return null;
529         }
530     }
531 
532     /**
533      * @return
534      */
getBasicLabelDiffHeight()535     public int getBasicLabelDiffHeight()
536     {
537         if (this.BasicLabelDiffHeight == -1)
538         {
539             initializeBasicControlValues();
540         }
541         return BasicLabelDiffHeight;
542     }
543 
544     /**
545      * @return
546      */
getControlReferenceHeight()547     public int getControlReferenceHeight()
548     {
549         if (this.nDBRefHeight == -1)
550         {
551             initializeBasicControlValues();
552         }
553         return nDBRefHeight;
554     }
555 
556     /**
557      * @return
558      */
getLabelHeight()559     public int getLabelHeight()
560     {
561         if (this.nLabelHeight == -1)
562         {
563             initializeBasicControlValues();
564         }
565         return nLabelHeight;
566     }
567 
setDrawObjectsCaptureMode(boolean _bCaptureObjects)568     public void setDrawObjectsCaptureMode(boolean _bCaptureObjects)
569     {
570         try
571         {
572             XPropertySet xPropertySet = UnoRuntime.queryInterface(XPropertySet.class, this.xMSFDoc.createInstance("com.sun.star.text.DocumentSettings"));
573             xPropertySet.setPropertyValue("DoNotCaptureDrawObjsOnPage", Boolean.valueOf(!_bCaptureObjects));
574         }
575         catch (Exception e)
576         {
577             Logger.getLogger(FormHandler.class.getName()).log(Level.SEVERE, null, e);
578         }
579     }
580 }
581