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 
24 package complex.reportdesign;
25 
26 import java.io.File;
27 import java.util.ArrayList;
28 
29 import com.sun.star.beans.PropertyValue;
30 import com.sun.star.beans.XPropertySet;
31 import com.sun.star.container.XNameAccess;
32 import com.sun.star.frame.XComponentLoader;
33 import com.sun.star.frame.XDesktop;
34 import com.sun.star.frame.XModel;
35 import com.sun.star.frame.XStorable;
36 import com.sun.star.lang.XComponent;
37 import com.sun.star.lang.XMultiServiceFactory;
38 import com.sun.star.sdb.XDocumentDataSource;
39 import com.sun.star.sdb.XOfficeDatabaseDocument;
40 import com.sun.star.sdb.XReportDocumentsSupplier;
41 import com.sun.star.sdb.application.XDatabaseDocumentUI;
42 import com.sun.star.uno.UnoRuntime;
43 import com.sun.star.uno.XInterface;
44 import com.sun.star.util.XCloseable;
45 
46 // import util.BasicMacroTools;
47 // import util.DesktopTools;
48 // import util.dbg;
49 // import complexlib.ComplexTestCase;
50 // import util.utils;
51 import helper.OfficeProvider;
52 import helper.URLHelper;
53 // import helper.OfficeWatcher;
54 
55 import convwatch.DB;
56 
57 // import java.util.Date;
58 // import java.text.SimpleDateFormat;
59 // import java.text.ParsePosition;
60 // import java.sql.Time;
61 //
62 // import java.io.BufferedReader;
63 // import java.io.File;
64 // import java.io.FileReader;
65 // import java.io.IOException;
66 // import java.io.FilenameFilter;
67 //
68 // import java.util.Vector;
69 //
70 // import helper.AppProvider;
71 // import java.text.DecimalFormat;
72 // import util.DynamicClassLoader;
73 // import java.util.StringTokenizer;
74 
75 import org.junit.After;
76 import org.junit.AfterClass;
77 import org.junit.Before;
78 import org.junit.BeforeClass;
79 import org.junit.Test;
80 import org.openoffice.test.OfficeConnection;
81 import static org.junit.Assert.*;
82 
83 
84 class PropertySetHelper
85 {
86     XPropertySet m_xPropertySet;
PropertySetHelper(Object _aObj)87     public PropertySetHelper(Object _aObj)
88         {
89             m_xPropertySet = UnoRuntime.queryInterface(XPropertySet.class, _aObj);
90         }
91 
92     /**
93        get a property and don't convert it
94        @param _sName the string name of the property
95        @return the object value of the property without any conversion
96     */
getPropertyValueAsObject(String _sName)97     public Object getPropertyValueAsObject(String _sName)
98         {
99             Object aObject = null;
100 
101             if (m_xPropertySet != null)
102             {
103                 try
104                 {
105                     aObject = m_xPropertySet.getPropertyValue(_sName);
106                 }
107                 catch (com.sun.star.beans.UnknownPropertyException e)
108                 {
109                     System.out.println("ERROR: UnknownPropertyException caught. '" + _sName + "'");
110                     System.out.println("Message: " + e.getMessage());
111                 }
112                 catch (com.sun.star.lang.WrappedTargetException e)
113                 {
114                     System.out.println("ERROR: WrappedTargetException caught.");
115                     System.out.println("Message: " + e.getMessage());
116                 }
117             }
118             return aObject;
119         }
120 }
121 
122 class PropertyHelper
123 {
124     /**
125        Create a PropertyValue[] from a ArrayList
126        @param _aArrayList
127        @return a PropertyValue[]
128     */
createPropertyValueArrayFormArrayList(ArrayList _aPropertyList)129     public static PropertyValue[] createPropertyValueArrayFormArrayList(ArrayList _aPropertyList)
130         {
131             // copy the whole PropertyValue List to an PropertyValue Array
132             PropertyValue[] aSaveProperties = null;
133 
134             if (_aPropertyList == null)
135             {
136                 aSaveProperties = new PropertyValue[0];
137             }
138             else
139             {
140                 if (_aPropertyList.size() > 0)
141                 {
142                     aSaveProperties = new PropertyValue[_aPropertyList.size()];
143                     for (int i = 0;i<_aPropertyList.size(); i++)
144                     {
145                         aSaveProperties[i] = (PropertyValue) _aPropertyList.get(i);
146                     }
147                 }
148                 else
149                 {
150                     aSaveProperties = new PropertyValue[0];
151                 }
152             }
153             return aSaveProperties;
154         }
155 }
156 
157 public class ReportDesignerTest
158 {
159 
160     String mTestDocumentPath;
161 
162 //    public String[] getTestMethodNames()
163 //        {
164 //            return new String[] {"firsttest"};
165 //        }
166 
before()167     @Before public void before()
168     {
169         System.out.println("before");
170         // String tempdir = System.getProperty("java.io.tmpdir");
171         //
172         int dummy = 0;
173         // m_xXMultiServiceFactory = getMSF();
174     }
175 
after()176     @After public void after()
177     {
178         System.out.println("after");
179     }
180 
181 //    private void checkIfOfficeExists(String _sOfficePathWithTrash)
182 //        {
183 //            String sOfficePath = "";
184 //            int nIndex = _sOfficePathWithTrash.indexOf("soffice.exe");
185 //            if (nIndex > 0)
186 //            {
187 //                sOfficePath = _sOfficePathWithTrash.substring(0, nIndex + 11);
188 //            }
189 //            else
190 //            {
191 //                nIndex = _sOfficePathWithTrash.indexOf("soffice");
192 //                if (nIndex > 0)
193 //                {
194 //                    sOfficePath = _sOfficePathWithTrash.substring(0, nIndex + 7);
195 //                }
196 //            }
197 //
198 //            System.out.println(sOfficePath);
199 //            File sOffice = new File(sOfficePath);
200 //            if (! sOffice.exists())
201 //            {
202 //                System.out.println("ERROR: There exists no office installation at given path: '" + sOfficePath + "'");
203 //                System.exit(0);
204 //            }
205 //        }
206 
207 
208     private XDesktop m_xDesktop = null;
getXDesktop()209     public XDesktop getXDesktop()
210         {
211 
212             if (m_xDesktop == null)
213             {
214                 try
215                 {
216                     XInterface xInterface = (XInterface) getMSF().createInstance( "com.sun.star.frame.Desktop" );
217                     m_xDesktop = UnoRuntime.queryInterface(XDesktop.class, xInterface);
218                     assertNotNull("Can't get XDesktop", m_xDesktop);
219                 }
220                 catch (com.sun.star.uno.Exception e)
221                 {
222                     System.out.println("ERROR: uno.Exception caught");
223                     System.out.println("Message: " + e.getMessage());
224                 }
225             }
226             return m_xDesktop;
227         }
228 
showElements(XNameAccess _xNameAccess)229     private void showElements(XNameAccess _xNameAccess)
230         {
231             if (_xNameAccess != null)
232             {
233                 String[] sElementNames = _xNameAccess.getElementNames();
234                 for(int i=0;i<sElementNames.length; i++)
235                 {
236                     System.out.println("Value: [" + i + "] := " + sElementNames[i]);
237                 }
238             }
239             else
240             {
241                 System.out.println("Warning: Given object is null.");
242             }
243         }
244 
245 
246     private OfficeProvider m_aProvider = null;
247 //    private void startOffice()
248 //        {
249 //            // int tempTime = param.getInt("SingleTimeOut");
250 //            param.put("TimeOut", new Integer(300000));
251 //            System.out.println("TimeOut: " + param.getInt("TimeOut"));
252 //            System.out.println("ThreadTimeOut: " + param.getInt("ThreadTimeOut"));
253 //
254 //            // OfficeProvider aProvider = null;
255 //            m_aProvider = new OfficeProvider();
256 //            m_xXMultiServiceFactory = (XMultiServiceFactory) m_aProvider.getManager(param);
257 //            param.put("ServiceFactory", m_xXMultiServiceFactory);
258 //        }
259 //
260 //    private void stopOffice()
261 //        {
262 //            if (m_aProvider != null)
263 //            {
264 //                m_aProvider.closeExistingOffice(param, true);
265 //                m_aProvider = null;
266 //            }
267 //        }
268 
269     private String m_sMailAddress = null;
270     private String m_sUPDMinor;
271     private String m_sCWS_WORK_STAMP;
272 
273     private static final int WRITER = 1;
274     private static final int CALC = 2;
275 
firsttest()276     @Test public void firsttest()
277         {
278             // convwatch.GlobalLogWriter.set(log);
279 
280             // -------------------- preconditions, try to find an office --------------------
281 
282 //                String sAppExecutionCommand = (String) param.get("AppExecutionCommand");
283 
284             String sUser = System.getProperty("user.name");
285             System.out.println("user.name='" + sUser + "'");
286 
287             String sVCSID = System.getProperty("VCSID");
288             System.out.println("VCSID='" + sVCSID + "'");
289             m_sMailAddress = sVCSID + "@openoffice.org";
290             System.out.println("Assumed mail address: " + m_sMailAddress);
291 
292             m_sUPDMinor = System.getProperty("UPDMINOR");
293             m_sCWS_WORK_STAMP = System.getProperty("CWS_WORK_STAMP");
294             // createDBEntry();
295             System.out.println("Current CWS: " + m_sCWS_WORK_STAMP);
296             System.out.println("Current MWS: " + m_sUPDMinor);
297 
298             // System.exit(1);
299 
300 //                sAppExecutionCommand = sAppExecutionCommand.replaceAll( "\\$\\{USERNAME\\}", sUser);
301 //                System.out.println("sAppExecutionCommand='" + sAppExecutionCommand + "'");
302 //
303             // an other way to replace strings
304             // sAppExecutionCommand = utils.replaceAll13(sAppExecutionCommand, "${USERNAME}", sUser);
305 
306 //                checkIfOfficeExists(sAppExecutionCommand);
307 //                param.put("AppExecutionCommand", new String(sAppExecutionCommand));
308 
309             // --------------------------- Start the given Office ---------------------------
310 
311 //                startOffice();
312 
313             // ------------------------------ Start a test run ------------------------------
314 
315 //            String sCurrentDirectory = System.getProperty("user.dir");
316 //            System.out.println("Current Dir: " + sCurrentDirectory);
317 //
318             String sWriterDocument =  TestDocument.getUrl("RPTWriterTests.odb");
319             startTestForFile(sWriterDocument, WRITER);
320 
321             String sCalcDocument =  TestDocument.getUrl("RPTCalcTests.odb");
322             startTestForFile(sCalcDocument, CALC);
323 //            catch (AssureException e)
324 //            {
325 //                stopOffice();
326 //                throw new AssureException(e.getMessage());
327 //            }
328 //
329             // ------------------------------ Office shutdown ------------------------------
330 //            stopOffice();
331         }
332 
333 // -----------------------------------------------------------------------------
startTestForFile(String _sDocument, int _nType)334     private void startTestForFile(String _sDocument, int _nType)
335         {
336             FileURL aFileURL = new FileURL(_sDocument);
337             assertTrue("Test File doesn't '" + _sDocument + "'exist.", aFileURL.exists());
338 
339             String sFileURL = _sDocument; // URLHelper.getFileURLFromSystemPath(_sDocument);
340             System.out.println("File URL: " + sFileURL);
341 
342             XComponent xDocComponent = loadComponent(sFileURL, getXDesktop(), null);
343             System.out.println("Load done");
344             assertNotNull("Can't load document ", xDocComponent);
345 
346             // 	context = createUnoService("com.sun.star.sdb.DatabaseContext")
347 //     oDataBase = context.getByName("hh")
348 //     oDBDoc = oDataBase.DatabaseDocument
349 //
350 // 	dim args(1) as new com.sun.star.beans.PropertyValue
351 // 	args(0).Name = "ActiveConnection"
352 // 	args(0).Value = oDBDoc.getCurrentController().getPropertyValue("ActiveConnection")
353 // 	reportContainer = oDBDoc.getReportDocuments()
354 //     report = reportContainer.loadComponentFromURL("Report40","",0,args)
355 
356             try
357             {
358                 XInterface x = (XInterface)getMSF().createInstance("com.sun.star.sdb.DatabaseContext");
359                 assertNotNull("can't create instance of com.sun.star.sdb.DatabaseContext", x);
360                 System.out.println("createInstance com.sun.star.sdb.DatabaseContext done");
361 
362                 XNameAccess xNameAccess = UnoRuntime.queryInterface(XNameAccess.class, x);
363                 showElements(xNameAccess);
364                 Object aObj = xNameAccess.getByName(sFileURL);
365 //                    System.out.println("1");
366 
367                     // PropertySetHelper aHelper = new PropertySetHelper(aObj);
368                 XDocumentDataSource xDataSource = UnoRuntime.queryInterface(XDocumentDataSource.class, aObj);
369 //                    Object aDatabaseDocmuent = aHelper.getPropertyValueAsObject("DatabaseDocument");
370                 XOfficeDatabaseDocument xOfficeDBDoc = xDataSource.getDatabaseDocument();
371 
372                 // XOfficeDatabaseDocument xOfficeDBDoc = (XOfficeDatabaseDocument)UnoRuntime.queryInterface(XOfficeDatabaseDocument.class, aDatabaseDocument);
373                 assertNotNull("can't access DatabaseDocument", xOfficeDBDoc);
374 //                    System.out.println("2");
375 
376                 XModel xDBSource = UnoRuntime.queryInterface(XModel.class, xOfficeDBDoc);
377                 Object aController = xDBSource.getCurrentController();
378                 assertNotNull("Controller of xOfficeDatabaseDocument is empty!", aController);
379 //                     System.out.println("3");
380 
381                 XDatabaseDocumentUI aDBDocUI = UnoRuntime.queryInterface(XDatabaseDocumentUI.class, aController);
382                 /* boolean isConnect = */
383 // TODO: throws an exception in DEV300m78
384                 aDBDocUI.connect();
385 //                     if (isConnect)
386 //                     {
387 //                         System.out.println("true");
388 //                     }
389 //                     else
390 //                     {
391 //                         System.out.println("false");
392 //                     }
393 //                     System.out.println("4");
394 
395                 // aHelper = new PropertySetHelper(aController);
396 
397                 // Object aActiveConnectionObj = aHelper.getPropertyValueAsObject("ActiveConnection");
398                 Object aActiveConnectionObj = aDBDocUI.getActiveConnection();
399                 assertNotNull("ActiveConnection is empty", aActiveConnectionObj);
400 //                     System.out.println("5");
401 
402                 XReportDocumentsSupplier xSupplier = UnoRuntime.queryInterface(XReportDocumentsSupplier.class, xOfficeDBDoc);
403                 xNameAccess = xSupplier.getReportDocuments();
404                 assertNotNull("xOfficeDatabaseDocument returns no Report Document", xNameAccess);
405 //                     System.out.println("5");
406 
407                 showElements(xNameAccess);
408 
409                 ArrayList<PropertyValue> aPropertyList = new ArrayList<PropertyValue>();
410 
411                 PropertyValue aActiveConnection = new PropertyValue();
412                 aActiveConnection.Name = "ActiveConnection";
413                 aActiveConnection.Value = aActiveConnectionObj;
414                 aPropertyList.add(aActiveConnection);
415 
416                 loadAndStoreReports(xNameAccess, aPropertyList, _nType);
417                 createDBEntry(_nType);
418             }
419             catch(com.sun.star.uno.Exception e)
420             {
421                 fail("ERROR: Exception caught" + e.getMessage());
422             }
423 
424                 // String mTestDocumentPath = (String) param.get("TestDocumentPath");
425                 // System.out.println("mTestDocumentPath: '" + mTestDocumentPath + "'");
426                 // // workaround for issue using deprecated "DOCPTH" prop
427                 // System.setProperty("DOCPTH", mTestDocumentPath);
428 
429                 // Close the document
430                 closeComponent(xDocComponent);
431         }
432 
getDocumentPoolName(int _nType)433     private String getDocumentPoolName(int _nType)
434         {
435             return getFileFormat(_nType);
436         }
437 
438 // -----------------------------------------------------------------------------
createDBEntry(int _nType)439     private void createDBEntry(int _nType)
440         {
441             // try to connect the database
442             String sDBConnection = ""; // (String)param.get( convwatch.PropertyName.DB_CONNECTION_STRING );
443             System.out.println("DBConnection: " + sDBConnection);
444             DB.init(sDBConnection);
445             String sDestinationVersion = m_sCWS_WORK_STAMP;
446             if (sDestinationVersion.length() == 0)
447             {
448                 sDestinationVersion = m_sUPDMinor;
449             }
450             String sDestinationName = "";
451             String sDestinationCreatorType = "";
452             String sDocumentPoolDir = getOutputPath(_nType);
453             String sDocumentPoolName = getDocumentPoolName(_nType);
454             String sSpecial = "";
455 
456             String sFixRefSubDirectory = "ReportDesign_qa_complex_" + getFileFormat(_nType);
457 //            DB.insertinto_documentcompare(sFixRefSubDirectory, "", "fixref",
458 //                                          sDestinationVersion, sDestinationName, sDestinationCreatorType,
459 //                                          sDocumentPoolDir, sDocumentPoolName, m_sMailAddress,
460 //                                          sSpecial);
461             // DB.test();
462             // System.exit(1);
463         }
464 
loadAndStoreReports(XNameAccess _xNameAccess, ArrayList _aPropertyList, int _nType)465     private void loadAndStoreReports(XNameAccess _xNameAccess, ArrayList _aPropertyList, int _nType)
466         {
467             if (_xNameAccess != null)
468             {
469                 String[] sElementNames = _xNameAccess.getElementNames();
470                 for(int i=0;i<sElementNames.length; i++)
471                 {
472                     String sReportName = sElementNames[i];
473                     XComponent xDoc = loadComponent(sReportName, _xNameAccess, _aPropertyList);
474                     // print? or store?
475                     storeComponent(sReportName, xDoc, _nType);
476                     closeComponent(xDoc);
477                 }
478             }
479         }
480 
getFormatExtension(int _nType)481     private String getFormatExtension(int _nType)
482         {
483             String sExtension;
484             switch(_nType)
485             {
486             case WRITER:
487                 sExtension = ".odt";
488                 break;
489             case CALC:
490                 sExtension = ".ods";
491                 break;
492             default:
493                 sExtension = ".UNKNOWN";
494             }
495             return sExtension;
496         }
getFileFormat(int _nType)497     private String getFileFormat(int _nType)
498         {
499             String sFileType;
500             switch(_nType)
501             {
502             case WRITER:
503                 sFileType = "writer8";
504                 break;
505             case CALC:
506                 sFileType = "calc8";
507                 break;
508             default:
509                 sFileType = "UNKNOWN";
510             }
511             return sFileType;
512         }
513 
getOutputPath(int _nType)514     private String getOutputPath(int _nType)
515         {
516             String sOutputPath = util.utils.getOfficeTemp/*Dir*/(getMSF());// (String)param.get( convwatch.PropertyName.DOC_COMPARATOR_OUTPUT_PATH );
517 
518             if (!sOutputPath.endsWith("/") ||         // construct the output file name
519                 !sOutputPath.endsWith("\\"))
520             {
521                 sOutputPath += System.getProperty("file.separator");
522             }
523             sOutputPath += "tmp_123";
524             sOutputPath += System.getProperty("file.separator");
525 
526             // sOutputPath += getFileFormat(_nType);
527             // sOutputPath += System.getProperty("file.separator");
528 
529             File aOutputFile = new File(sOutputPath); // create the directory of the given output path
530             aOutputFile.mkdirs();
531 
532             return sOutputPath;
533         }
534 
535     /*
536       store given _xComponent under the given Name in DOC_COMPARATOR_INPUTPATH
537      */
storeComponent(String _sName, Object _xComponent, int _nType)538     private void storeComponent(String _sName, Object _xComponent, int _nType)
539         {
540             String sOutputPath = getOutputPath(_nType);
541 
542             // add DocumentPoolName
543             sOutputPath += getDocumentPoolName(_nType);
544             sOutputPath += System.getProperty("file.separator");
545 
546             File aOutputFile = new File(sOutputPath); // create the directory of the given output path
547             aOutputFile.mkdirs();
548 
549             sOutputPath += _sName;
550             sOutputPath += getFormatExtension(_nType);
551 
552             String sOutputURL = URLHelper.getFileURLFromSystemPath(sOutputPath);
553 
554             ArrayList<PropertyValue> aPropertyList = new ArrayList<PropertyValue>(); // set some properties for storeAsURL
555 
556             PropertyValue aFileFormat = new PropertyValue();
557             aFileFormat.Name = "FilterName";
558             aFileFormat.Value = getFileFormat(_nType);
559             aPropertyList.add(aFileFormat);
560 
561             PropertyValue aOverwrite = new PropertyValue(); // always overwrite already exist files
562             aOverwrite.Name = "Overwrite";
563             aOverwrite.Value = Boolean.TRUE;
564             aPropertyList.add(aOverwrite);
565 
566             // store the document in an other directory
567             XStorable aStorable = UnoRuntime.queryInterface(XStorable.class, _xComponent);
568             if (aStorable != null)
569             {
570                 System.out.println("store document as URL: '" + sOutputURL + "'");
571                 try
572                 {
573                     aStorable.storeAsURL(sOutputURL, PropertyHelper.createPropertyValueArrayFormArrayList(aPropertyList));
574                 }
575                 catch (com.sun.star.io.IOException e)
576                 {
577                     System.out.println("ERROR: Exception caught");
578                     System.out.println("Can't write document URL: '" + sOutputURL + "'");
579                     System.out.println("Message: " + e.getMessage());
580                 }
581             }
582         }
583 
loadComponent(String _sName, Object _xComponent, ArrayList _aPropertyList)584     private XComponent loadComponent(String _sName, Object _xComponent, ArrayList _aPropertyList)
585         {
586             XComponent xDocComponent = null;
587             XComponentLoader xComponentLoader = UnoRuntime.queryInterface(XComponentLoader.class, _xComponent);
588 
589             try
590             {
591                 PropertyValue[] aLoadProperties = PropertyHelper.createPropertyValueArrayFormArrayList(_aPropertyList);
592                 System.out.println("Load component: '" + _sName + "'");
593                 xDocComponent = xComponentLoader.loadComponentFromURL(_sName, "_blank", 0, aLoadProperties);
594             }
595             catch (com.sun.star.io.IOException e)
596             {
597                 System.out.println("ERROR: Exception caught");
598                 System.out.println("Can't load document '" + _sName + "'");
599                 System.out.println("Message: " + e.getMessage());
600             }
601             catch (com.sun.star.lang.IllegalArgumentException e)
602             {
603                 System.out.println("ERROR: Exception caught");
604                 System.out.println("Illegal Arguments given to loadComponentFromURL.");
605                 System.out.println("Message: " + e.getMessage());
606             }
607             return xDocComponent;
608         }
609 
closeComponent(XComponent _xDoc)610     private void closeComponent(XComponent _xDoc)
611         {
612             // Close the document
613             XCloseable xCloseable = UnoRuntime.queryInterface(XCloseable.class, _xDoc);
614             try
615             {
616                 xCloseable.close(true);
617             }
618             catch (com.sun.star.util.CloseVetoException e)
619             {
620                 System.out.println("ERROR: CloseVetoException caught");
621                 System.out.println("CloseVetoException occured Can't close document.");
622                 System.out.println("Message: " + e.getMessage());
623             }
624         }
625 
626 
getMSF()627     private XMultiServiceFactory getMSF()
628     {
629         final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
630         return xMSF1;
631     }
632 
633     // setup and close connections
setUpConnection()634     @BeforeClass public static void setUpConnection() throws Exception {
635         System.out.println("setUpConnection()");
636         connection.setUp();
637     }
638 
tearDownConnection()639     @AfterClass public static void tearDownConnection()
640         throws InterruptedException, com.sun.star.uno.Exception
641     {
642         System.out.println("tearDownConnection()");
643         connection.tearDown();
644     }
645 
646     private static final OfficeConnection connection = new OfficeConnection();
647 
648 }
649