001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.spring.hibernate;
022:
023: import com.liferay.util.dao.DataAccess;
024:
025: import java.sql.CallableStatement;
026: import java.sql.Connection;
027: import java.sql.DatabaseMetaData;
028: import java.sql.ResultSet;
029: import java.sql.SQLException;
030:
031: import java.util.Enumeration;
032: import java.util.Map;
033: import java.util.Properties;
034: import java.util.Set;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: import org.hibernate.HibernateException;
040: import org.hibernate.LockMode;
041: import org.hibernate.MappingException;
042: import org.hibernate.dialect.DB2400Dialect;
043: import org.hibernate.dialect.Dialect;
044: import org.hibernate.dialect.DialectFactory;
045: import org.hibernate.dialect.SybaseDialect;
046: import org.hibernate.dialect.lock.LockingStrategy;
047: import org.hibernate.exception.SQLExceptionConverter;
048: import org.hibernate.exception.ViolatedConstraintNameExtracter;
049: import org.hibernate.persister.entity.Lockable;
050: import org.hibernate.sql.CaseFragment;
051: import org.hibernate.sql.JoinFragment;
052:
053: /**
054: * <a href="DynamicDialect.java.html"><b><i>View Source</i></b></a>
055: *
056: * @author Brian Wing Shun Chan
057: * @author Bruno Farache
058: *
059: */
060: public class DynamicDialect extends Dialect {
061:
062: public DynamicDialect() {
063:
064: // Instantiate the proper dialect
065:
066: Connection con = null;
067:
068: try {
069: con = HibernateUtil.getConnection();
070:
071: DatabaseMetaData metaData = con.getMetaData();
072:
073: String dbName = metaData.getDatabaseProductName();
074: int dbMajorVersion = metaData.getDatabaseMajorVersion();
075:
076: if (_log.isInfoEnabled()) {
077: _log.info("Determining dialect for " + dbName + " "
078: + dbMajorVersion);
079: }
080:
081: if (dbName.startsWith("HSQL")) {
082: if (_log.isWarnEnabled()) {
083: _log
084: .warn("Liferay is configured to use Hypersonic as its "
085: + "database. Do NOT use Hypersonic in production. "
086: + "Hypersonic is an embedded database useful "
087: + "for development and demo'ing purposes.");
088: }
089: }
090:
091: if (dbName.equals("ASE") && (dbMajorVersion == 15)) {
092: _dialect = new SybaseDialect();
093: } else {
094: _dialect = DialectFactory.determineDialect(dbName,
095: dbMajorVersion);
096: }
097:
098: if (_log.isInfoEnabled()) {
099: _log.info("Using dialect "
100: + _dialect.getClass().getName());
101: }
102: } catch (Exception e) {
103: String msg = e.getMessage();
104:
105: if (msg.indexOf("explicitly set for database: DB2") != -1) {
106: _dialect = new DB2400Dialect();
107:
108: if (_log.isWarnEnabled()) {
109: _log
110: .warn("DB2400Dialect was dynamically chosen as the "
111: + "Hibernate dialect for DB2. This can be "
112: + "overriden in portal.properties");
113: }
114: } else {
115: _log.error(e, e);
116: }
117: } finally {
118: DataAccess.cleanUp(con);
119: }
120:
121: if (_dialect == null) {
122: throw new RuntimeException("No dialect found");
123: }
124:
125: // Synchorize default properties
126:
127: Properties dynamicDefaultProps = getDefaultProperties();
128: Properties dialectDefaultProps = _dialect
129: .getDefaultProperties();
130:
131: dynamicDefaultProps.clear();
132:
133: Enumeration enu = dialectDefaultProps.propertyNames();
134:
135: while (enu.hasMoreElements()) {
136: String key = (String) enu.nextElement();
137: String value = dialectDefaultProps.getProperty(key);
138:
139: dynamicDefaultProps.setProperty(key, value);
140: }
141: }
142:
143: public Dialect getWrappedDialect() {
144: return _dialect;
145: }
146:
147: public String appendIdentitySelectToInsert(String insertSQL) {
148: return _dialect.appendIdentitySelectToInsert(insertSQL);
149: }
150:
151: public String appendLockHint(LockMode mode, String tableName) {
152: return _dialect.appendLockHint(mode, tableName);
153: }
154:
155: public String applyLocksToSql(String sql, Map aliasedLockModes,
156: Map keyColumnNames) {
157:
158: return _dialect.applyLocksToSql(sql, aliasedLockModes,
159: keyColumnNames);
160: }
161:
162: public boolean areStringComparisonsCaseInsensitive() {
163: return _dialect.areStringComparisonsCaseInsensitive();
164: }
165:
166: public boolean bindLimitParametersFirst() {
167: return _dialect.bindLimitParametersFirst();
168: }
169:
170: public boolean bindLimitParametersInReverseOrder() {
171: return _dialect.bindLimitParametersInReverseOrder();
172: }
173:
174: public SQLExceptionConverter buildSQLExceptionConverter() {
175: return _dialect.buildSQLExceptionConverter();
176: }
177:
178: public char closeQuote() {
179: return _dialect.closeQuote();
180: }
181:
182: public CaseFragment createCaseFragment() {
183: return _dialect.createCaseFragment();
184: }
185:
186: public JoinFragment createOuterJoinFragment() {
187: return _dialect.createOuterJoinFragment();
188: }
189:
190: public boolean doesReadCommittedCauseWritersToBlockReaders() {
191: return _dialect.doesReadCommittedCauseWritersToBlockReaders();
192: }
193:
194: public boolean doesRepeatableReadCauseReadersToBlockWriters() {
195: return _dialect.doesRepeatableReadCauseReadersToBlockWriters();
196: }
197:
198: public boolean dropConstraints() {
199: return _dialect.dropConstraints();
200: }
201:
202: public boolean dropTemporaryTableAfterUse() {
203: return _dialect.dropTemporaryTableAfterUse();
204: }
205:
206: public boolean forUpdateOfColumns() {
207: return _dialect.forUpdateOfColumns();
208: }
209:
210: public String generateTemporaryTableName(String baseTableName) {
211: return _dialect.generateTemporaryTableName(baseTableName);
212: }
213:
214: public String getAddColumnString() {
215: return _dialect.getAddColumnString();
216: }
217:
218: public String getAddForeignKeyConstraintString(
219: String constraintName, String[] foreignKey,
220: String referencedTable, String[] primaryKey,
221: boolean referencesPrimaryKey) {
222:
223: return _dialect.getAddForeignKeyConstraintString(
224: constraintName, foreignKey, referencedTable,
225: primaryKey, referencesPrimaryKey);
226: }
227:
228: public String getAddPrimaryKeyConstraintString(String constraintName) {
229: return _dialect
230: .getAddPrimaryKeyConstraintString(constraintName);
231: }
232:
233: public String getCascadeConstraintsString() {
234: return _dialect.getCascadeConstraintsString();
235: }
236:
237: public String getCastTypeName(int code) {
238: return _dialect.getCastTypeName(code);
239: }
240:
241: public String getColumnComment(String comment) {
242: return _dialect.getColumnComment(comment);
243: }
244:
245: public String getCreateMultisetTableString() {
246: return _dialect.getCreateMultisetTableString();
247: }
248:
249: /**
250: * @deprecated
251: */
252: public String[] getCreateSequenceStrings(String sequenceName)
253: throws MappingException {
254:
255: return _dialect.getCreateSequenceStrings(sequenceName);
256: }
257:
258: public String[] getCreateSequenceStrings(String sequenceName,
259: int initialValue, int incrementSize)
260: throws MappingException {
261:
262: return _dialect.getCreateSequenceStrings(sequenceName,
263: initialValue, incrementSize);
264: }
265:
266: public String getCreateTableString() {
267: return _dialect.getCreateTableString();
268: }
269:
270: public String getCreateTemporaryTablePostfix() {
271: return _dialect.getCreateTemporaryTablePostfix();
272: }
273:
274: public String getCreateTemporaryTableString() {
275: return _dialect.getCreateTemporaryTableString();
276: }
277:
278: public String getCurrentTimestampSelectString() {
279: return _dialect.getCurrentTimestampSelectString();
280: }
281:
282: public String getCurrentTimestampSQLFunctionName() {
283: return _dialect.getCurrentTimestampSQLFunctionName();
284: }
285:
286: public String getDropForeignKeyString() {
287: return _dialect.getDropForeignKeyString();
288: }
289:
290: public String[] getDropSequenceStrings(String sequenceName)
291: throws MappingException {
292:
293: return _dialect.getDropSequenceStrings(sequenceName);
294: }
295:
296: public String getForUpdateNowaitString() {
297: return _dialect.getForUpdateNowaitString();
298: }
299:
300: public String getForUpdateNowaitString(String aliases) {
301: return _dialect.getForUpdateNowaitString(aliases);
302: }
303:
304: public String getForUpdateString() {
305: return _dialect.getForUpdateString();
306: }
307:
308: public String getForUpdateString(LockMode lockMode) {
309: return _dialect.getForUpdateString(lockMode);
310: }
311:
312: public String getForUpdateString(String aliases) {
313: return _dialect.getForUpdateString(aliases);
314: }
315:
316: public String getHibernateTypeName(int code)
317: throws HibernateException {
318: return _dialect.getHibernateTypeName(code);
319: }
320:
321: public String getHibernateTypeName(int code, int length,
322: int precision, int scale) throws HibernateException {
323:
324: return _dialect.getHibernateTypeName(code, length, precision,
325: scale);
326: }
327:
328: public String getIdentityColumnString(int type)
329: throws MappingException {
330: return _dialect.getIdentityColumnString(type);
331: }
332:
333: public String getIdentityInsertString() {
334: return _dialect.getIdentityInsertString();
335: }
336:
337: public String getIdentitySelectString(String table, String column,
338: int type) throws MappingException {
339:
340: return _dialect.getIdentitySelectString(table, column, type);
341: }
342:
343: public Set getKeywords() {
344: return _dialect.getKeywords();
345: }
346:
347: public String getLimitString(String querySelect, int hasOffset,
348: int limit) {
349: return _dialect.getLimitString(querySelect, hasOffset, limit);
350: }
351:
352: public LockingStrategy getLockingStrategy(Lockable lockable,
353: LockMode lockMode) {
354:
355: return _dialect.getLockingStrategy(lockable, lockMode);
356: }
357:
358: public String getLowercaseFunction() {
359: return _dialect.getLowercaseFunction();
360: }
361:
362: public int getMaxAliasLength() {
363: return _dialect.getMaxAliasLength();
364: }
365:
366: public Class getNativeIdentifierGeneratorClass() {
367: return _dialect.getNativeIdentifierGeneratorClass();
368: }
369:
370: public String getNoColumnsInsertString() {
371: return _dialect.getNoColumnsInsertString();
372: }
373:
374: public String getNullColumnString() {
375: return _dialect.getNullColumnString();
376: }
377:
378: public String getQuerySequencesString() {
379: return _dialect.getQuerySequencesString();
380: }
381:
382: public ResultSet getResultSet(CallableStatement ps)
383: throws SQLException {
384: return _dialect.getResultSet(ps);
385: }
386:
387: public String getSelectClauseNullString(int sqlType) {
388: return _dialect.getSelectClauseNullString(sqlType);
389: }
390:
391: public String getSelectGUIDString() {
392: return _dialect.getSelectGUIDString();
393: }
394:
395: public String getSelectSequenceNextValString(String sequenceName)
396: throws MappingException {
397:
398: return _dialect.getSelectSequenceNextValString(sequenceName);
399: }
400:
401: public String getSequenceNextValString(String sequenceName)
402: throws MappingException {
403:
404: return _dialect.getSequenceNextValString(sequenceName);
405: }
406:
407: public String getTableComment(String comment) {
408: return _dialect.getTableComment(comment);
409: }
410:
411: public String getTableTypeString() {
412: return _dialect.getTableTypeString();
413: }
414:
415: public String getTypeName(int code) throws HibernateException {
416: return _dialect.getTypeName(code);
417: }
418:
419: public String getTypeName(int code, int length, int precision,
420: int scale) throws HibernateException {
421:
422: return _dialect.getTypeName(code, length, precision, scale);
423: }
424:
425: public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
426:
427: return _dialect.getViolatedConstraintNameExtracter();
428: }
429:
430: public boolean hasAlterTable() {
431: return _dialect.hasAlterTable();
432: }
433:
434: public boolean hasDataTypeInIdentityColumn() {
435: return _dialect.hasDataTypeInIdentityColumn();
436: }
437:
438: public boolean hasSelfReferentialForeignKeyBug() {
439: return _dialect.hasSelfReferentialForeignKeyBug();
440: }
441:
442: public boolean isCurrentTimestampSelectStringCallable() {
443: return _dialect.isCurrentTimestampSelectStringCallable();
444: }
445:
446: public char openQuote() {
447: return _dialect.openQuote();
448: }
449:
450: public Boolean performTemporaryTableDDLInIsolation() {
451: return _dialect.performTemporaryTableDDLInIsolation();
452: }
453:
454: public boolean qualifyIndexName() {
455: return _dialect.qualifyIndexName();
456: }
457:
458: public int registerResultSetOutParameter(
459: CallableStatement statement, int col) throws SQLException {
460:
461: return _dialect.registerResultSetOutParameter(statement, col);
462: }
463:
464: public boolean supportsBindAsCallableArgument() {
465: return _dialect.supportsBindAsCallableArgument();
466: }
467:
468: public boolean supportsCascadeDelete() {
469: return _dialect.supportsCascadeDelete();
470: }
471:
472: public boolean supportsCircularCascadeDeleteConstraints() {
473: return _dialect.supportsCircularCascadeDeleteConstraints();
474: }
475:
476: public boolean supportsColumnCheck() {
477: return _dialect.supportsColumnCheck();
478: }
479:
480: public boolean supportsCommentOn() {
481: return _dialect.supportsCommentOn();
482: }
483:
484: public boolean supportsCurrentTimestampSelection() {
485: return _dialect.supportsCurrentTimestampSelection();
486: }
487:
488: public boolean supportsEmptyInList() {
489: return _dialect.supportsEmptyInList();
490: }
491:
492: public boolean supportsExistsInSelect() {
493: return _dialect.supportsExistsInSelect();
494: }
495:
496: public boolean supportsExpectedLobUsagePattern() {
497: return _dialect.supportsExpectedLobUsagePattern();
498: }
499:
500: public boolean supportsIdentityColumns() {
501: return _dialect.supportsIdentityColumns();
502: }
503:
504: public boolean supportsIfExistsAfterTableName() {
505: return _dialect.supportsIfExistsAfterTableName();
506: }
507:
508: public boolean supportsIfExistsBeforeTableName() {
509: return _dialect.supportsIfExistsBeforeTableName();
510: }
511:
512: public boolean supportsInsertSelectIdentity() {
513: return _dialect.supportsInsertSelectIdentity();
514: }
515:
516: public boolean supportsLimit() {
517: return _dialect.supportsLimit();
518: }
519:
520: public boolean supportsLimitOffset() {
521: return _dialect.supportsLimitOffset();
522: }
523:
524: public boolean supportsLobValueChangePropogation() {
525: return _dialect.supportsLobValueChangePropogation();
526: }
527:
528: public boolean supportsNotNullUnique() {
529: return _dialect.supportsNotNullUnique();
530: }
531:
532: public boolean supportsOuterJoinForUpdate() {
533: return _dialect.supportsOuterJoinForUpdate();
534: }
535:
536: public boolean supportsParametersInInsertSelect() {
537: return _dialect.supportsParametersInInsertSelect();
538: }
539:
540: public boolean supportsPooledSequences() {
541: return _dialect.supportsPooledSequences();
542: }
543:
544: public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
545: return _dialect
546: .supportsResultSetPositionQueryMethodsOnForwardOnlyCursor();
547: }
548:
549: public boolean supportsRowValueConstructorSyntax() {
550: return _dialect.supportsRowValueConstructorSyntax();
551: }
552:
553: public boolean supportsRowValueConstructorSyntaxInInList() {
554: return _dialect.supportsRowValueConstructorSyntaxInInList();
555: }
556:
557: public boolean supportsSequences() {
558: return _dialect.supportsSequences();
559: }
560:
561: public boolean supportsSubqueryOnMutatingTable() {
562: return _dialect.supportsSubqueryOnMutatingTable();
563: }
564:
565: public boolean supportsSubselectAsInPredicateLHS() {
566: return _dialect.supportsSubselectAsInPredicateLHS();
567: }
568:
569: public boolean supportsTableCheck() {
570: return _dialect.supportsTableCheck();
571: }
572:
573: public boolean supportsTemporaryTables() {
574: return _dialect.supportsTemporaryTables();
575: }
576:
577: public boolean supportsUnboundedLobLocatorMaterialization() {
578: return _dialect.supportsUnboundedLobLocatorMaterialization();
579: }
580:
581: public boolean supportsUnionAll() {
582: return _dialect.supportsUnionAll();
583: }
584:
585: public boolean supportsUnique() {
586: return _dialect.supportsUnique();
587: }
588:
589: public boolean supportsUniqueConstraintInCreateAlterTable() {
590: return _dialect.supportsUniqueConstraintInCreateAlterTable();
591: }
592:
593: public boolean supportsVariableLimit() {
594: return _dialect.supportsVariableLimit();
595: }
596:
597: public String toBooleanValueString(boolean bool) {
598: return _dialect.toBooleanValueString(bool);
599: }
600:
601: public String toString() {
602: if (_dialect != null) {
603: return _dialect.toString();
604: } else {
605: return null;
606: }
607: }
608:
609: public String transformSelectString(String select) {
610: return _dialect.transformSelectString(select);
611: }
612:
613: public boolean useInputStreamToInsertBlob() {
614: return _dialect.useInputStreamToInsertBlob();
615: }
616:
617: public boolean useMaxForLimit() {
618: return _dialect.useMaxForLimit();
619: }
620:
621: private static Log _log = LogFactory.getLog(DynamicDialect.class);
622:
623: private Dialect _dialect;
624:
625: }
|