Source Code Cross Referenced for MetaData.java in  » Web-Framework » jWebApp » jpersist » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » jWebApp » jpersist 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * Copyright (C) 2006, 2007 David Bulmore, Software Sensation Inc.  
0003:         * All Rights Reserved.
0004:         *
0005:         * This file is part of JPersist.
0006:         *
0007:         * JPersist is free software; you can redistribute it and/or modify it under 
0008:         * the terms of the GNU General Public License (Version 2) as published by 
0009:         * the Free Software Foundation.
0010:         *
0011:         * JPersist is distributed in the hope that it will be useful, but WITHOUT 
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
0013:         * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
0014:         * for more details.
0015:         *
0016:         * You should have received a copy of the GNU General Public License 
0017:         * along with JPersist; if not, write to the Free Software Foundation, 
0018:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0019:         */package jpersist;
0020:
0021:        import java.sql.Connection;
0022:        import java.sql.DatabaseMetaData;
0023:        import java.sql.ResultSet;
0024:        import java.sql.ResultSetMetaData;
0025:        import java.sql.SQLException;
0026:        import java.sql.Savepoint;
0027:        import java.sql.Statement;
0028:        import java.util.HashMap;
0029:        import java.util.Iterator;
0030:        import java.util.Map;
0031:        import jcommontk.utils.StringUtils;
0032:        import java.util.HashSet;
0033:        import java.util.Set;
0034:        import java.util.logging.Level;
0035:        import java.util.logging.Logger;
0036:        import jcommontk.inflector.SimpleInflector;
0037:        import jpersist.interfaces.ColumnMapping;
0038:        import jpersist.interfaces.TableMapping;
0039:
0040:        /**
0041:         * This class provides database level metadata.
0042:         */
0043:
0044:        @SuppressWarnings("unchecked")
0045:        // working to complete a Java 1.5 version
0046:        public final class MetaData {
0047:            public static final int STORES_UNKNOWN = 0;
0048:            public static final int STORES_UPPERCASE = 1;
0049:            public static final int STORES_LOWERCASE = 2;
0050:            public static final int STORES_MIXEDCASE = 3;
0051:
0052:            private static Logger logger = Logger.getLogger(MetaData.class
0053:                    .getName());
0054:            private static Map metaDataMap = new HashMap();
0055:
0056:            private String tableTypes[] = new String[] { "TABLE", "VIEW" },
0057:                    identifierQuoteString = "", searchStringEscape = "",
0058:                    databaseUrl;
0059:            private Map tables = new HashMap(), tableCache = new HashMap(),
0060:                    tableNameMapping = new HashMap();
0061:            private Set stripTablePrefixes, stripTableSuffixes,
0062:                    stripColumnPrefixes, stripColumnSuffixes;
0063:            private boolean supportsGeneratedKeys, supportsSavepoints,
0064:                    strictClassTableMatching = false,
0065:                    strictMethodColumnMatching = true;
0066:            private int storesCase = 0;
0067:
0068:            static MetaData getMetaData(Connection connection)
0069:                    throws SQLException, JPersistException {
0070:                String databaseUrl = connection.getMetaData().getURL();
0071:                MetaData metaData = (MetaData) metaDataMap.get(databaseUrl);
0072:
0073:                if (metaData != null)
0074:                    return metaData;
0075:
0076:                return loadMetaData(connection);
0077:            }
0078:
0079:            static synchronized MetaData loadMetaData(Connection connection)
0080:                    throws SQLException, JPersistException {
0081:                String databaseUrl = connection.getMetaData().getURL();
0082:                MetaData metaData = (MetaData) metaDataMap.get(databaseUrl);
0083:
0084:                if (metaData == null) {
0085:                    metaData = new MetaData();
0086:                    metaDataMap.put(databaseUrl, metaData);
0087:                    DatabaseMetaData dbMetaData = connection.getMetaData();
0088:
0089:                    try {
0090:                        logger.finer("database product name = "
0091:                                + dbMetaData.getDatabaseProductName());
0092:                        logger.finer("database product version = "
0093:                                + dbMetaData.getDatabaseProductVersion());
0094:                        logger.finer("database version = "
0095:                                + dbMetaData.getDatabaseMajorVersion() + "."
0096:                                + dbMetaData.getDatabaseMinorVersion());
0097:                        logger.finer("JDBC driver version = "
0098:                                + dbMetaData.getDriverMajorVersion() + "."
0099:                                + +dbMetaData.getDriverMinorVersion());
0100:                        logger.finer("user name = " + dbMetaData.getUserName());
0101:                        logger.finer("supports transactions = "
0102:                                + dbMetaData.supportsTransactions());
0103:                        logger.finer("supports multiple transactions = "
0104:                                + dbMetaData.supportsMultipleTransactions());
0105:                        logger
0106:                                .finer("supports transaction isolation level TRANSACTION_READ_COMMITTED = "
0107:                                        + dbMetaData
0108:                                                .supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));
0109:                        logger
0110:                                .finer("supports transaction isolation level TRANSACTION_READ_UNCOMMITTED = "
0111:                                        + dbMetaData
0112:                                                .supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
0113:                        logger
0114:                                .finer("supports transaction isolation level TRANSACTION_REPEATABLE_READ = "
0115:                                        + dbMetaData
0116:                                                .supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ));
0117:                        logger
0118:                                .finer("supports transaction isolation level TRANSACTION_SERIALIZABLE = "
0119:                                        + dbMetaData
0120:                                                .supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));
0121:                        logger
0122:                                .finer("supports result set TYPE_FORWARD_ONLY = "
0123:                                        + dbMetaData
0124:                                                .supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY));
0125:                        logger
0126:                                .finer("supports result set TYPE_SCROLL_INSENSITIVE = "
0127:                                        + dbMetaData
0128:                                                .supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE));
0129:                        logger
0130:                                .finer("supports result set TYPE_SCROLL_SENSITIVE = "
0131:                                        + dbMetaData
0132:                                                .supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE));
0133:                        logger
0134:                                .finer("supports result set holdability CLOSE_CURSORS_AT_COMMIT = "
0135:                                        + dbMetaData
0136:                                                .supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT));
0137:                        logger
0138:                                .finer("supports result set holdability HOLD_CURSORS_OVER_COMMIT = "
0139:                                        + dbMetaData
0140:                                                .supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
0141:                        logger.finer("stores lower case identifiers = "
0142:                                + dbMetaData.storesLowerCaseIdentifiers());
0143:                        logger
0144:                                .finer("stores lower case quoted identifiers = "
0145:                                        + dbMetaData
0146:                                                .storesLowerCaseQuotedIdentifiers());
0147:                        logger.finer("stores upper case identifiers = "
0148:                                + dbMetaData.storesUpperCaseIdentifiers());
0149:                        logger
0150:                                .finer("stores upper case quoted identifiers = "
0151:                                        + dbMetaData
0152:                                                .storesUpperCaseQuotedIdentifiers());
0153:                        logger.finer("stores mixed case identifiers = "
0154:                                + dbMetaData.storesMixedCaseIdentifiers());
0155:                        logger
0156:                                .finer("stores mixed case quoted identifiers = "
0157:                                        + dbMetaData
0158:                                                .storesMixedCaseQuotedIdentifiers());
0159:                    } catch (Exception e) {
0160:                        logger.log(Level.WARNING, e.getMessage(), e);
0161:                    }
0162:
0163:                    logger.finer("Catalog term = "
0164:                            + dbMetaData.getCatalogTerm());
0165:                    logger.finer("Schema term = " + dbMetaData.getSchemaTerm());
0166:
0167:                    try {
0168:                        if (dbMetaData.supportsSavepoints()) {
0169:                            Savepoint savepoint = connection.setSavepoint();
0170:                            connection.releaseSavepoint(savepoint);
0171:                        }
0172:
0173:                        metaData.supportsSavepoints = dbMetaData
0174:                                .supportsSavepoints();
0175:                    } catch (Exception e) {
0176:                        logger
0177:                                .log(
0178:                                        Level.FINE,
0179:                                        "The database metadata reports it supports savepoints, but the database fails with setSavepoint().  Therefore, the database probably does not support savepoints",
0180:                                        e);
0181:                    }
0182:
0183:                    logger.finer("supports savepoints = "
0184:                            + metaData.supportsSavepoints);
0185:
0186:                    if (dbMetaData.storesLowerCaseIdentifiers()
0187:                            || dbMetaData.storesLowerCaseQuotedIdentifiers())
0188:                        metaData.storesCase = STORES_LOWERCASE;
0189:                    else if (dbMetaData.storesUpperCaseIdentifiers()
0190:                            || dbMetaData.storesUpperCaseQuotedIdentifiers())
0191:                        metaData.storesCase = STORES_UPPERCASE;
0192:                    else if (dbMetaData.storesMixedCaseIdentifiers()
0193:                            || dbMetaData.storesMixedCaseQuotedIdentifiers())
0194:                        metaData.storesCase = STORES_MIXEDCASE;
0195:
0196:                    logger.finer("maximum concurrent connections = "
0197:                            + dbMetaData.getMaxConnections());
0198:
0199:                    metaData.identifierQuoteString = dbMetaData
0200:                            .getIdentifierQuoteString();
0201:
0202:                    if (metaData.identifierQuoteString.equals(" "))
0203:                        metaData.identifierQuoteString = "";
0204:
0205:                    logger.finer("identifier quote string = '"
0206:                            + metaData.identifierQuoteString + "'");
0207:                    logger.finer("supports generated keys = "
0208:                            + (metaData.supportsGeneratedKeys = dbMetaData
0209:                                    .supportsGetGeneratedKeys()));
0210:                    logger.finer("search string escape = "
0211:                            + (metaData.searchStringEscape = dbMetaData
0212:                                    .getSearchStringEscape()));
0213:                    logger.finer("database url = "
0214:                            + (metaData.databaseUrl = databaseUrl));
0215:                }
0216:
0217:                return metaData;
0218:            }
0219:
0220:            public String getIdentifierQuoteString() {
0221:                return identifierQuoteString;
0222:            }
0223:
0224:            public String getSearchStringEscape() {
0225:                return searchStringEscape;
0226:            }
0227:
0228:            public String getDatabaseUrl() {
0229:                return databaseUrl;
0230:            }
0231:
0232:            public int getStoresCase() {
0233:                return storesCase;
0234:            }
0235:
0236:            public boolean supportsGeneratedKeys() {
0237:                return supportsGeneratedKeys;
0238:            }
0239:
0240:            public boolean supportsSavepoints() {
0241:                return supportsSavepoints;
0242:            }
0243:
0244:            public void setTableTypes(String[] tableTypes) {
0245:                this .tableTypes = tableTypes;
0246:            }
0247:
0248:            public void setStrictMethodColumnMatching(boolean trueFalse) {
0249:                strictMethodColumnMatching = trueFalse;
0250:            }
0251:
0252:            public void setStrictClassTableMatching(boolean trueFalse) {
0253:                strictClassTableMatching = trueFalse;
0254:            }
0255:
0256:            /**
0257:             * Set of prefixes to be stripped from table names to help in class to table name matching.
0258:             * @param stripTablePrefixes a set of prefixes (Strings)
0259:             */
0260:            public void setTablePrefixesToStrip(Set stripTablePrefixes) {
0261:                this .stripTablePrefixes = stripTablePrefixes;
0262:            }
0263:
0264:            /**
0265:             * Set of suffixes to be stripped from table names to help in class to table name matching.
0266:             * @param stripTableSuffixes a set of suffixes (Strings)
0267:             */
0268:            public void setTableSuffixesToStrip(Set stripTableSuffixes) {
0269:                this .stripTableSuffixes = stripTableSuffixes;
0270:            }
0271:
0272:            /**
0273:             * Set of prefixes to be stripped from column names to help in method to column name matching.
0274:             * @param stripColumnPrefixes a set of prefixes (Strings)
0275:             */
0276:            public void setColumnPrefixesToStrip(Set stripColumnPrefixes) {
0277:                this .stripColumnPrefixes = stripColumnPrefixes;
0278:            }
0279:
0280:            /**
0281:             * Set of suffixes to be stripped from column names to help in method to column name matching.
0282:             * @param stripColumnSuffixes a set of suffixes (Strings)
0283:             */
0284:            public void setColumnSuffixesToStrip(Set stripColumnSuffixes) {
0285:                this .stripColumnSuffixes = stripColumnSuffixes;
0286:            }
0287:
0288:            /*
0289:             * Remove table from the MetaData cache.  A non-harmful method.  If called 
0290:             * by accident and the table is still needed, it will simply be reloaded.
0291:             *
0292:             * @param tableName name of the table to remove
0293:            public void removeTableFromCache(String tableName) { tableCache.remove(normalizeName(tableName)); }
0294:             */
0295:
0296:            /**
0297:             * Add a table mapping.
0298:             *
0299:             * @param searchTableName the name that should be matched
0300:             * @param returnTableName the actual table name in the database
0301:             */
0302:            public synchronized void addTableNameMapping(
0303:                    String searchTableName, String returnTableName) {
0304:                tableNameMapping.put(normalizeName(searchTableName),
0305:                        returnTableName);
0306:            }
0307:
0308:            public Table getTable(Connection connection,
0309:                    TableMapping tableMapper, ColumnMapping columnMapper,
0310:                    String catalogPattern, String schemaPattern,
0311:                    String tableName, Object object) throws SQLException,
0312:                    JPersistException {
0313:                String searchName = normalizeName((catalogPattern != null ? catalogPattern
0314:                        + "."
0315:                        : "")
0316:                        + (schemaPattern != null ? schemaPattern + "." : "")
0317:                        + tableName);
0318:                Table table = (Table) tableCache.get(searchName);
0319:
0320:                // table already loaded
0321:                if (table != null) {
0322:                    if (table instanceof  NullTable)
0323:                        return null;
0324:                } else
0325:                    table = tableSearch(connection, tableMapper,
0326:                            catalogPattern, schemaPattern, tableName, object);
0327:
0328:                if (table != null && !table.isTableDetailLoaded())
0329:                    loadTableDetail(connection, columnMapper, table);
0330:
0331:                return table;
0332:            }
0333:
0334:            /* load all possiblities and scan for an exact match, or a single match */
0335:            synchronized Table tableSearch(Connection connection,
0336:                    TableMapping tableMapper, String catalogPattern,
0337:                    String schemaPattern, String tableName, Object object)
0338:                    throws SQLException, JPersistException {
0339:                String searchName = normalizeName((catalogPattern != null ? catalogPattern
0340:                        + "."
0341:                        : "")
0342:                        + (schemaPattern != null ? schemaPattern + "." : "")
0343:                        + tableName);
0344:                Table table = (Table) tableCache.get(searchName);
0345:
0346:                // table already loaded
0347:                if (table != null) {
0348:                    if (table instanceof  NullTable)
0349:                        return null;
0350:
0351:                    return table;
0352:                }
0353:
0354:                String name = null, catalog = null, schema = null;
0355:
0356:                if (logger.isLoggable(Level.FINER))
0357:                    logger.finer("Searching for table " + tableName);
0358:
0359:                if (catalogPattern != null)
0360:                    catalog = storesCase == 0 || storesCase == STORES_UPPERCASE ? catalogPattern
0361:                            .toUpperCase()
0362:                            : catalogPattern.toLowerCase();
0363:
0364:                if (schemaPattern != null)
0365:                    schema = storesCase == 0 || storesCase == STORES_UPPERCASE ? schemaPattern
0366:                            .toUpperCase()
0367:                            : schemaPattern.toLowerCase();
0368:
0369:                // search and load TabbleMapping defined
0370:                if (object != null
0371:                        && object instanceof  TableMapping
0372:                        && (name = ((TableMapping) object)
0373:                                .getDatabaseTableName(tableName.toLowerCase())) != null) {
0374:                    name = storesCase == 0 || storesCase == STORES_UPPERCASE ? name
0375:                            .toUpperCase()
0376:                            : name.toLowerCase();
0377:
0378:                    loadTables(connection, catalog, schema, name);
0379:                    table = tableScan(catalog, schema, name, true);
0380:                }
0381:
0382:                // search and load global TabbleMapping defined
0383:                if (table == null
0384:                        && tableMapper != null
0385:                        && (name = tableMapper.getDatabaseTableName(tableName
0386:                                .toLowerCase())) != null) {
0387:                    name = storesCase == 0 || storesCase == STORES_UPPERCASE ? name
0388:                            .toUpperCase()
0389:                            : name.toLowerCase();
0390:
0391:                    loadTables(connection, catalog, schema, name);
0392:                    table = tableScan(catalog, schema, name, true);
0393:                }
0394:
0395:                // search and load table hints
0396:                if (table == null
0397:                        && (name = (String) tableNameMapping
0398:                                .get(normalizeName(tableName))) != null) {
0399:                    loadTables(connection, catalog, schema, name);
0400:                    table = tableScan(catalog, schema, name, true);
0401:                }
0402:
0403:                // search and load for tableName
0404:                if (table == null) {
0405:                    loadTables(connection, catalogPattern, schemaPattern,
0406:                            name = tableName);
0407:                    table = tableScan(catalog, schema, name, true);
0408:                }
0409:
0410:                // search and load plurals
0411:                if (table == null) {
0412:                    String[] plurals = SimpleInflector.pluralize(tableName);
0413:
0414:                    for (int i = 0; table == null && i < plurals.length; i++) {
0415:                        loadTables(connection, catalog, schema,
0416:                                name = plurals[i]);
0417:                        table = tableScan(catalog, schema, name, true);
0418:                    }
0419:                }
0420:
0421:                // search and load for TABLENAME
0422:                if (table == null) {
0423:                    name = storesCase == 0 || storesCase == STORES_UPPERCASE ? tableName
0424:                            .toUpperCase()
0425:                            : tableName.toLowerCase();
0426:                    loadTables(connection, catalog, schema, name);
0427:                    table = tableScan(catalog, schema, name, true);
0428:                }
0429:
0430:                // search and load for TABLE_NAME
0431:                if (table == null) {
0432:                    name = storesCase == 0 || storesCase == STORES_UPPERCASE ? StringUtils
0433:                            .camelCaseToUpperCaseUnderline(tableName)
0434:                            : StringUtils
0435:                                    .camelCaseToLowerCaseUnderline(tableName);
0436:                    loadTables(connection, catalog, schema, name);
0437:                    table = tableScan(catalog, schema, name, true);
0438:                }
0439:
0440:                // search and load for opposite of TABLE_NAME
0441:                if (table == null) {
0442:                    if (catalogPattern != null)
0443:                        catalog = storesCase == 0
0444:                                || storesCase == STORES_UPPERCASE ? catalogPattern
0445:                                .toLowerCase()
0446:                                : catalogPattern.toUpperCase();
0447:
0448:                    if (schemaPattern != null)
0449:                        schema = storesCase == 0
0450:                                || storesCase == STORES_UPPERCASE ? schemaPattern
0451:                                .toLowerCase()
0452:                                : schemaPattern.toUpperCase();
0453:
0454:                    // search and load for tablename
0455:                    name = storesCase == 0 || storesCase == STORES_UPPERCASE ? tableName
0456:                            .toLowerCase()
0457:                            : tableName.toUpperCase();
0458:                    loadTables(connection, catalog, schema, name);
0459:                    table = tableScan(catalog, schema, name, true);
0460:
0461:                    // search and load for table_name
0462:                    if (table == null) {
0463:                        name = storesCase == 0
0464:                                || storesCase == STORES_UPPERCASE ? StringUtils
0465:                                .camelCaseToLowerCaseUnderline(tableName)
0466:                                : StringUtils
0467:                                        .camelCaseToUpperCaseUnderline(tableName);
0468:                        loadTables(connection, catalog, schema, name);
0469:                        table = tableScan(catalog, schema, name, true);
0470:                    }
0471:                }
0472:
0473:                if (table == null && !strictClassTableMatching)
0474:                    table = tableScan(catalog, schema, name, false);
0475:
0476:                if (table != null)
0477:                    tableCache.put(searchName, table);
0478:                else {
0479:                    tableCache.put(searchName, new NullTable());
0480:
0481:                    if (logger.isLoggable(Level.FINER))
0482:                        logger.finer("Table " + tableName + " not found!");
0483:                }
0484:
0485:                return table;
0486:            }
0487:
0488:            int loadTables(Connection connection, String catalogPattern,
0489:                    String schemaPattern, String tablePattern)
0490:                    throws SQLException, JPersistException {
0491:                DatabaseMetaData metaData = connection.getMetaData();
0492:                ResultSet resultSet = metaData.getTables(catalogPattern,
0493:                        schemaPattern, "%" + tablePattern + "%", tableTypes);
0494:                int tableCount = 0;
0495:
0496:                while (resultSet.next()) {
0497:                    Table table = new Table(resultSet.getString("table_name"),
0498:                            resultSet.getString("table_cat"), resultSet
0499:                                    .getString("table_schem"), resultSet
0500:                                    .getString("table_type"));
0501:
0502:                    String searchName = normalizeName((table.getCatalogName() != null ? table
0503:                            .getCatalogName()
0504:                            + "."
0505:                            : "")
0506:                            + (table.getSchemaName() != null ? table
0507:                                    .getSchemaName()
0508:                                    + "." : "") + table.getTableName());
0509:
0510:                    tables.put(searchName, table);
0511:
0512:                    if (logger.isLoggable(Level.FINE))
0513:                        logger.finer("Found table: " + table);
0514:
0515:                    tableCount++;
0516:                }
0517:
0518:                resultSet.close();
0519:
0520:                return tableCount;
0521:            }
0522:
0523:            Table tableScan(String catalogName, String schemaName,
0524:                    String tableName, boolean strictMatch)
0525:                    throws JPersistException {
0526:                String searchName = normalizeName((catalogName != null ? catalogName
0527:                        + "."
0528:                        : "")
0529:                        + (schemaName != null ? schemaName + "." : "")
0530:                        + tableName);
0531:                Table table = (Table) tables.get(searchName);
0532:
0533:                if (table != null)
0534:                    return table;
0535:
0536:                tableName = normalizeName(tableName);
0537:
0538:                catalogName = catalogName != null ? catalogName.toLowerCase()
0539:                        : "";
0540:                schemaName = schemaName != null ? schemaName.toLowerCase() : "";
0541:
0542:                Iterator it = tables.entrySet().iterator();
0543:
0544:                while (it.hasNext()) {
0545:                    Table itTable = (Table) ((Map.Entry) it.next()).getValue();
0546:                    String matchName1 = normalizeName(itTable.getTableName()), matchName2 = null, itTableCatalog = itTable
0547:                            .getCatalogName() != null ? itTable
0548:                            .getCatalogName().toLowerCase() : "", itTableSchema = itTable
0549:                            .getSchemaName() != null ? itTable.getSchemaName()
0550:                            .toLowerCase() : "";
0551:
0552:                    if (stripTablePrefixes != null
0553:                            || stripTableSuffixes != null)
0554:                        matchName2 = normalizeName(stripName(itTable
0555:                                .getTableName(), stripTablePrefixes,
0556:                                stripTableSuffixes));
0557:
0558:                    if ((tableName.equals(matchName1) || (matchName2 != null && tableName
0559:                            .equals(matchName2)))
0560:                            && (catalogName.length() == 0 || catalogName
0561:                                    .equals(itTableCatalog))
0562:                            && (schemaName.length() == 0 || schemaName
0563:                                    .equals(itTableSchema))) {
0564:                        if (table == null)
0565:                            table = itTable;
0566:                        else
0567:                            throw new JPersistException(
0568:                                    "Scanning produces multiple possible tables for table name '"
0569:                                            + tableName
0570:                                            + "'\n"
0571:                                            + "To obtain an exact match you can further qualify the naming, or add catalog/schema qualifiers,\n or define prefix/suffix stripping, or table name mapping.");
0572:                    }
0573:                }
0574:
0575:                if (!strictMatch && table == null) {
0576:                    it = tables.entrySet().iterator();
0577:
0578:                    while (it.hasNext()) {
0579:                        Table itTable = (Table) ((Map.Entry) it.next())
0580:                                .getValue();
0581:                        String matchName1 = normalizeName(itTable
0582:                                .getTableName()), itTableCatalog = itTable
0583:                                .getCatalogName() != null ? itTable
0584:                                .getCatalogName().toLowerCase() : "", itTableSchema = itTable
0585:                                .getSchemaName() != null ? itTable
0586:                                .getSchemaName().toLowerCase() : "";
0587:
0588:                        if (matchName1.indexOf(tableName) != -1
0589:                                && (catalogName.length() == 0 || catalogName
0590:                                        .equals(itTableCatalog))
0591:                                && (schemaName.length() == 0 || schemaName
0592:                                        .equals(itTableSchema))) {
0593:                            if (table == null || matchName1.equals(tableName))
0594:                                table = itTable;
0595:                            else
0596:                                throw new JPersistException(
0597:                                        "Scanning produces multiple possible tables for table name '"
0598:                                                + tableName
0599:                                                + "'\n"
0600:                                                + "To obtain an exact match you can further qualify the naming, or add catalog/schema qualifiers,\n or define prefix/suffix stripping, or table name mapping.");
0601:                        }
0602:                    }
0603:                }
0604:
0605:                return table;
0606:            }
0607:
0608:            void loadTableDetail(Connection connection,
0609:                    ColumnMapping columnMapper, Table table)
0610:                    throws SQLException, JPersistException {
0611:                Statement statement = connection.createStatement();
0612:                DatabaseMetaData metaData = connection.getMetaData();
0613:                ResultSet resultSet = metaData.getPrimaryKeys(table
0614:                        .getCatalogName(), table.getSchemaName(), table
0615:                        .getTableName());
0616:
0617:                Map primaryKeys = new HashMap();
0618:
0619:                while (resultSet.next()) {
0620:                    String name = resultSet.getString("column_name");
0621:                    primaryKeys.put(name, table.new Key(name, resultSet
0622:                            .getString("table_name"), resultSet
0623:                            .getString("table_cat"), resultSet
0624:                            .getString("table_schem")));
0625:                }
0626:
0627:                table.setPrimaryKeys(primaryKeys);
0628:
0629:                resultSet.close();
0630:
0631:                resultSet = metaData.getBestRowIdentifier(table
0632:                        .getCatalogName(), table.getSchemaName(), table
0633:                        .getTableName(), DatabaseMetaData.bestRowSession, true);
0634:
0635:                Set bestRowIds = new HashSet();
0636:
0637:                while (resultSet.next())
0638:                    bestRowIds.add(resultSet.getString("column_name"));
0639:
0640:                table.setBestRowIds(bestRowIds);
0641:
0642:                resultSet.close();
0643:
0644:                resultSet = metaData.getImportedKeys(table.getCatalogName(),
0645:                        table.getSchemaName(), table.getTableName());
0646:
0647:                Map importedKeys = new HashMap();
0648:
0649:                while (resultSet.next()) {
0650:                    String name = resultSet.getString("fkcolumn_name");
0651:                    importedKeys.put(name, table.new Key(name, resultSet
0652:                            .getString("fktable_cat"), resultSet
0653:                            .getString("fktable_schem"), resultSet
0654:                            .getString("fktable_name"), resultSet
0655:                            .getString("pkcolumn_name"), resultSet
0656:                            .getString("pktable_cat"), resultSet
0657:                            .getString("pktable_schem"), resultSet
0658:                            .getString("pktable_name")));
0659:                }
0660:
0661:                table.setImportedKeys(importedKeys);
0662:
0663:                resultSet.close();
0664:
0665:                resultSet = metaData.getExportedKeys(table.getCatalogName(),
0666:                        table.getSchemaName(), table.getTableName());
0667:
0668:                Map exportedKeys = new HashMap();
0669:
0670:                while (resultSet.next()) {
0671:                    String name = resultSet.getString("pkcolumn_name");
0672:                    exportedKeys.put(name, table.new Key(name, resultSet
0673:                            .getString("pktable_cat"), resultSet
0674:                            .getString("pktable_schem"), resultSet
0675:                            .getString("pktable_name"), resultSet
0676:                            .getString("fkcolumn_name"), resultSet
0677:                            .getString("fktable_cat"), resultSet
0678:                            .getString("fktable_schem"), resultSet
0679:                            .getString("fktable_name")));
0680:                }
0681:
0682:                table.setExportedKeys(exportedKeys);
0683:
0684:                resultSet.close();
0685:
0686:                resultSet = metaData.getColumns(table.getCatalogName(), table
0687:                        .getSchemaName(), table.getTableName(), null);
0688:
0689:                Map columns = new HashMap();
0690:
0691:                while (resultSet.next()) {
0692:                    String columnName = resultSet.getString("COLUMN_NAME");
0693:
0694:                    Table.Column column = table.new Column(columnName,
0695:                            resultSet.getString("TYPE_NAME"), resultSet
0696:                                    .getInt("DATA_TYPE"), resultSet
0697:                                    .getInt("COLUMN_SIZE"), resultSet
0698:                                    .getInt("DECIMAL_DIGITS"), resultSet
0699:                                    .getInt("NUM_PREC_RADIX"), resultSet
0700:                                    .getString("IS_NULLABLE").equalsIgnoreCase(
0701:                                            "Yes") ? true : false, primaryKeys
0702:                                    .get(columnName) != null, bestRowIds
0703:                                    .contains(columnName));
0704:
0705:                    columns.put(normalizeName(columnName), column);
0706:                }
0707:
0708:                table.setColumns(columns);
0709:
0710:                resultSet.close();
0711:
0712:                if ((resultSet = statement.executeQuery("select * from "
0713:                        + table.getTableName() + " where 1 = 0")) != null) {
0714:                    ResultSetMetaData resultSetMetaData = resultSet
0715:                            .getMetaData();
0716:
0717:                    if (resultSetMetaData != null)
0718:                        for (int i = 0; i < resultSetMetaData.getColumnCount(); i++) {
0719:                            Table.Column column = table.getColumn(columnMapper,
0720:                                    normalizeName(resultSetMetaData
0721:                                            .getColumnName(i + 1)), null);
0722:
0723:                            if (column != null) {
0724:                                column.setAdditionalInfo(resultSetMetaData
0725:                                        .getColumnLabel(i + 1),
0726:                                        resultSetMetaData
0727:                                                .getColumnClassName(i + 1),
0728:                                        resultSetMetaData
0729:                                                .isAutoIncrement(i + 1),
0730:                                        resultSetMetaData.isReadOnly(i + 1),
0731:                                        resultSetMetaData.isSearchable(i + 1));
0732:
0733:                                if (column.isAutoIncrement())
0734:                                    table.setGeneratedKey(column
0735:                                            .getColumnName());
0736:                            }
0737:                        }
0738:
0739:                    resultSet.close();
0740:                }
0741:
0742:                table.setTableDetailLoaded(true);
0743:            }
0744:
0745:            public class Table {
0746:                private String tableName, catalogName, schemaName, type,
0747:                        generatedKey;
0748:                private Map primaryKeys, exportedKeys, importedKeys;
0749:                private Map columns, columnNameMapping = new HashMap();
0750:                private boolean isTableDetailLoaded;
0751:                private Set bestRowIds;
0752:
0753:                Table(String tableName, String catalogName, String schemaName,
0754:                        String type) {
0755:                    this .tableName = tableName;
0756:                    this .catalogName = catalogName;
0757:                    this .schemaName = schemaName;
0758:                    this .type = type;
0759:                }
0760:
0761:                public String getTableName() {
0762:                    return tableName;
0763:                }
0764:
0765:                public String getCatalogName() {
0766:                    return catalogName;
0767:                }
0768:
0769:                public String getSchemaName() {
0770:                    return schemaName;
0771:                }
0772:
0773:                public String getType() {
0774:                    return type;
0775:                }
0776:
0777:                public String toString() {
0778:                    return "catalog = " + catalogName + ", schema = "
0779:                            + schemaName + ", table = " + tableName;
0780:                }
0781:
0782:                boolean isTableDetailLoaded() {
0783:                    return isTableDetailLoaded;
0784:                }
0785:
0786:                void setTableDetailLoaded(boolean isTableDetailLoaded) {
0787:                    this .isTableDetailLoaded = isTableDetailLoaded;
0788:                }
0789:
0790:                public Set getBestRowIds() {
0791:                    return bestRowIds;
0792:                }
0793:
0794:                void setBestRowIds(Set bestRowIds) {
0795:                    this .bestRowIds = bestRowIds;
0796:                }
0797:
0798:                public String getGeneratedKey() {
0799:                    return generatedKey;
0800:                }
0801:
0802:                void setGeneratedKey(String generatedKey) {
0803:                    this .generatedKey = generatedKey;
0804:                }
0805:
0806:                public String getPossibleGeneratedKey() {
0807:                    if (generatedKey != null)
0808:                        return generatedKey;
0809:
0810:                    Column lastColumnMatch = null;
0811:
0812:                    for (Iterator it = primaryKeys.keySet().iterator(); it
0813:                            .hasNext();) {
0814:                        String key = (String) it.next();
0815:                        Column column = (Column) columns
0816:                                .get(normalizeName(key));
0817:
0818:                        if (importedKeys.get(key) == null)
0819:                            lastColumnMatch = column;
0820:                    }
0821:
0822:                    if (lastColumnMatch != null)
0823:                        return lastColumnMatch.getColumnName();
0824:
0825:                    return null;
0826:                }
0827:
0828:                public Map getPrimaryKeys() {
0829:                    return primaryKeys;
0830:                }
0831:
0832:                void setPrimaryKeys(Map primaryKeys) {
0833:                    this .primaryKeys = primaryKeys;
0834:                }
0835:
0836:                public Map getExportedKeys() {
0837:                    return exportedKeys;
0838:                }
0839:
0840:                void setExportedKeys(Map exportedKeys) {
0841:                    this .exportedKeys = exportedKeys;
0842:                }
0843:
0844:                public Map getImportedKeys() {
0845:                    return importedKeys;
0846:                }
0847:
0848:                void setImportedKeys(Map importedKeys) {
0849:                    this .importedKeys = importedKeys;
0850:                }
0851:
0852:                public Map getColumns() {
0853:                    return columns;
0854:                }
0855:
0856:                void setColumns(Map columns) {
0857:                    this .columns = columns;
0858:                }
0859:
0860:                public synchronized void addColumnNameMapping(
0861:                        String searchColumnName, String returnColumnName) {
0862:                    columnNameMapping.put(normalizeName(searchColumnName),
0863:                            returnColumnName);
0864:                }
0865:
0866:                public Column getColumn(ColumnMapping columnMapper,
0867:                        String columnName, Object object)
0868:                        throws JPersistException {
0869:                    Column column = (Column) columns
0870:                            .get(normalizeName(columnName));
0871:
0872:                    if (column != null)
0873:                        return column;
0874:
0875:                    return columnSearch(columnMapper, columnName, object);
0876:                }
0877:
0878:                synchronized Column columnSearch(ColumnMapping columnMapper,
0879:                        String columnName, Object object)
0880:                        throws JPersistException {
0881:                    String normalizedColumnName = normalizeName(columnName), name = null;
0882:                    Column column = (Column) columns.get(normalizedColumnName);
0883:
0884:                    if (column != null)
0885:                        return column;
0886:
0887:                    if (object != null
0888:                            && object instanceof  ColumnMapping
0889:                            && (name = ((ColumnMapping) object)
0890:                                    .getTableColumnName(columnName
0891:                                            .toLowerCase())) != null)
0892:                        column = (Column) columns.get(normalizeName(name));
0893:                    else if (columnMapper != null
0894:                            && (name = columnMapper
0895:                                    .getTableColumnName(columnName
0896:                                            .toLowerCase())) != null)
0897:                        column = (Column) columns.get(normalizeName(name));
0898:                    else if ((name = (String) columnNameMapping
0899:                            .get(normalizedColumnName)) != null)
0900:                        column = (Column) columns.get(normalizeName(name));
0901:                    else if ((stripColumnPrefixes != null || stripColumnSuffixes != null)) {
0902:                        Iterator it = columns.entrySet().iterator();
0903:
0904:                        while (it.hasNext()) {
0905:                            Column itColumn = (Column) ((Map.Entry) it.next())
0906:                                    .getValue();
0907:                            String strippedName = normalizeName(stripName(
0908:                                    itColumn.getColumnName(),
0909:                                    stripColumnPrefixes, stripColumnSuffixes));
0910:
0911:                            if (columnName.equals(strippedName)) {
0912:                                if (column == null)
0913:                                    column = itColumn;
0914:                                else
0915:                                    throw new JPersistException(
0916:                                            "Scanning produces multiple possible columns for column name '"
0917:                                                    + columnName
0918:                                                    + "' found in table '"
0919:                                                    + getTableName()
0920:                                                    + "'\n"
0921:                                                    + "To obtain an exact match you can further qualify the naming, or define prefix/suffix stripping, or column name mapping.");
0922:                            }
0923:                        }
0924:                    }
0925:
0926:                    if (!strictMethodColumnMatching && column == null) {
0927:                        Iterator it = columns.keySet().iterator();
0928:
0929:                        while (it.hasNext()) {
0930:                            name = (String) it.next();
0931:
0932:                            if (name.indexOf(normalizedColumnName) != -1) {
0933:                                if (column == null
0934:                                        || name.equals(normalizedColumnName))
0935:                                    column = (Column) columns.get(name);
0936:                                else
0937:                                    throw new JPersistException(
0938:                                            "Scanning produces multiple possible columns for column name '"
0939:                                                    + columnName
0940:                                                    + "' found in table '"
0941:                                                    + getTableName()
0942:                                                    + "'\n"
0943:                                                    + "To obtain an exact match you can further qualify the naming, or define prefix/suffix stripping, or column name mapping.");
0944:                            }
0945:                        }
0946:                    }
0947:
0948:                    if (column != null)
0949:                        columns.put(normalizedColumnName, column);
0950:
0951:                    if (column == null && logger.isLoggable(Level.FINER)
0952:                            && !columnName.equals("dbAssociation"))
0953:                        logger.finer("Column " + columnName + " not matched!");
0954:
0955:                    return column;
0956:                }
0957:
0958:                public class Column {
0959:                    private String columnName, columnLabel, typeName,
0960:                            className;
0961:                    private int dataType, columnSize, decimalDigits, radix;
0962:                    private boolean isNullable, isPrimaryKey, isRowId,
0963:                            isAutoIncrement, isReadOnly, isSearchable;
0964:
0965:                    Column(String columnName, String typeName, int dataType,
0966:                            int columnSize, int decimalDigits, int radix,
0967:                            boolean isNullable, boolean isPrimaryKey,
0968:                            boolean isRowId) {
0969:                        this .columnName = columnName;
0970:                        this .typeName = typeName;
0971:                        this .dataType = dataType;
0972:                        this .columnSize = columnSize;
0973:                        this .decimalDigits = decimalDigits;
0974:                        this .radix = radix;
0975:                        this .isNullable = isNullable;
0976:                        this .isPrimaryKey = isPrimaryKey;
0977:                        this .isRowId = isRowId;
0978:                    }
0979:
0980:                    void setAdditionalInfo(String columnLabel,
0981:                            String className, boolean isAutoIncrement,
0982:                            boolean isReadOnly, boolean isSearchable) {
0983:                        this .columnLabel = columnLabel;
0984:                        this .className = className;
0985:                        this .isAutoIncrement = isAutoIncrement;
0986:                        //this.isReadOnly = isReadOnly;
0987:                        this .isSearchable = isSearchable;
0988:                    }
0989:
0990:                    public String getColumnName() {
0991:                        return columnName;
0992:                    }
0993:
0994:                    public String getColumnLabel() {
0995:                        return columnLabel;
0996:                    }
0997:
0998:                    public String getClassName() {
0999:                        return className;
1000:                    }
1001:
1002:                    public String getTypeName() {
1003:                        return typeName;
1004:                    }
1005:
1006:                    public int getDataType() {
1007:                        return dataType;
1008:                    }
1009:
1010:                    public int getColumnSize() {
1011:                        return columnSize;
1012:                    }
1013:
1014:                    public int getDecimalDigits() {
1015:                        return decimalDigits;
1016:                    }
1017:
1018:                    public int getRadix() {
1019:                        return radix;
1020:                    }
1021:
1022:                    public boolean isNullable() {
1023:                        return isNullable;
1024:                    }
1025:
1026:                    public boolean isPrimaryKey() {
1027:                        return isPrimaryKey;
1028:                    }
1029:
1030:                    public boolean isRowId() {
1031:                        return isRowId;
1032:                    }
1033:
1034:                    public boolean isAutoIncrement() {
1035:                        return isAutoIncrement;
1036:                    }
1037:
1038:                    public boolean isReadOnly() {
1039:                        return isReadOnly || isAutoIncrement;
1040:                    }
1041:
1042:                    public boolean isSearchable() {
1043:                        return isSearchable;
1044:                    }
1045:                }
1046:
1047:                public class Key {
1048:                    private String localColumnName, localTableCatalog,
1049:                            localTableSchema, localTableName,
1050:                            foreignColumnName, foreignTableCatalog,
1051:                            foreignTableSchema, foreignTableName;
1052:
1053:                    Key(String localColumnName, String localTableCatalog,
1054:                            String localTableSchema, String localTableName) {
1055:                        this .localColumnName = localColumnName;
1056:                        this .localTableCatalog = localTableCatalog;
1057:                        this .localTableSchema = localTableSchema;
1058:                        this .localTableName = localTableName;
1059:                    }
1060:
1061:                    Key(String localColumnName, String localTableCatalog,
1062:                            String localTableSchema, String localTableName,
1063:                            String foreignColumnName,
1064:                            String foreignTableCatalog,
1065:                            String foreignTableSchema, String foreignTableName) {
1066:                        this .localColumnName = localColumnName;
1067:                        this .localTableCatalog = localTableCatalog;
1068:                        this .localTableSchema = localTableSchema;
1069:                        this .localTableName = localTableName;
1070:                        this .foreignColumnName = foreignColumnName;
1071:                        this .foreignTableCatalog = foreignTableCatalog;
1072:                        this .foreignTableSchema = foreignTableSchema;
1073:                        this .foreignTableName = foreignTableName;
1074:                    }
1075:
1076:                    public String getForeignColumnName() {
1077:                        return foreignColumnName;
1078:                    }
1079:
1080:                    public String getForeignTableCatalog() {
1081:                        return foreignTableCatalog;
1082:                    }
1083:
1084:                    public String getForeignTableSchema() {
1085:                        return foreignTableSchema;
1086:                    }
1087:
1088:                    public String getForeignTableName() {
1089:                        return foreignTableName;
1090:                    }
1091:
1092:                    public String getLocalColumnName() {
1093:                        return localColumnName;
1094:                    }
1095:
1096:                    public String getLocalTableCatalog() {
1097:                        return localTableCatalog;
1098:                    }
1099:
1100:                    public String getLocalTableSchema() {
1101:                        return localTableSchema;
1102:                    }
1103:
1104:                    public String getLocalTableName() {
1105:                        return localTableName;
1106:                    }
1107:                }
1108:            }
1109:
1110:            class NullTable extends Table {
1111:                NullTable() {
1112:                    super (null, null, null, null);
1113:                }
1114:            }
1115:
1116:            static String stripName(String name, Set prefixes, Set suffixes) {
1117:                if (prefixes != null)
1118:                    for (Iterator it = prefixes.iterator(); it.hasNext();) {
1119:                        String prefix = (String) it.next();
1120:
1121:                        if (name.startsWith(prefix)) {
1122:                            name = name.substring(prefix.length());
1123:                            break;
1124:                        }
1125:                    }
1126:
1127:                if (suffixes != null)
1128:                    for (Iterator it = suffixes.iterator(); it.hasNext();) {
1129:                        String suffix = (String) it.next();
1130:
1131:                        if (name.endsWith(suffix)) {
1132:                            name = name.substring(0, name.length()
1133:                                    - suffix.length());
1134:                            break;
1135:                        }
1136:                    }
1137:
1138:                return name;
1139:            }
1140:
1141:            static String normalizeName(String name) {
1142:                return name.replaceAll("_", "").toLowerCase();
1143:            }
1144:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.