1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 package com.sun.star.wizards.db;
19 
20 import java.util.ArrayList;
21 import java.util.logging.Level;
22 import java.util.logging.Logger;
23 
24 import com.sun.star.awt.VclWindowPeerAttribute;
25 import com.sun.star.awt.XWindow;
26 import com.sun.star.awt.XWindowPeer;
27 import com.sun.star.beans.PropertyValue;
28 import com.sun.star.beans.UnknownPropertyException;
29 import com.sun.star.beans.XPropertySet;
30 import com.sun.star.container.XHierarchicalNameAccess;
31 import com.sun.star.container.XHierarchicalNameContainer;
32 import com.sun.star.container.XNameAccess;
33 import com.sun.star.container.XNameContainer;
34 import com.sun.star.frame.XModel;
35 import com.sun.star.frame.XStorable;
36 import com.sun.star.lang.IllegalArgumentException;
37 import com.sun.star.lang.Locale;
38 import com.sun.star.lang.WrappedTargetException;
39 import com.sun.star.lang.XComponent;
40 import com.sun.star.lang.XInitialization;
41 import com.sun.star.lang.XMultiServiceFactory;
42 import com.sun.star.lang.XSingleServiceFactory;
43 import com.sun.star.sdb.XCompletedConnection;
44 import com.sun.star.sdb.XDocumentDataSource;
45 import com.sun.star.sdb.XFormDocumentsSupplier;
46 import com.sun.star.sdb.XOfficeDatabaseDocument;
47 import com.sun.star.sdb.XQueriesSupplier;
48 import com.sun.star.sdb.XQueryDefinitionsSupplier;
49 import com.sun.star.sdb.XReportDocumentsSupplier;
50 import com.sun.star.sdb.tools.XConnectionTools;
51 import com.sun.star.sdbc.DataType;
52 import com.sun.star.sdbc.SQLException;
53 import com.sun.star.sdbc.XConnection;
54 import com.sun.star.sdbc.XDataSource;
55 import com.sun.star.sdbc.XDatabaseMetaData;
56 import com.sun.star.sdbc.XResultSet;
57 import com.sun.star.sdbc.XRow;
58 import com.sun.star.sdbcx.XColumnsSupplier;
59 import com.sun.star.sdbcx.XTablesSupplier;
60 import com.sun.star.task.XInteractionHandler;
61 import com.sun.star.ucb.XSimpleFileAccess;
62 import com.sun.star.ui.dialogs.XExecutableDialog;
63 import com.sun.star.uno.Any;
64 import com.sun.star.uno.AnyConverter;
65 import com.sun.star.uno.UnoRuntime;
66 import com.sun.star.uno.XInterface;
67 import com.sun.star.util.XCloseable;
68 import com.sun.star.util.XNumberFormatsSupplier;
69 import com.sun.star.wizards.common.Configuration;
70 import com.sun.star.wizards.common.Desktop;
71 import com.sun.star.wizards.common.FileAccess;
72 import com.sun.star.wizards.common.JavaTools;
73 import com.sun.star.wizards.common.NamedValueCollection;
74 import com.sun.star.wizards.common.NumberFormatter;
75 import com.sun.star.wizards.common.Properties;
76 import com.sun.star.wizards.common.PropertyNames;
77 import com.sun.star.wizards.common.Resource;
78 import com.sun.star.wizards.common.SystemDialog;
79 
80 public class DBMetaData
81 {
82     private XNameAccess xQueryNames;
83     public XDatabaseMetaData xDBMetaData;
84     private XDataSource m_dataSource;
85     private XPropertySet m_dataSourceSettings;
86     private XOfficeDatabaseDocument xModel;
87     private XPropertySet xDataSourcePropertySet;
88     private java.util.ArrayList<CommandObject> CommandObjects = new ArrayList<CommandObject>(1);
89     private Locale aLocale;
90     public String DataSourceName;
91     public com.sun.star.sdbc.XConnection DBConnection;
92     private com.sun.star.sdb.tools.XConnectionTools m_connectionTools;
93     public com.sun.star.lang.XMultiServiceFactory xMSF;
94     private XComponent xConnectionComponent;
95 
96     private XNameAccess xNameAccess;
97     private XInterface xDatabaseContext;
98     private XWindowPeer xWindowPeer;
99     private String[] TableNames = new String[] {};
100     private String[] QueryNames = new String[] {};
101 
102     protected int[][] WidthList;
103     protected static final int[] NumericTypes = {
104             DataType.TINYINT, // ==  -6;
105             DataType.BIGINT, // ==  -5
106             DataType.NUMERIC, // ==  - 2
107             DataType.DECIMAL, // ==   3;
108             DataType.INTEGER, // ==   4;
109             DataType.SMALLINT, // ==   5;
110             DataType.FLOAT, // ==   6;
111             DataType.REAL, // ==   7;
112             DataType.DOUBLE, // ==   8;
113         };
114     protected static final int[] BinaryTypes = { //new int[12];
115             DataType.BINARY,
116             DataType.VARBINARY,
117             DataType.LONGVARBINARY,
118             DataType.BLOB,
119             DataType.SQLNULL,
120             DataType.OBJECT,
121             DataType.DISTINCT,
122             DataType.STRUCT,
123             DataType.ARRAY,
124             DataType.CLOB,
125             DataType.REF
126             /* DataType.OTHER, */
127         };
128 
129     private int iMaxColumnsInSelect;
130     private int iMaxColumnNameLength = -1;
131     private int iMaxTableNameLength = -1;
132     private boolean bPasswordIsRequired;
133     private static final int NOLIMIT = 9999999;
134     private static final int INVALID = 9999999;
135     public TypeInspector oTypeInspector;
136     private NumberFormatter oNumberFormatter = null;
137     private long lDateCorrection = INVALID;
138     private boolean bdisposeConnection = false;
139 
getDataSourcePropertySet()140     public XPropertySet getDataSourcePropertySet()
141     {
142         return xDataSourcePropertySet;
143     }
144 
DBMetaData(XMultiServiceFactory xMSF)145     public DBMetaData(XMultiServiceFactory xMSF)
146     {
147         getInterfaces(xMSF);
148         InitializeWidthList();
149     }
150 
getNumberFormatter()151     public NumberFormatter getNumberFormatter()
152     {
153         if (oNumberFormatter == null)
154         {
155             try
156             {
157                 XNumberFormatsSupplier xNumberFormatsSupplier = (XNumberFormatsSupplier) AnyConverter.toObject(XNumberFormatsSupplier.class, xDataSourcePropertySet.getPropertyValue("NumberFormatsSupplier"));
158                 //TODO get the locale from the datasource
159                 aLocale = Configuration.getLocale(xMSF);
160                 oNumberFormatter = new NumberFormatter(xMSF, xNumberFormatsSupplier, aLocale);
161                 lDateCorrection = oNumberFormatter.getNullDateCorrection();
162             }
163             catch (Exception e)
164             {
165                 Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
166             }
167         }
168         return oNumberFormatter;
169     }
170 
getNullDateCorrection()171     public long getNullDateCorrection()
172     {
173         if (lDateCorrection == INVALID)
174         {
175             if (oNumberFormatter == null)
176             {
177                 oNumberFormatter = getNumberFormatter();
178             }
179             lDateCorrection = oNumberFormatter.getNullDateCorrection();
180         }
181         return lDateCorrection;
182     }
183 
getInterfaces(XMultiServiceFactory xMSF)184     private void getInterfaces(XMultiServiceFactory xMSF)
185     {
186         try
187         {
188             this.xMSF = xMSF;
189             xDatabaseContext = (XInterface) xMSF.createInstance("com.sun.star.sdb.DatabaseContext");
190             xNameAccess = UnoRuntime.queryInterface( XNameAccess.class, xDatabaseContext );
191             xNameAccess.getElementNames();
192         }
193         catch (Exception e)
194         {
195             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
196         }
197     }
198 
199 
200 
hasTableByName(String _stablename)201     public boolean hasTableByName(String _stablename)
202     {
203         return getTableNamesAsNameAccess().hasByName(_stablename);
204     }
205 
setTableByName(String _tableName)206     public void setTableByName(String _tableName)
207     {
208         CommandObject oTableObject = new CommandObject(_tableName, com.sun.star.sdb.CommandType.TABLE);
209         this.CommandObjects.add(oTableObject);
210     }
211 
getTableByName(String _tablename)212     public CommandObject getTableByName(String _tablename)
213     {
214         return getCommandByName(_tablename, com.sun.star.sdb.CommandType.TABLE);
215     }
216 
getQueryByName(String _queryname)217     public CommandObject getQueryByName(String _queryname)
218     {
219         return getCommandByName(_queryname, com.sun.star.sdb.CommandType.QUERY);
220     }
221 
getCommandByName(String _commandname, int _commandtype)222     public CommandObject getCommandByName(String _commandname, int _commandtype)
223     {
224         CommandObject oCommand = null;
225         for (int i = 0; i < CommandObjects.size(); i++)
226         {
227             oCommand = CommandObjects.get(i);
228             if ((oCommand.Name.equals(_commandname)) && (oCommand.CommandType == _commandtype))
229             {
230                 return oCommand;
231             }
232         }
233         if (oCommand == null)
234         {
235             oCommand = new CommandObject(_commandname, _commandtype);
236             CommandObjects.add(oCommand);
237         }
238         return oCommand;
239     }
240 
setQueryByName(String _QueryName)241     public void setQueryByName(String _QueryName)
242     {
243         CommandObject oQueryObject = new CommandObject(_QueryName, com.sun.star.sdb.CommandType.QUERY);
244         this.CommandObjects.add(oQueryObject);
245     }
246 
247     public class CommandObject
248     {
249 
250         private XNameAccess xColumns;
251         private XPropertySet xPropertySet;
252         private String Name;
253         private int CommandType;
254 
CommandObject(String _CommandName, int _CommandType)255         private CommandObject(String _CommandName, int _CommandType)
256         {
257             try
258             {
259                 Object oCommand;
260                 this.Name = _CommandName;
261                 this.CommandType = _CommandType;
262                 if (CommandType == com.sun.star.sdb.CommandType.TABLE)
263                 {
264                     oCommand = getTableNamesAsNameAccess().getByName(Name);
265                 }
266                 else
267                 {
268                     oCommand = getQueryNamesAsNameAccess().getByName(Name);
269                 }
270                 XColumnsSupplier xCommandCols = UnoRuntime.queryInterface( XColumnsSupplier.class, oCommand );
271                 xPropertySet = UnoRuntime.queryInterface( XPropertySet.class, oCommand );
272 // TODO: Performance leak getColumns() take very long.
273                 xColumns = UnoRuntime.queryInterface( XNameAccess.class, xCommandCols.getColumns() );
274             }
275             catch (Exception e)
276             {
277                 Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
278             }
279         }
getColumns()280         public XNameAccess getColumns()
281         {
282             return xColumns;
283         }
getName()284         public String getName()
285         {
286             return Name;
287         }
getPropertySet()288         public XPropertySet getPropertySet()
289         {
290             return xPropertySet;
291         }
292     }
293 
hasEscapeProcessing(XPropertySet _xQueryPropertySet)294     public boolean hasEscapeProcessing(XPropertySet _xQueryPropertySet)
295     {
296         boolean bHasEscapeProcessing = false;
297         try
298         {
299             if (_xQueryPropertySet.getPropertySetInfo().hasPropertyByName("EscapeProcessing"))
300             {
301                 bHasEscapeProcessing = AnyConverter.toBoolean(_xQueryPropertySet.getPropertyValue("EscapeProcessing"));
302             }
303         }
304         catch (Exception e)
305         {
306             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
307         }
308         return bHasEscapeProcessing;
309     }
310 
getQueryNamesAsNameAccess()311     private XNameAccess getQueryNamesAsNameAccess()
312     {
313         XQueriesSupplier xDBQueries = UnoRuntime.queryInterface( XQueriesSupplier.class, DBConnection );
314         xQueryNames = xDBQueries.getQueries();
315         return xQueryNames;
316     }
317 
getTableNamesAsNameAccess()318     public XNameAccess getTableNamesAsNameAccess()
319     {
320         XTablesSupplier xDBTables = UnoRuntime.queryInterface( XTablesSupplier.class, DBConnection );
321         return xDBTables.getTables();
322     }
323 
getQueryNames()324     public String[] getQueryNames()
325     {
326         if (QueryNames != null && QueryNames.length > 0)
327         {
328             return QueryNames;
329         }
330         QueryNames = getQueryNamesAsNameAccess().getElementNames();
331         return QueryNames;
332     }
333 
getTableNames()334     public String[] getTableNames()
335     {
336         if (TableNames != null && TableNames.length > 0)
337         {
338             return TableNames;
339         }
340         TableNames = getTableNamesAsNameAccess().getElementNames();
341         return TableNames;
342     }
343 
InitializeWidthList()344     private void InitializeWidthList()
345     {
346         WidthList = new int[17][2];
347         WidthList[0][0] = DataType.BIT; // ==  -7;
348         WidthList[1][0] = DataType.BOOLEAN; // = 16
349         WidthList[2][0] = DataType.TINYINT; // ==  -6;
350         WidthList[3][0] = DataType.BIGINT; // ==  -5;
351         WidthList[4][0] = DataType.LONGVARCHAR; // ==  -1;
352         WidthList[5][0] = DataType.CHAR; // ==   1;
353         WidthList[6][0] = DataType.NUMERIC; // ==   2;
354         WidthList[7][0] = DataType.DECIMAL; // ==   3;  [with fractional part]
355         WidthList[8][0] = DataType.INTEGER; // ==   4;
356         WidthList[9][0] = DataType.SMALLINT; // ==   5;
357         WidthList[10][0] = DataType.FLOAT; // ==   6;
358         WidthList[11][0] = DataType.REAL; // ==   7;
359         WidthList[12][0] = DataType.DOUBLE; // ==   8;
360         WidthList[13][0] = DataType.VARCHAR; // ==  12;
361         WidthList[14][0] = DataType.DATE; // ==  91;
362         WidthList[15][0] = DataType.TIME; // ==  92;
363         WidthList[16][0] = DataType.TIMESTAMP; // ==  93;
364         // NumericTypes are all types where aggregate functions can be performed on.
365         // Similarly to a major competitor date/time/timestamp fields are not included
366 
367 
368     }
369 
isBinaryDataType(int _itype)370     public boolean isBinaryDataType(int _itype)
371     {
372         if (NumericTypes == null)
373         {
374             InitializeWidthList();
375         }
376         return (JavaTools.FieldInIntTable(BinaryTypes, _itype) > -1);
377     }
378 
getMaxTablesInSelect()379     public int getMaxTablesInSelect()
380     {
381         try
382         {
383             int itablecount = xDBMetaData.getMaxTablesInSelect();
384             if (itablecount == 0)
385             {
386                 return DBMetaData.NOLIMIT;
387             }
388             else
389             {
390                 return itablecount;
391             }
392         }
393         catch (SQLException e)
394         {
395             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
396             return - 1;
397         }
398     }
399 
getMaxColumnsInSelect()400     public int getMaxColumnsInSelect()
401     {
402         return iMaxColumnsInSelect;
403     }
404 
setMaxColumnsInSelect()405     private void setMaxColumnsInSelect() throws SQLException
406     {
407         iMaxColumnsInSelect = xDBMetaData.getMaxColumnsInSelect();
408         if (iMaxColumnsInSelect == 0)
409         {
410             iMaxColumnsInSelect = DBMetaData.NOLIMIT;
411         }
412     }
413 
getMaxColumnsInTable()414     public int getMaxColumnsInTable() throws SQLException
415     {
416         int iMaxColumnsInTable = xDBMetaData.getMaxColumnsInTable();
417         if (iMaxColumnsInTable == 0)
418         {
419             iMaxColumnsInTable = DBMetaData.NOLIMIT;
420         }
421         return iMaxColumnsInTable;
422     }
423 
getDataSourceObjects()424     private void getDataSourceObjects() throws Exception
425     {
426         try
427         {
428             xDBMetaData = DBConnection.getMetaData();
429             getDataSourceInterfaces();
430             setMaxColumnsInSelect();
431         }
432         catch (SQLException e)
433         {
434             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
435         }
436     }
437 
ensureDataSourceSettings()438     private void ensureDataSourceSettings() throws UnknownPropertyException, WrappedTargetException
439     {
440         if ( m_dataSourceSettings != null )
441             return;
442 
443         XPropertySet dataSourceProperties = UnoRuntime.queryInterface( XPropertySet.class, getDataSource() );
444         m_dataSourceSettings = UnoRuntime.queryInterface( XPropertySet.class, dataSourceProperties.getPropertyValue( "Settings" ) );
445     }
446 
isSQL92CheckEnabled()447     public boolean isSQL92CheckEnabled()
448     {
449         boolean isSQL92CheckEnabled = false;
450         try
451         {
452             ensureDataSourceSettings();
453             isSQL92CheckEnabled = AnyConverter.toBoolean( m_dataSourceSettings.getPropertyValue( "EnableSQL92Check" ) );
454         }
455         catch (Exception e)
456         {
457             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
458         }
459         return isSQL92CheckEnabled;
460     }
461 
getDataSource()462     public XDataSource getDataSource()
463     {
464         if (m_dataSource == null)
465         {
466             try
467             {
468                     Object oDataSource = xNameAccess.getByName(DataSourceName);
469                     m_dataSource = UnoRuntime.queryInterface( XDataSource.class, oDataSource );
470             }
471             catch (com.sun.star.container.NoSuchElementException e)
472             {
473             }
474             catch (com.sun.star.lang.WrappedTargetException e)
475             {
476             }
477         }
478         return m_dataSource;
479     }
480 
setDataSourceByName(String _DataSourceName)481     private void setDataSourceByName(String _DataSourceName)
482     {
483         try
484         {
485             this.DataSourceName = _DataSourceName;
486             getDataSourceInterfaces();
487             XDocumentDataSource xDocu = UnoRuntime.queryInterface( XDocumentDataSource.class, getDataSource() );
488             if (xDocu != null)
489             {
490                 xModel = xDocu.getDatabaseDocument();
491             }
492         }
493         catch (Exception e)
494         {
495             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
496         }
497     }
498 
getDataSourceInterfaces()499     private void getDataSourceInterfaces() throws Exception
500     {
501         xDataSourcePropertySet = UnoRuntime.queryInterface( XPropertySet.class, getDataSource() );
502         bPasswordIsRequired = ((Boolean) xDataSourcePropertySet.getPropertyValue("IsPasswordRequired")).booleanValue();
503     }
504 
getConnection(PropertyValue[] curproperties)505     public boolean getConnection(PropertyValue[] curproperties)
506     {
507         try
508         {
509             XConnection xConnection = null;
510             if (Properties.hasPropertyValue(curproperties, PropertyNames.ACTIVE_CONNECTION))
511             {
512                 xConnection = UnoRuntime.queryInterface( XConnection.class, Properties.getPropertyValue( curproperties, PropertyNames.ACTIVE_CONNECTION ) );
513                 if (xConnection != null)
514                 {
515                     com.sun.star.container.XChild child = UnoRuntime.queryInterface( com.sun.star.container.XChild.class, xConnection );
516 
517                     m_dataSource = UnoRuntime.queryInterface( XDataSource.class, child.getParent() );
518                     XDocumentDataSource xDocu = UnoRuntime.queryInterface( XDocumentDataSource.class, m_dataSource );
519                     if (xDocu != null)
520                     {
521                         xModel = xDocu.getDatabaseDocument();
522                     }
523                     XPropertySet xPSet = UnoRuntime.queryInterface( XPropertySet.class, m_dataSource );
524                     if (xPSet != null)
525                     {
526                         DataSourceName = AnyConverter.toString(xPSet.getPropertyValue(PropertyNames.PROPERTY_NAME));
527                     }
528                     return getConnection(xConnection);
529                 }
530                 else
531                 {
532                     bdisposeConnection = true;
533                 }
534             }
535             else
536             {
537                 bdisposeConnection = true;
538             }
539             if (Properties.hasPropertyValue(curproperties, "DataSourceName"))
540             {
541                 String sDataSourceName = AnyConverter.toString(Properties.getPropertyValue(curproperties, "DataSourceName"));
542                 return getConnection(sDataSourceName);
543             }
544             else if (Properties.hasPropertyValue(curproperties, "DataSource"))
545             {
546                 m_dataSource = UnoRuntime.queryInterface( XDataSource.class, Properties.getPropertyValue( curproperties, "DataSource" ) );
547                 XDocumentDataSource xDocu = UnoRuntime.queryInterface( XDocumentDataSource.class, this.m_dataSource );
548                 if (xDocu != null)
549                 {
550                     xModel = xDocu.getDatabaseDocument();
551                 }
552                 return getConnection(m_dataSource);
553             }
554             if (Properties.hasPropertyValue(curproperties, "DatabaseLocation"))
555             {
556                 String sDataSourceName = AnyConverter.toString(Properties.getPropertyValue(curproperties, "DatabaseLocation"));
557                 return getConnection(sDataSourceName);
558             }
559         }
560         catch (IllegalArgumentException e)
561         {
562             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
563         }
564         catch (UnknownPropertyException e)
565         {
566             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
567         }
568         catch (WrappedTargetException e)
569         {
570             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
571         }
572 
573         return false;
574     }
575 
getConnection(String _DataSourceName)576     private boolean getConnection(String _DataSourceName)
577     {
578         setDataSourceByName(_DataSourceName);
579          return getConnection( getDataSource() );
580     }
581 
getConnection(com.sun.star.sdbc.XConnection _DBConnection)582     private boolean getConnection(com.sun.star.sdbc.XConnection _DBConnection)
583     {
584         try
585         {
586             this.DBConnection = _DBConnection;
587             this.m_connectionTools = UnoRuntime.queryInterface( XConnectionTools.class, this.DBConnection );
588             getDataSourceObjects();
589             return true;
590         }
591         catch (Exception e)
592         {
593             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
594             return false;
595         }
596     }
597 
getConnection(XDataSource _dataSource)598     private boolean getConnection(XDataSource _dataSource)
599     {
600         Resource oResource = new Resource(xMSF);
601         try
602         {
603             int iMsg = 0;
604             boolean bgetConnection = false;
605             if (DBConnection != null)
606             {
607                 xConnectionComponent.dispose();
608             }
609             getDataSourceInterfaces();
610             if (!bPasswordIsRequired)
611             {
612                 DBConnection = _dataSource.getConnection(PropertyNames.EMPTY_STRING, PropertyNames.EMPTY_STRING);
613                 bgetConnection = true;
614             }
615             else
616             {
617                 XInteractionHandler xInteractionHandler = UnoRuntime.queryInterface( XInteractionHandler.class, xMSF.createInstance("com.sun.star.task.InteractionHandler") );
618                 boolean bExitLoop = true;
619                 do
620                 {
621                     XCompletedConnection xCompleted2 = UnoRuntime.queryInterface( XCompletedConnection.class, _dataSource );
622                     try
623                     {
624                         DBConnection = xCompleted2.connectWithCompletion( xInteractionHandler );
625                         bgetConnection = DBConnection != null;
626                         if (!bgetConnection)
627                         {
628                             bExitLoop = true;
629                         }
630                     }
631                     catch (Exception exception)
632                     {
633                         // Note:  WindowAttributes from toolkit/source/awt/vclxtoolkit.cxx
634                         String sMsgNoConnection = oResource.getResText("RID_DB_COMMON_14");
635                         iMsg = showMessageBox("QueryBox", VclWindowPeerAttribute.RETRY_CANCEL, sMsgNoConnection);
636                         bExitLoop = iMsg == 0;
637                         bgetConnection = false;
638                     }
639                 }
640                 while (!bExitLoop);
641             }
642             if (!bgetConnection)
643             {
644                 String sMsgConnectionImpossible = oResource.getResText("RID_DB_COMMON_35");
645                 showMessageBox("ErrorBox", VclWindowPeerAttribute.OK, sMsgConnectionImpossible);
646             }
647             else
648             {
649                 xConnectionComponent = UnoRuntime.queryInterface( XComponent.class, DBConnection );
650                 m_connectionTools = UnoRuntime.queryInterface( XConnectionTools.class, DBConnection );
651                 getDataSourceObjects();
652             }
653             return bgetConnection;
654         }
655         catch (Exception e)
656         {
657             String sMsgConnectionImpossible = oResource.getResText("RID_DB_COMMON_35");
658             showMessageBox("ErrorBox", VclWindowPeerAttribute.OK, sMsgConnectionImpossible);
659             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
660             return false;
661         }
662     }
663 
getMaxColumnNameLength()664     public int getMaxColumnNameLength()
665     {
666         try
667         {
668             if (iMaxColumnNameLength <= 0)
669             {
670                 iMaxColumnNameLength = xDBMetaData.getMaxColumnNameLength();
671             }
672             return iMaxColumnNameLength;
673         }
674         catch (SQLException e)
675         {
676             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
677             return 0;
678         }
679     }
680 
getMaxTableNameLength()681     public int getMaxTableNameLength()
682     {
683         try
684         {
685             if (iMaxTableNameLength <= 0)
686             {
687                 iMaxTableNameLength = xDBMetaData.getMaxTableNameLength();
688             }
689             return iMaxTableNameLength;
690         }
691         catch (SQLException e)
692         {
693             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
694             return 0;
695         }
696     }
697 
supportsPrimaryKeys()698     public boolean supportsPrimaryKeys()
699     {
700         boolean supportsPrimaryKeys = false;
701         try
702         {
703             ensureDataSourceSettings();
704             Any primaryKeySupport = (Any)m_dataSourceSettings.getPropertyValue( "PrimaryKeySupport" );
705             if ( AnyConverter.isVoid( primaryKeySupport ) )
706                 supportsPrimaryKeys = supportsCoreSQLGrammar();
707             else
708                 supportsPrimaryKeys = AnyConverter.toBoolean( primaryKeySupport );
709         }
710         catch ( Exception ex )
711         {
712             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, ex );
713         }
714         return supportsPrimaryKeys;
715     }
716 
supportsCoreSQLGrammar()717     private boolean supportsCoreSQLGrammar()
718     {
719         try
720         {
721             return xDBMetaData.supportsCoreSQLGrammar();
722         }
723         catch (SQLException e)
724         {
725             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
726             return false;
727         }
728     }
729 
supportsQueriesInFrom()730     public boolean supportsQueriesInFrom() throws SQLException
731     {
732         return m_connectionTools.getDataSourceMetaData().supportsQueriesInFrom();
733     }
734 
suggestName( final int i_objectType, final String i_baseName )735     public String suggestName( final int i_objectType, final String i_baseName ) throws IllegalArgumentException, SQLException
736     {
737         return m_connectionTools.getObjectNames().suggestName( i_objectType, i_baseName );
738     }
739 
740     /**
741      * inserts a Query to a datasource; There is no validation if the queryname is already existing in the datasource
742      */
createQuery(SQLQueryComposer _oSQLQueryComposer, String _QueryName)743     public boolean createQuery(SQLQueryComposer _oSQLQueryComposer, String _QueryName)
744     {
745         try
746         {
747             XQueryDefinitionsSupplier xQueryDefinitionsSuppl = UnoRuntime.queryInterface( XQueryDefinitionsSupplier.class, m_dataSource );
748             XNameAccess xQueryDefs = xQueryDefinitionsSuppl.getQueryDefinitions();
749             XSingleServiceFactory xSSFQueryDefs = UnoRuntime.queryInterface( XSingleServiceFactory.class, xQueryDefs );
750             Object oQuery = xSSFQueryDefs.createInstance(); //"com.sun.star.sdb.QueryDefinition"
751             XPropertySet xPSet = UnoRuntime.queryInterface( XPropertySet.class, oQuery );
752 
753             String s = _oSQLQueryComposer.m_xQueryAnalyzer.getQuery();
754             xPSet.setPropertyValue(PropertyNames.COMMAND, s);
755 
756             XNameContainer xNameCont = UnoRuntime.queryInterface( XNameContainer.class, xQueryDefs );
757             m_connectionTools.getObjectNames().checkNameForCreate(com.sun.star.sdb.CommandType.QUERY, _QueryName);
758             xNameCont.insertByName(_QueryName, oQuery);
759             return true;
760         }
761         catch (WrappedTargetException exception)
762         {
763             SQLException sqlError = null;
764             try
765             {
766                 sqlError = (SQLException) exception.TargetException;
767             }
768             catch (ClassCastException castError)
769             {
770             }
771 
772             if (sqlError != null)
773             {
774                 callSQLErrorMessageDialog(sqlError, null);
775                 return false;
776             }
777             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, exception );
778         }
779         catch (SQLException e)
780         {
781             callSQLErrorMessageDialog(e, null);
782             return false;
783         }
784         catch (Exception e)
785         {
786             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
787         }
788         return false;
789     }
790 
dispose()791     public void dispose()
792     {
793         if ((DBConnection != null) && (this.bdisposeConnection))
794         {
795             xConnectionComponent.dispose();
796         }
797     }
798 
getReportDocuments()799     public XHierarchicalNameAccess getReportDocuments()
800     {
801         XReportDocumentsSupplier xReportDocumentSuppl = UnoRuntime.queryInterface( XReportDocumentsSupplier.class, this.xModel );
802         xReportDocumentSuppl.getReportDocuments();
803         return UnoRuntime.queryInterface( XHierarchicalNameAccess.class, xReportDocumentSuppl.getReportDocuments() );
804     }
805 
getFormDocuments()806     public XHierarchicalNameAccess getFormDocuments()
807     {
808         XFormDocumentsSupplier xFormDocumentSuppl = UnoRuntime.queryInterface( XFormDocumentsSupplier.class, xModel );
809         return UnoRuntime.queryInterface( XHierarchicalNameAccess.class, xFormDocumentSuppl.getFormDocuments() );
810     }
811 
hasFormDocumentByName(String _sFormName)812     public boolean hasFormDocumentByName(String _sFormName)
813     {
814         XFormDocumentsSupplier xFormDocumentSuppl = UnoRuntime.queryInterface( XFormDocumentsSupplier.class, xModel );
815         XNameAccess xFormNameAccess = UnoRuntime.queryInterface( XNameAccess.class, xFormDocumentSuppl.getFormDocuments() );
816         return xFormNameAccess.hasByName(_sFormName);
817     }
818 
addFormDocument(XComponent _xComponent)819     public void addFormDocument(XComponent _xComponent)
820     {
821         XHierarchicalNameAccess _xFormDocNameAccess = getFormDocuments();
822         addDatabaseDocument(_xComponent, _xFormDocNameAccess, false);
823     }
824 
addReportDocument(XComponent _xComponent, boolean _bcreatedynamicreport)825     public void addReportDocument(XComponent _xComponent, boolean _bcreatedynamicreport)
826     {
827         XHierarchicalNameAccess xReportDocNameAccess = getReportDocuments();
828         addDatabaseDocument(_xComponent, xReportDocNameAccess, _bcreatedynamicreport);
829     }
830 
831     /**
832      * adds the passed document as a report or a form to the database. Afterwards the document is deleted.
833      * the document may not be open
834      * @param i_createTemplate  describes the type of the document: "form" or "report"
835      */
addDatabaseDocument(XComponent _xComponent, XHierarchicalNameAccess _xDocNameAccess, boolean i_createTemplate)836     private void addDatabaseDocument(XComponent _xComponent, XHierarchicalNameAccess _xDocNameAccess, boolean i_createTemplate)
837     {
838         try
839         {
840             XModel xDocumentModel = UnoRuntime.queryInterface( XModel.class, _xComponent );
841             String documentURL = xDocumentModel.getURL();
842             String basename = FileAccess.getBasename(documentURL, "/");
843             XCloseable xCloseable = UnoRuntime.queryInterface( XCloseable.class, _xComponent );
844             xCloseable.close(false);
845 
846             NamedValueCollection creationArgs = new NamedValueCollection();
847             creationArgs.put( PropertyNames.PROPERTY_NAME, basename );
848             creationArgs.put( PropertyNames.URL, documentURL );
849             creationArgs.put( "AsTemplate", i_createTemplate );
850             XMultiServiceFactory xDocMSF = UnoRuntime.queryInterface( XMultiServiceFactory.class, _xDocNameAccess );
851             Object oDBDocument = xDocMSF.createInstanceWithArguments( "com.sun.star.sdb.DocumentDefinition", creationArgs.getPropertyValues() );
852             XHierarchicalNameContainer xHier = UnoRuntime.queryInterface( XHierarchicalNameContainer.class, _xDocNameAccess );
853             String sdocname = Desktop.getUniqueName(_xDocNameAccess, basename);
854             xHier.insertByHierarchicalName(sdocname, oDBDocument);
855             XInterface xInterface = (XInterface) xMSF.createInstance("com.sun.star.ucb.SimpleFileAccess");
856             XSimpleFileAccess xSimpleFileAccess = UnoRuntime.queryInterface( XSimpleFileAccess.class, xInterface );
857             xSimpleFileAccess.kill(documentURL);
858         }
859         catch (Exception e)
860         {
861             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
862         }
863     }
864 
createTypeInspector()865     public void createTypeInspector() throws SQLException
866     {
867         oTypeInspector = new TypeInspector(xDBMetaData.getTypeInfo());
868     }
869 
getDBDataTypeInspector()870     public TypeInspector getDBDataTypeInspector()
871     {
872         return oTypeInspector;
873     }
874 
StringsFromResultSet(XResultSet _xResultSet, int _icol)875     private String[] StringsFromResultSet(XResultSet _xResultSet, int _icol)
876     {
877         String[] sColValues = null;
878         if (_xResultSet == null)
879             return sColValues;
880         try
881         {
882             XRow xRow = UnoRuntime.queryInterface( XRow.class, _xResultSet );
883             ArrayList<String> aColVector = new ArrayList<String>();
884             while (_xResultSet.next())
885             {
886                 aColVector.add(xRow.getString(_icol));
887             }
888             sColValues = new String[aColVector.size()];
889             aColVector.toArray(sColValues);
890         }
891         catch (SQLException e)
892         {
893             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
894         }
895         return sColValues;
896     }
897 
getCatalogNames()898     public String[] getCatalogNames()
899     {
900         try
901         {
902             XResultSet xResultSet = xDBMetaData.getCatalogs();
903             return StringsFromResultSet(xResultSet, 1);
904         }
905         catch (SQLException e)
906         {
907             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
908             return null;
909         }
910     }
911 
getSchemaNames()912     public String[] getSchemaNames()
913     {
914         try
915         {
916             XResultSet xResultSet = xDBMetaData.getSchemas();
917             return StringsFromResultSet(xResultSet, 1);
918         }
919         catch (SQLException e)
920         {
921             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
922             return null;
923         }
924     }
925 
storeDatabaseDocumentToTempPath(XComponent _xcomponent, String _storename)926     public boolean storeDatabaseDocumentToTempPath(XComponent _xcomponent, String _storename)
927     {
928         try
929         {
930             String storepath = FileAccess.getOfficePath(xMSF, "Temp") + "/" + _storename;
931             XStorable xStoreable = UnoRuntime.queryInterface( XStorable.class, _xcomponent );
932             PropertyValue[] oStoreProperties = new PropertyValue[1];
933             oStoreProperties[0] = Properties.createProperty("FilterName", "writer8");
934             storepath += ".odt";
935             xStoreable.storeAsURL(storepath, oStoreProperties);
936             return true;
937         }
938         catch (Exception e)
939         {
940             Logger.getLogger( DBMetaData.class.getName() ).log( Level.SEVERE, null, e );
941             return false;
942         }
943     }
944 
showMessageBox(String windowServiceName, int windowAttribute, String MessageText)945     public int showMessageBox(String windowServiceName, int windowAttribute, String MessageText)
946     {
947         if (getWindowPeer() != null)
948         {
949             return SystemDialog.showMessageBox(xMSF, xWindowPeer, windowServiceName, windowAttribute, MessageText);
950         }
951         else
952         {
953             return SystemDialog.showMessageBox(xMSF, windowServiceName, windowAttribute, MessageText);
954         }
955     }
956 
957     /**
958      * @return Returns the xWindowPeer.
959      */
getWindowPeer()960     private XWindowPeer getWindowPeer()
961     {
962         return xWindowPeer;
963     }
964 
965     /**
966      * @param windowPeer The xWindowPeer to set.
967      * Should be called as soon as a Windowpeer of a wizard dialog is available
968      * The windowpeer is needed to call a Messagebox
969      */
setWindowPeer(XWindowPeer windowPeer)970     public void setWindowPeer(XWindowPeer windowPeer)
971     {
972         xWindowPeer = windowPeer;
973     }
974 
callSQLErrorMessageDialog(SQLException oSQLException, XWindow _xWindow)975     public void callSQLErrorMessageDialog(SQLException oSQLException, XWindow _xWindow)
976     {
977         try
978         {
979             Object oDialog = xMSF.createInstance("com.sun.star.sdb.ErrorMessageDialog");
980             XInitialization xInitialization = UnoRuntime.queryInterface( XInitialization.class, oDialog );
981             PropertyValue[] aPropertyValue = new PropertyValue[2];
982             aPropertyValue[0] = Properties.createProperty("SQLException", oSQLException);
983             aPropertyValue[1] = Properties.createProperty("ParentWindow", _xWindow);
984             xInitialization.initialize(aPropertyValue);
985             XExecutableDialog xExecutableDialog = UnoRuntime.queryInterface( XExecutableDialog.class, oDialog );
986             xExecutableDialog.execute();
987         }
988         catch (com.sun.star.uno.Exception ex)
989         {
990             Logger.getLogger( getClass().getName() ).log( Level.SEVERE, "error calling the error dialog", ex );
991         }
992     }
993 
finish()994     public void finish()
995     {
996         xQueryNames = null;
997         xNameAccess = null;
998         xDatabaseContext = null;
999         xDBMetaData = null;
1000         m_dataSource = null;
1001         xModel = null;
1002         xDataSourcePropertySet = null;
1003         xWindowPeer = null;
1004         DBConnection = null;
1005         m_connectionTools = null;
1006         xMSF = null;
1007         xConnectionComponent = null;
1008         CommandObjects = null;
1009     }
1010 }
1011