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