Source code: org/enableit/db/darrt/SchemaExporter.java
1 // Package declaration
2 package org.enableit.db.darrt ;
3
4 // Java imports
5 import java.io.File ;
6 import java.io.FileOutputStream ;
7 import java.sql.Connection ;
8 import java.sql.DatabaseMetaData ;
9 import java.sql.ResultSet ;
10 import java.text.SimpleDateFormat ;
11 import java.util.ArrayList ;
12 import java.util.Arrays ;
13 import java.util.Date ;
14 import java.util.Iterator ;
15 import java.util.List ;
16 import java.util.StringTokenizer ;
17 import java.util.TreeMap ;
18
19 // XML imports (inc in J2EE)
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.DocumentBuilderFactory;
22 import javax.xml.parsers.FactoryConfigurationError;
23 import javax.xml.parsers.ParserConfigurationException;
24
25 import org.w3c.dom.Document;
26 import org.w3c.dom.Element;
27 import org.w3c.dom.Node;
28 import org.w3c.dom.NodeList;
29
30 // Log4J imports
31 import org.apache.log4j.Category;
32
33 import org.enableit.db.ConnectionFactory ;
34 import org.enableit.db.DataSourceProxy ;
35 import org.enableit.db.DBException ;
36 import org.enableit.db.DBUtils ;
37 import org.enableit.db.SqlType ;
38 import org.enableit.db.darrt.schema.ProviderExt ;
39
40 /**
41 * Export database schemas as XML.
42 *
43 * Note on ASA interpretation of DatabaseMetaData object:
44 * SchemaConstants.SCHEMA = users and groups
45 */
46 public class SchemaExporter extends AbstractSchemaHandler {
47 /*
48 * Constructors
49 */
50 /**
51 * Default Constructor
52 */
53 public SchemaExporter() {
54 formatter = new SimpleDateFormat() ;
55 }
56
57 /**
58 * The name of the schema to be exported.
59 * <p>
60 * If no schema is specified all will be exported.
61 */
62 public void setTargetSchema(String targetSchema) {
63 logger.info("METHOD_ENTRY: setTargetSchema: " + targetSchema);
64
65 this.targetSchema = targetSchema ;
66
67 logger.info("METHOD_EXIT: setTargetSchema");
68 }
69
70 /**
71 * Set the table types to export.
72 */
73 public void setTableTypes(String tableTypes) {
74 StringTokenizer st = new StringTokenizer(tableTypes, ",");
75 String[] tableTypesArray = new String[st.countTokens()] ;
76 int i = 0 ;
77 while (st.hasMoreTokens()) {
78 tableTypesArray[i++] = st.nextToken().trim();
79 }
80 setTableTypes(tableTypesArray);
81 }
82
83 /**
84 * An array of table types to be exported.
85 * <p>
86 * Table types include such things as 'TABLE' and 'VIEW',
87 * though the exact list depends
88 * on the database vendor.
89 * <p>
90 * If no table types are specified all will be exported.
91 */
92 public void setTableTypes(String[] tableTypes) {
93
94 if (tableTypes==null) {
95 this.tableTypes = null ;
96 } else {
97 /*
98 * The objective here is to set the local array to the
99 * parameter array but to exclude VIEW
100 */
101 this.tableTypes = new String[tableTypes.length-1] ;
102 logger.debug("No. of table types =" + tableTypes.length);
103
104 int j = 0 ;
105 try {
106 for (int i=0 ; i<tableTypes.length ; i++) {
107 if (!SchemaConstants.VIEW.equalsIgnoreCase(tableTypes[i])) {
108 this.tableTypes[j++] = tableTypes[i] ;
109 }
110 }
111 } catch (ArrayIndexOutOfBoundsException e) {
112 this.tableTypes = tableTypes ;
113 }
114 logger.info("tableTypes=" + Arrays.asList(this.tableTypes));
115 }
116
117 logger.info("METHOD_EXIT: setTableTypes");
118 }
119
120 /**
121 * Export the schema identified by the provided connection parameters.
122 */
123 public Document export(String driver, String url,
124 String userid, String password)
125 throws DBException {
126 logger.info("METHOD_ENTRY: export: " + driver + ","
127 + url + "," + userid + "," + password) ;
128
129 Document doc = null ;
130 try {
131 // Set the provider to avoid NPE in output
132 provider = new ProviderExt() ;
133 provider.setConnectionProperties(driver, url, userid, password) ;
134 Connection conn = ConnectionFactory.getConnection(driver,
135 url, userid, password);
136 if (conn == null) {
137 throw new DBException("Null connection when connecting "
138 + "to database") ;
139 }
140
141 doc = export(conn) ;
142 conn.close() ;
143 conn = null ;
144 } catch (DBException e) {
145 throw e ;
146 } catch (Exception e) {
147 logger.error(e.getMessage()) ;
148 throw new DBException(e.getClass().getName() + ":"
149 + e.getMessage(), e) ;
150 }
151
152 return doc ;
153 }
154
155 /**
156 * Export the schema identified by the provided connection parameters.
157 */
158 public Document export(String dataSourceName)
159 throws DBException
160 {
161 logger.info("METHOD_ENTRY: export: dataSourceName=" + dataSourceName) ;
162 Document doc = null ;
163 try {
164 // Set the provider to avoid NPE in output
165 provider = new ProviderExt() ;
166 Connection conn = DataSourceProxy.getConnection(dataSourceName) ;
167 if (conn==null) {
168 throw new DBException("Null connection when connecting to database") ;
169 }
170
171 doc = export(conn) ;
172 conn.close() ;
173 conn = null ;
174
175 } catch (DBException e) {
176 throw e ;
177 } catch (Exception e) {
178 logger.error(e.getMessage(), e);
179 throw new DBException(e.getClass().getName() + ":" + e.getMessage()) ;
180 }
181
182 return doc ;
183 }
184
185 /**
186 * Export the schema at the database already connected to.
187 */
188 private Document export(Connection conn)
189 throws DBException {
190 Document doc = null ;
191 // Construct an xml doc
192 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
193 try {
194 DocumentBuilder docBuilder = factory.newDocumentBuilder();
195 doc = docBuilder.newDocument() ;
196 } catch (ParserConfigurationException e) {
197 logger.error(e.getMessage());
198 throw new DBException(e.getMessage()) ;
199 }
200
201 // get schema items to place in doc
202 try {
203 Element databaseTag = doc.createElement(SchemaConstants.ROOT_ELEMENT) ;
204 DatabaseMetaData dmd = conn.getMetaData() ;
205
206 /*
207 * General database provider information
208 */
209 Element providerTag = doc.createElement(SchemaConstants.PROVIDER) ;
210 Element productNameTag = doc.createElement(SchemaConstants.NAME) ;
211 productNameTag.appendChild(doc.createTextNode(dmd.getDatabaseProductName()));
212 providerTag.appendChild(productNameTag) ;
213
214 Element productVsnTag = doc.createElement(SchemaConstants.VSN) ;
215 productVsnTag.appendChild(doc.createTextNode(dmd.getDatabaseProductVersion())) ;
216 providerTag.appendChild(productVsnTag) ;
217
218 Element productUrlTag = doc.createElement(SchemaConstants.URL_STRING) ;
219 productUrlTag.appendChild(doc.createTextNode(dmd.getURL())) ;
220 providerTag.appendChild(productUrlTag) ;
221
222 Element usernameTag = doc.createElement(SchemaConstants.USERNAME) ;
223 usernameTag.appendChild(doc.createTextNode(dmd.getUserName())) ;
224 providerTag.appendChild(usernameTag) ;
225
226 Element passwordTag = doc.createElement(SchemaConstants.PASSWORD) ;
227 passwordTag.appendChild(doc.createTextNode(provider.getPassword())) ;
228 providerTag.appendChild(passwordTag) ;
229
230 // Database driver info
231 Element driverTag = doc.createElement(SchemaConstants.DRIVER) ;
232 Element driverNameTag = doc.createElement(SchemaConstants.NAME) ;
233 driverNameTag.appendChild(doc.createTextNode(dmd.getDriverName())) ;
234 driverTag.appendChild(driverNameTag) ;
235 Element driverVsnTag = doc.createElement(SchemaConstants.VSN) ;
236 driverVsnTag.appendChild(doc.createTextNode(dmd.getDriverVersion())) ;
237 driverTag.appendChild(driverVsnTag) ;
238 Element driverClassNameTag = doc.createElement(SchemaConstants.CLASS_NAME) ;
239 driverClassNameTag.appendChild(doc.createTextNode(
240 provider.getDriver()==null
241 ? ""
242 : provider.getDriver().getClassName())) ;
243 driverTag.appendChild(driverClassNameTag) ;
244 providerTag.appendChild(driverTag) ;
245
246 Element creationDateTag = doc.createElement(SchemaConstants.CREATION_DATE) ;
247 creationDateTag.appendChild(doc.createTextNode(formatter.format(new Date()))) ;
248 providerTag.appendChild(creationDateTag) ;
249
250 databaseTag.appendChild(providerTag);
251
252 /*
253 * Database metadata information (not sure if this is useful yet)
254 */
255 Element metadataTag = doc.createElement(SchemaConstants.METADATA) ;
256 Element catalogsTag = doc.createElement(SchemaConstants.CATALOGS) ;
257 ResultSet catalogs = dmd.getCatalogs() ;
258 while (catalogs.next()) {
259 //logger.debug("TABLE TYPE: " + tableTypes.getString("TABLE_TYPE"));
260 Element catalogNameTag = doc.createElement(SchemaConstants.NAME) ;
261 catalogNameTag.appendChild(doc.createTextNode(catalogs.getString("TABLE_CAT").trim()));
262 catalogsTag.appendChild(catalogNameTag);
263 }
264 catalogs.close() ;
265 metadataTag.appendChild(catalogsTag) ;
266
267 Element tableTypesTag = doc.createElement(SchemaConstants.TABLE_TYPES) ;
268 ResultSet tableTypes = dmd.getTableTypes() ;
269 while (tableTypes.next()) {
270 //logger.debug("TABLE TYPE: " + tableTypes.getString("TABLE_TYPE"));
271 Element tableTypeNameTag = doc.createElement(SchemaConstants.NAME) ;
272 tableTypeNameTag.appendChild(doc.createTextNode(tableTypes.getString("TABLE_TYPE").trim()));
273 tableTypesTag.appendChild(tableTypeNameTag);
274 }
275 metadataTag.appendChild(tableTypesTag) ;
276
277 Element catalogTermTag = doc.createElement(SchemaConstants.CATALOG_TERM) ;
278 catalogTermTag.appendChild(doc.createTextNode(dmd.getCatalogTerm()));
279 metadataTag.appendChild(catalogTermTag) ;
280
281 Element schemaTermTag = doc.createElement(SchemaConstants.SCHEMA_TERM) ;
282 schemaTermTag.appendChild(doc.createTextNode(dmd.getSchemaTerm()));
283 metadataTag.appendChild(schemaTermTag) ;
284
285 if (getDebug()) {
286 databaseTag.appendChild(metadataTag) ;
287 }
288
289 /*
290 * Get the schema data (including the table data)
291 */
292
293 ResultSet schemas = dmd.getSchemas() ;
294 ArrayList schList = (ArrayList)DBUtils.convertResultToList(schemas) ;
295
296 for (Iterator i=schList.iterator() ; i.hasNext() ;) {
297 Element schemaTag = doc.createElement(SchemaConstants.SCHEMA) ;
298 TreeMap row = (TreeMap)i.next() ;
299 String schemaName = (String)row.get("TABLE_SCHEM") ;
300 logger.debug("Found schema named: " + schemaName);
301
302 // If no target schema was specified, or if this is the one specified - export it
303 if (targetSchema==null || schemaName.equalsIgnoreCase(targetSchema)) {
304 logger.debug("Exporting schema named: " + schemaName);
305 Element schemaNameTag = doc.createElement(SchemaConstants.NAME) ;
306 schemaNameTag.appendChild(doc.createTextNode(schemaName));
307 schemaTag.appendChild(schemaNameTag) ;
308
309 if (this.tableTypes.length>0) {
310 addTables(dmd, doc, schemaName, schemaTag, this.tableTypes) ;
311 }
312 String[] viewType = new String[1] ;
313 viewType[0] = "VIEW" ; // TODO is this constant for all dbms?
314 viewExporter.setProvider(provider) ;
315 addTables(dmd, doc, schemaName, schemaTag, viewType) ;
316 databaseTag.appendChild(schemaTag) ;
317 } else {
318 logger.debug("Ignoring schema named: " + schemaName);
319 }
320 }
321 doc.appendChild(databaseTag);
322 } catch (Exception e) {
323 // Things to catch : array out of bounds from no column results found
324 logger.debug(e.getClass().getName() + ":" + e.getMessage()) ;
325 logger.debug(e) ;
326 //if (e.getMessage()==null || e.getMessage().length()==0) {
327 e.printStackTrace(System.err) ;
328 //}
329 }
330 return doc ;
331 }
332
333 /**
334 * Extract table metadata adding appropriate tags.
335 */
336 private void addTables(DatabaseMetaData dmd, Document doc, String schemaName,
337 Element schemaTag, String[] tableTypes)
338 throws SchemaHandlingException {
339 logger.info("METHOD_ENTRY: addTables");
340
341 try {
342
343 ResultSet tables = dmd.getTables(null, schemaName, getTablePattern(), tableTypes) ;
344 while (tables.next()) {
345 String tableName = tables.getString("TABLE_NAME") ;
346 String tableType = tables.getString("TABLE_TYPE") ;
347 /*
348 * The table portion
349 */
350 Element tableTag = null ;
351 if (SchemaConstants.VIEW.equalsIgnoreCase(tableType)) {
352 tableTag = doc.createElement(SchemaConstants.VIEW) ;
353 } else {
354 tableTag = doc.createElement(SchemaConstants.TABLE) ;
355 }
356 Element nameTag = doc.createElement(SchemaConstants.NAME) ;
357 nameTag.appendChild(doc.createTextNode(tableName));
358 tableTag.appendChild(nameTag) ;
359
360 Element typeTag = doc.createElement(SchemaConstants.TYPE) ;
361 typeTag.appendChild(doc.createTextNode(tableType));
362 tableTag.appendChild(typeTag) ;
363
364 // Capture Primary Key Name
365 ResultSet pk = dmd.getPrimaryKeys(catalog, schemaName, tableName) ;
366 ArrayList pkList = (ArrayList)DBUtils.convertResultToList(pk) ;
367 pk.close() ;
368 if (pkList.size()==0) {
369 logger.warn("No primary key was found for " + tableName) ;
370 //throw new DBException(msg) ;
371 } else {
372 TreeMap pkCol = (TreeMap)pkList.get(0);
373 logger.debug(pkList.toString()) ;
374 }
375
376 // All columns' data
377 ResultSet columns = dmd.getColumns(catalog, schemaName, tableName, null) ;
378 ArrayList colList = (ArrayList)DBUtils.convertResultToList(columns) ;
379 columns.close() ;
380 ResultSet pKeys = dmd.getExportedKeys(catalog, schemaName, tableName) ;
381 ArrayList pKeyList = new ArrayList() ;
382 while (pKeys.next()) {
383 pKeyList.add(pKeys.getString("PKCOLUMN_NAME")) ;
384 }
385 pKeys.close() ;
386 //pks.add(((TreeMap)colList.get(0)).get("COLUMN_NAME")) ;
387
388 // All foreign keys' data
389 ResultSet fKeys = dmd.getImportedKeys(catalog, schemaName, tableName) ;
390 ArrayList fKeyList = (ArrayList)DBUtils.convertResultToList(fKeys) ;
391 //logger.debug("FKs found=" + fKeyList);
392 fKeys.close() ;
393
394 // For each list element (represents a table column) ...
395 Element columnTag = null ;
396 for (Iterator i=colList.iterator() ; i.hasNext() ;) {
397 TreeMap tableCol = (TreeMap)i.next() ;
398 // ... for each column construct column element
399 columnTag = doc.createElement(COLUMN) ;
400
401 // get column name & description
402 String colName = (String)tableCol.get("COLUMN_NAME") ;
403 Element colDescTag = doc.createElement(SchemaConstants.DESCRIPTION) ;
404 colDescTag.appendChild(doc.createTextNode((String)tableCol.get("REMARKS"))) ;
405 Element columnNameTag = doc.createElement(SchemaConstants.COL_NAME) ;
406 columnNameTag.appendChild(doc.createTextNode(colName));
407 columnTag.appendChild(colDescTag) ;
408 columnTag.appendChild(columnNameTag) ;
409
410 // get column datatype
411 // defined as short in JDBC doco, Oracle returns BigDecimal, Sybase an Integer
412 Number typeObj = (Number)tableCol.get("DATA_TYPE") ;
413 int type = (typeObj==null ? Integer.MIN_VALUE : typeObj.intValue());
414 Number scaleObj = (Number)tableCol.get("COLUMN_SIZE") ;
415 int scale = (scaleObj==null ? Integer.MIN_VALUE : scaleObj.intValue());
416 Number precisionObj = (Number)tableCol.get("DECIMAL_DIGITS") ;
417 int precision = (precisionObj==null ? Integer.MIN_VALUE : precisionObj.intValue());
418 String colType = new SqlType(type, scale, precision).toString() ;
419 Element columnTypeTag = doc.createElement(COL_TYPE) ;
420 columnTypeTag.appendChild(doc.createTextNode(colType)) ;
421 columnTag.appendChild(columnTypeTag) ;
422
423 // get column null / not null
424 // assume the worst (includes don't know case)
425 boolean isNullable = false ;
426 logger.debug("Nullable: " + tableCol.get("IS_NULLABLE").toString()) ;
427 if (((String)tableCol.get("IS_NULLABLE")).equals("YES")) {
428 isNullable = true ;
429 }
430 Element nullableTag = doc.createElement(NULLABLE) ;
431 nullableTag.appendChild(doc.createTextNode(String.valueOf(isNullable))) ;
432 columnTag.appendChild(nullableTag) ;
433
434 // determine if column is primary key
435 if (pKeyList.contains(colName)) {
436 Element pkTag = doc.createElement(SchemaConstants.PK) ;
437 pkTag.appendChild(doc.createTextNode("true")) ;
438 columnTag.appendChild(pkTag) ;
439 }
440
441 // determine if column is a foreign key
442 for (Iterator j=fKeyList.iterator() ; j.hasNext() ;) {
443 TreeMap key = (TreeMap)j.next() ;
444 String fKeyName = (String)key.get("FKCOLUMN_NAME") ;
445 if (fKeyName!=null && fKeyName.equals(colName)) {
446 logger.debug("Found foreign key for column: " + fKeyName);
447 Element fkTag = doc.createElement(FK) ;
448 Element fkTableTag = doc.createElement(FK_TABLE) ;
449 fkTableTag.appendChild(doc.createTextNode(
450 (String)key.get("PKTABLE_NAME"))) ;
451 fkTag.appendChild(fkTableTag) ;
452
453 // foreign key data col (the actual foreign key)
454 Element fkDataColTag = doc.createElement(FK_DATA_COLUMN) ;
455 String pkName = (String)key.get("PKCOLUMN_NAME") ;
456 Element fkDataColDescTag = doc.createElement(SchemaConstants.DESCRIPTION) ;
457 fkDataColDescTag.appendChild(doc.createTextNode((String)key.get("REMARKS"))) ;
458 fkDataColTag.appendChild(fkDataColDescTag) ;
459 Element fkDataColNameTag = doc.createElement(SchemaConstants.FK_DATA_COL_NAME) ;
460 fkDataColNameTag.appendChild(doc.createTextNode(pkName)) ;
461
462 // fk display column
463 Element fkDisplayColTag = doc.createElement(FK_DISPLAY_COLUMN) ;
464 Element fkDisplayColNameTag = doc.createElement(SchemaConstants.FK_DISPLAY_COL_NAME) ;
465 fkDisplayColNameTag.appendChild(doc.createTextNode(pkName)) ;
466 fkDataColTag.appendChild(fkDataColNameTag) ;
467 Element fkDisplayColDescTag = doc.createElement(SchemaConstants.DESCRIPTION) ;
468 fkDisplayColDescTag.appendChild(doc.createTextNode((String)key.get("REMARKS"))) ;
469 fkDisplayColTag.appendChild(fkDisplayColDescTag) ;
470 fkDisplayColTag.appendChild(fkDisplayColNameTag) ;
471 fkTag.appendChild(fkDataColTag) ;
472 fkTag.appendChild(fkDisplayColTag) ;
473
474 columnTag.appendChild(fkTag) ;
475 }
476 }
477
478 tableTag.appendChild(columnTag) ;
479 }
480
481 if (SchemaConstants.VIEW.equalsIgnoreCase(tableType)) {
482 // For views find, their definition
483 Element definitionTag = doc.createElement(SchemaConstants.DEFINITION) ;
484 String definition = viewExporter.export(dmd.getConnection(), tableName) ;
485 logger.debug("definition=" + definition);
486 definitionTag.appendChild(doc.createTextNode(definition)) ;
487 tableTag.appendChild(definitionTag) ;
488 } else {
489
490 // Get Index info - 1st null indicates drop catalog from criteria
491 ResultSet indexes = dmd.getIndexInfo(null, schemaName,
492 tableName, uniqueIndexOnly, approxIndexStats) ;
493 int indexCount = 0 ;
494 String lastIndexName = null ;
495 Element indexTag = null ;
496 while (indexes.next()) {
497
498 switch (indexes.getInt("TYPE")) {
499 case DatabaseMetaData.tableIndexStatistic :
500 // do nothing
501 break ;
502 default :
503 String indexName = indexes.getString("INDEX_NAME") ;
504 if (lastIndexName==null || !indexName.equals(lastIndexName)) {
505 // Create new index
506 if (indexTag!=null && lastIndexName!=null) {
507 tableTag.appendChild(indexTag) ;
508 }
509 indexCount++ ;
510 indexTag = doc.createElement(SchemaConstants.INDEX) ;
511
512 Element indexNameTag = doc.createElement(SchemaConstants.NAME) ;
513 indexNameTag.appendChild(
514 doc.createTextNode(String.valueOf(indexName))) ;
515 indexTag.appendChild(indexNameTag) ;
516
517 Element indexTypeTag = doc.createElement(SchemaConstants.TYPE) ;
518 indexTypeTag.appendChild(
519 doc.createTextNode(String.valueOf(indexes.getInt("TYPE")))) ;
520 indexTag.appendChild(indexTypeTag) ;
521
522 Element indexUniqueTag = doc.createElement(SchemaConstants.INDEX_UNIQUE) ;
523 // This is horrible - the jdk1.3.1 javadoc says the column should be called 'NON-UNIQUE'
524 String unique = "UNKNOWN" ;
525 if (provider!=null && provider.getDriver() != null
526 && provider.getDriver().getName() != null) {
527 if (provider.getDriver().getName().indexOf("sybase")>0) {
528 unique = (indexes.getBoolean("TABLE_NAME") ? "UNIQUE" : "NON-UNIQUE") ;
529 } else if (provider.getDriver().getName().indexOf("microsoft")>0) {
530 // ??
531 } else if (provider.getDriver().getName().indexOf("oracle")>0) {
532 unique = (indexes.getBoolean("TABLE_NAME") ? "UNIQUE" : "NON-UNIQUE") ;
533 }
534 }
535 indexUniqueTag.appendChild(doc.createTextNode(unique)) ;
536 indexTag.appendChild(indexUniqueTag) ;
537 }
538
539 // Add index column details
540 Element colNameTag = doc.createElement(SchemaConstants.COL_NAME) ;
541 colNameTag.appendChild(
542 doc.createTextNode(indexes.getString("COLUMN_NAME"))) ;
543 indexTag.appendChild(colNameTag) ;
544
545 lastIndexName = indexName ;
546 }
547 }
548
549 if (indexTag!=null) {
550 tableTag.appendChild(indexTag) ;
551 }
552 indexCount++ ;
553
554 logger.warn("Index count for table " + tableName + "=" + indexCount);
555 indexes.close() ;
556
557
558 }
559
560 schemaTag.appendChild(tableTag);
561 } // end while have tables
562 } catch (Exception e) {
563 logger.error("Error whilst trying to process schema named: " + schemaName) ;
564 e.printStackTrace() ;
565 throw new SchemaHandlingException(e.getMessage()) ;
566 }
567 logger.info("METHOD_EXIT: addTables");
568 }
569
570 /*
571 * Methods
572 */
573 /**
574 *
575 *
576 * @param args
577 * args[0] - tableName to turn into XML representation
578 */
579 public static void main(String[] args)
580 {
581 try {
582 SchemaExporter transformer = new SchemaExporter() ;
583 transformer.export(args[0], args[1], args[2], args[3]) ;
584
585 } catch (Exception e) {
586 System.out.println("Failed: " + e.getMessage()) ;
587 }
588 }
589
590 /**
591 * Returns the directory name classes should be stored in based on the
592 * Java package name received
593 */
594 private String getPackageDir(String javaPackage)
595 {
596 StringBuffer dir = new StringBuffer() ;
597 StringTokenizer st = new StringTokenizer(javaPackage, ".");
598 while (st.hasMoreTokens()) {
599 dir.append(st.nextToken()) ;
600 dir.append("/") ;
601 }
602
603 // remove final '/' and return
604 return dir.substring(0, dir.length()-1) ;
605 }
606
607 /*
608 * Properties
609 */
610 private String catalog ;
611 private String targetDir ;
612 private String targetSchema ;
613 private String[] tableTypes ;
614
615 private boolean uniqueIndexOnly = false ;
616 private boolean approxIndexStats = false ;
617
618 private ProviderExt provider ;
619 private ViewExporter viewExporter = new ViewExporter() ;
620 private SimpleDateFormat formatter ;
621
622 /*
623 * Constant Properties
624 */
625
626
627
628 /*
629 * Application specifics
630 *//*
631 public static final String JAVA_PACKAGE_DIR = "package-dir" ;
632 public static final String JAVA_PACKAGE_SchemaConstants.NAME = "package-name" ;
633 public static final String JAVA_PACKAGE_VALUE = "org.thestephensons.webservices" ;
634 */
635 /*
636 * Document Tags
637 */
638 //public static final String APP = "app" ;
639 //public static final String JAVA = "java" ;
640 public static final String SCHEMAS = "schemas" ;
641 public static final String COLUMN = "column" ;
642 public static final String COL_NAME = "col-name" ;
643 public static final String COL_TYPE = "col-type" ;
644 public static final String NULLABLE = "null" ;
645 public static final String PK = "primary-key" ;
646 public static final String FK = "foreign-key" ;
647 public static final String FK_TABLE = "fk-table-name" ;
648 public static final String FK_DATA_COLUMN = "data-column" ;
649 public static final String FK_DATA_COL_NAME = "col-name" ;
650 public static final String FK_DISPLAY_COLUMN = "display-column" ;
651 public static final String FK_DISPLAY_COL_NAME = "col-name" ;
652
653 /**
654 * Define a static Category instance for logging.
655 */
656 private static Category logger = Category.getInstance(SchemaExporter.class);
657
658 }
659