001: /**
002: * Copyright (c) 2000-2007 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.io.IOException;
026: import java.sql.CallableStatement;
027: import java.sql.Connection;
028: import java.sql.DatabaseMetaData;
029: import java.sql.DriverManager;
030: import java.sql.ResultSet;
031: import java.sql.SQLException;
032: import java.util.Enumeration;
033: import java.util.Map;
034: import java.util.Properties;
035: import java.util.Set;
036:
037: import javax.naming.NamingException;
038: import javax.sql.DataSource;
039:
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042: import org.hibernate.HibernateException;
043: import org.hibernate.LockMode;
044: import org.hibernate.MappingException;
045: import org.hibernate.dialect.DB2400Dialect;
046: import org.hibernate.dialect.Dialect;
047: import org.hibernate.dialect.DialectFactory;
048: import org.hibernate.dialect.lock.LockingStrategy;
049: import org.hibernate.exception.SQLExceptionConverter;
050: import org.hibernate.exception.ViolatedConstraintNameExtracter;
051: import org.hibernate.persister.entity.Lockable;
052: import org.hibernate.sql.CaseFragment;
053: import org.hibernate.sql.JoinFragment;
054: import org.springframework.jndi.JndiObjectFactoryBean;
055:
056: /**
057: * <a href="DynamicDialect.java.html"><b><i>View Source</i></b></a>
058: *
059: * @author Brian Wing Shun Chan
060: * @author Bruno Farache
061: *
062: * @note [akakunin@emdev.ru] I've got this class from LifeRay project
063: * - since it is also LGPL project I hope here should not be problem with license
064: * and made minimal changes to reduce dependencies from another classes.
065: * Plus, I implemented own way to get connection (from jndi name specified in configuration)
066: *
067: */
068: public class DynamicDialect extends Dialect {
069:
070: public DynamicDialect() {
071:
072: // Instantiate the proper dialect
073:
074: Connection con = null;
075:
076: try {
077: con = getConnection();
078:
079: DatabaseMetaData metaData = con.getMetaData();
080:
081: String dbName = metaData.getDatabaseProductName();
082:
083: // [SZA, 31.01.2008] Warning: some of jdbc drivers throws
084: // java.lang.AbstractMethodError when you try to call getDatabaseMajorVersion()!
085: // In this case specify a concrete dialect in config.properties. See dialects here:
086: // http://www.hibernate.org/hib_docs/v3/api/org/hibernate/dialect/package-summary.html
087: int dbMajorVersion = metaData.getDatabaseMajorVersion();
088:
089: if (_log.isInfoEnabled()) {
090: _log.info("Determining dialect for " + dbName + " "
091: + dbMajorVersion);
092: }
093:
094: if (dbName.startsWith("HSQL")) {
095:
096: if (_log.isWarnEnabled()) {
097: _log
098: .warn("Liferay is configured to use Hypersonic as its "
099: + "database. Do NOT use Hypersonic in production. "
100: + "Hypersonic is an embedded database useful "
101: + "for development and demo'ing purposes.");
102: }
103: }
104:
105: _dialect = DialectFactory.determineDialect(dbName,
106: dbMajorVersion);
107:
108: if (_log.isInfoEnabled()) {
109: _log.info("Using dialect "
110: + _dialect.getClass().getName());
111: }
112: } catch (Exception e) {
113: String msg = e.getMessage();
114:
115: if (msg != null
116: && msg.indexOf("explicitly set for database: DB2") != -1) {
117: _dialect = new DB2400Dialect();
118:
119: if (_log.isWarnEnabled()) {
120: _log
121: .warn("DB2400Dialect was dynamically chosen as the "
122: + "Hibernate dialect for DB2. This can be "
123: + "overriden in portal.properties");
124: }
125: } else {
126: _log.error(e, e);
127: }
128: } finally {
129: try {
130: if (con != null) {
131: con.close();
132: }
133: } catch (SQLException sqle) {
134: if (_log.isWarnEnabled()) {
135: _log.warn(sqle.getMessage());
136: }
137: }
138: }
139:
140: if (_dialect == null) {
141: throw new DynamicDialectException("No dialect found");
142: }
143:
144: // Synchorize default properties
145:
146: Properties dynamicDefaultProps = getDefaultProperties();
147: Properties dialectDefaultProps = _dialect
148: .getDefaultProperties();
149:
150: dynamicDefaultProps.clear();
151:
152: Enumeration enu = dialectDefaultProps.propertyNames();
153:
154: while (enu.hasMoreElements()) {
155: String key = (String) enu.nextElement();
156: String value = dialectDefaultProps.getProperty(key);
157:
158: dynamicDefaultProps.setProperty(key, value);
159: }
160: }
161:
162: public Dialect getWrappedDialect() {
163: return _dialect;
164: }
165:
166: public String appendIdentitySelectToInsert(String insertSQL) {
167: return _dialect.appendIdentitySelectToInsert(insertSQL);
168: }
169:
170: public String appendLockHint(LockMode mode, String tableName) {
171: return _dialect.appendLockHint(mode, tableName);
172: }
173:
174: public String applyLocksToSql(String sql, Map aliasedLockModes,
175: Map keyColumnNames) {
176:
177: return _dialect.applyLocksToSql(sql, aliasedLockModes,
178: keyColumnNames);
179: }
180:
181: public boolean areStringComparisonsCaseInsensitive() {
182: return _dialect.areStringComparisonsCaseInsensitive();
183: }
184:
185: public boolean bindLimitParametersFirst() {
186: return _dialect.bindLimitParametersFirst();
187: }
188:
189: public boolean bindLimitParametersInReverseOrder() {
190: return _dialect.bindLimitParametersInReverseOrder();
191: }
192:
193: public SQLExceptionConverter buildSQLExceptionConverter() {
194: return _dialect.buildSQLExceptionConverter();
195: }
196:
197: public char closeQuote() {
198: return _dialect.closeQuote();
199: }
200:
201: public CaseFragment createCaseFragment() {
202: return _dialect.createCaseFragment();
203: }
204:
205: public JoinFragment createOuterJoinFragment() {
206: return _dialect.createOuterJoinFragment();
207: }
208:
209: public boolean dropConstraints() {
210: return _dialect.dropConstraints();
211: }
212:
213: public boolean dropTemporaryTableAfterUse() {
214: return _dialect.dropTemporaryTableAfterUse();
215: }
216:
217: public boolean forUpdateOfColumns() {
218: return _dialect.forUpdateOfColumns();
219: }
220:
221: public String generateTemporaryTableName(String baseTableName) {
222: return _dialect.generateTemporaryTableName(baseTableName);
223: }
224:
225: public String getAddColumnString() {
226: return _dialect.getAddColumnString();
227: }
228:
229: public String getAddForeignKeyConstraintString(
230: String constraintName, String[] foreignKey,
231: String referencedTable, String[] primaryKey,
232: boolean referencesPrimaryKey) {
233:
234: return _dialect.getAddForeignKeyConstraintString(
235: constraintName, foreignKey, referencedTable,
236: primaryKey, referencesPrimaryKey);
237: }
238:
239: public String getAddPrimaryKeyConstraintString(String constraintName) {
240: return _dialect
241: .getAddPrimaryKeyConstraintString(constraintName);
242: }
243:
244: public String getCascadeConstraintsString() {
245: return _dialect.getCascadeConstraintsString();
246: }
247:
248: public String getCastTypeName(int code) {
249: return _dialect.getCastTypeName(code);
250: }
251:
252: public String getColumnComment(String comment) {
253: return _dialect.getColumnComment(comment);
254: }
255:
256: /**
257: * @deprecated
258: */
259: public String[] getCreateSequenceStrings(String sequenceName)
260: throws MappingException {
261:
262: return _dialect.getCreateSequenceStrings(sequenceName);
263: }
264:
265: public String getCreateTemporaryTablePostfix() {
266: return _dialect.getCreateTemporaryTablePostfix();
267: }
268:
269: public String getCreateTemporaryTableString() {
270: return _dialect.getCreateTemporaryTableString();
271: }
272:
273: public String getCurrentTimestampSelectString() {
274: return _dialect.getCurrentTimestampSelectString();
275: }
276:
277: public String getCurrentTimestampSQLFunctionName() {
278: return _dialect.getCurrentTimestampSQLFunctionName();
279: }
280:
281: public String getDropForeignKeyString() {
282: return _dialect.getDropForeignKeyString();
283: }
284:
285: public String[] getDropSequenceStrings(String sequenceName)
286: throws MappingException {
287:
288: return _dialect.getDropSequenceStrings(sequenceName);
289: }
290:
291: public String getForUpdateNowaitString() {
292: return _dialect.getForUpdateNowaitString();
293: }
294:
295: public String getForUpdateNowaitString(String aliases) {
296: return _dialect.getForUpdateNowaitString(aliases);
297: }
298:
299: public String getForUpdateString() {
300: return _dialect.getForUpdateString();
301: }
302:
303: public String getForUpdateString(LockMode lockMode) {
304: return _dialect.getForUpdateString(lockMode);
305: }
306:
307: public String getForUpdateString(String aliases) {
308: return _dialect.getForUpdateString(aliases);
309: }
310:
311: public String getHibernateTypeName(int code)
312: throws HibernateException {
313: return _dialect.getHibernateTypeName(code);
314: }
315:
316: public String getHibernateTypeName(int code, int length,
317: int precision, int scale) throws HibernateException {
318:
319: return _dialect.getHibernateTypeName(code, length, precision,
320: scale);
321: }
322:
323: public String getIdentityColumnString(int type)
324: throws MappingException {
325: return _dialect.getIdentityColumnString(type);
326: }
327:
328: public String getIdentityInsertString() {
329: return _dialect.getIdentityInsertString();
330: }
331:
332: public String getIdentitySelectString(String table, String column,
333: int type) throws MappingException {
334:
335: return _dialect.getIdentitySelectString(table, column, type);
336: }
337:
338: public Set getKeywords() {
339: return _dialect.getKeywords();
340: }
341:
342: public String getLimitString(String querySelect, int hasOffset,
343: int limit) {
344: return _dialect.getLimitString(querySelect, hasOffset, limit);
345: }
346:
347: public LockingStrategy getLockingStrategy(Lockable lockable,
348: LockMode lockMode) {
349:
350: return _dialect.getLockingStrategy(lockable, lockMode);
351: }
352:
353: public String getLowercaseFunction() {
354: return _dialect.getLowercaseFunction();
355: }
356:
357: public int getMaxAliasLength() {
358: return _dialect.getMaxAliasLength();
359: }
360:
361: public Class getNativeIdentifierGeneratorClass() {
362: return _dialect.getNativeIdentifierGeneratorClass();
363: }
364:
365: public String getNoColumnsInsertString() {
366: return _dialect.getNoColumnsInsertString();
367: }
368:
369: public String getNullColumnString() {
370: return _dialect.getNullColumnString();
371: }
372:
373: public String getQuerySequencesString() {
374: return _dialect.getQuerySequencesString();
375: }
376:
377: public ResultSet getResultSet(CallableStatement ps)
378: throws SQLException {
379: return _dialect.getResultSet(ps);
380: }
381:
382: public String getSelectClauseNullString(int sqlType) {
383: return _dialect.getSelectClauseNullString(sqlType);
384: }
385:
386: public String getSelectGUIDString() {
387: return _dialect.getSelectGUIDString();
388: }
389:
390: public String getSelectSequenceNextValString(String sequenceName)
391: throws MappingException {
392:
393: return _dialect.getSelectSequenceNextValString(sequenceName);
394: }
395:
396: public String getSequenceNextValString(String sequenceName)
397: throws MappingException {
398:
399: return _dialect.getSequenceNextValString(sequenceName);
400: }
401:
402: public String getTableComment(String comment) {
403: return _dialect.getTableComment(comment);
404: }
405:
406: public String getTableTypeString() {
407: return _dialect.getTableTypeString();
408: }
409:
410: public String getTypeName(int code) throws HibernateException {
411: return _dialect.getTypeName(code);
412: }
413:
414: public String getTypeName(int code, int length, int precision,
415: int scale) throws HibernateException {
416:
417: return _dialect.getTypeName(code, length, precision, scale);
418: }
419:
420: public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
421:
422: return _dialect.getViolatedConstraintNameExtracter();
423: }
424:
425: public boolean hasAlterTable() {
426: return _dialect.hasAlterTable();
427: }
428:
429: public boolean hasDataTypeInIdentityColumn() {
430: return _dialect.hasDataTypeInIdentityColumn();
431: }
432:
433: public boolean hasSelfReferentialForeignKeyBug() {
434: return _dialect.hasSelfReferentialForeignKeyBug();
435: }
436:
437: public boolean isCurrentTimestampSelectStringCallable() {
438: return _dialect.isCurrentTimestampSelectStringCallable();
439: }
440:
441: public char openQuote() {
442: return _dialect.openQuote();
443: }
444:
445: public Boolean performTemporaryTableDDLInIsolation() {
446: return _dialect.performTemporaryTableDDLInIsolation();
447: }
448:
449: public boolean qualifyIndexName() {
450: return _dialect.qualifyIndexName();
451: }
452:
453: public int registerResultSetOutParameter(
454: CallableStatement statement, int col) throws SQLException {
455:
456: return _dialect.registerResultSetOutParameter(statement, col);
457: }
458:
459: public boolean supportsCascadeDelete() {
460: return _dialect.supportsCascadeDelete();
461: }
462:
463: public boolean supportsCircularCascadeDeleteConstraints() {
464: return _dialect.supportsCircularCascadeDeleteConstraints();
465: }
466:
467: public boolean supportsColumnCheck() {
468: return _dialect.supportsColumnCheck();
469: }
470:
471: public boolean supportsCommentOn() {
472: return _dialect.supportsCommentOn();
473: }
474:
475: public boolean supportsCurrentTimestampSelection() {
476: return _dialect.supportsCurrentTimestampSelection();
477: }
478:
479: public boolean supportsEmptyInList() {
480: return _dialect.supportsEmptyInList();
481: }
482:
483: public boolean supportsExistsInSelect() {
484: return _dialect.supportsExistsInSelect();
485: }
486:
487: public boolean supportsExpectedLobUsagePattern() {
488: return _dialect.supportsExpectedLobUsagePattern();
489: }
490:
491: public boolean supportsIdentityColumns() {
492: return _dialect.supportsIdentityColumns();
493: }
494:
495: public boolean supportsIfExistsAfterTableName() {
496: return _dialect.supportsIfExistsAfterTableName();
497: }
498:
499: public boolean supportsIfExistsBeforeTableName() {
500: return _dialect.supportsIfExistsBeforeTableName();
501: }
502:
503: public boolean supportsInsertSelectIdentity() {
504: return _dialect.supportsInsertSelectIdentity();
505: }
506:
507: public boolean supportsLimit() {
508: return _dialect.supportsLimit();
509: }
510:
511: public boolean supportsLimitOffset() {
512: return _dialect.supportsLimitOffset();
513: }
514:
515: public boolean supportsLobValueChangePropogation() {
516: return _dialect.supportsLobValueChangePropogation();
517: }
518:
519: public boolean supportsNotNullUnique() {
520: return _dialect.supportsNotNullUnique();
521: }
522:
523: public boolean supportsOuterJoinForUpdate() {
524: return _dialect.supportsOuterJoinForUpdate();
525: }
526:
527: public boolean supportsParametersInInsertSelect() {
528: return _dialect.supportsParametersInInsertSelect();
529: }
530:
531: public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
532: return _dialect
533: .supportsResultSetPositionQueryMethodsOnForwardOnlyCursor();
534: }
535:
536: public boolean supportsRowValueConstructorSyntax() {
537: return _dialect.supportsRowValueConstructorSyntax();
538: }
539:
540: public boolean supportsRowValueConstructorSyntaxInInList() {
541: return _dialect.supportsRowValueConstructorSyntaxInInList();
542: }
543:
544: public boolean supportsSequences() {
545: return _dialect.supportsSequences();
546: }
547:
548: public boolean supportsSubqueryOnMutatingTable() {
549: return _dialect.supportsSubqueryOnMutatingTable();
550: }
551:
552: public boolean supportsSubselectAsInPredicateLHS() {
553: return _dialect.supportsSubselectAsInPredicateLHS();
554: }
555:
556: public boolean supportsTableCheck() {
557: return _dialect.supportsTableCheck();
558: }
559:
560: public boolean supportsTemporaryTables() {
561: return _dialect.supportsTemporaryTables();
562: }
563:
564: public boolean supportsUnboundedLobLocatorMaterialization() {
565: return _dialect.supportsUnboundedLobLocatorMaterialization();
566: }
567:
568: public boolean supportsUnionAll() {
569: return _dialect.supportsUnionAll();
570: }
571:
572: public boolean supportsUnique() {
573: return _dialect.supportsUnique();
574: }
575:
576: public boolean supportsUniqueConstraintInCreateAlterTable() {
577: return _dialect.supportsUniqueConstraintInCreateAlterTable();
578: }
579:
580: public boolean supportsVariableLimit() {
581: return _dialect.supportsVariableLimit();
582: }
583:
584: public String toBooleanValueString(boolean bool) {
585: return _dialect.toBooleanValueString(bool);
586: }
587:
588: public String toString() {
589: if (_dialect != null) {
590: return _dialect.toString();
591: } else {
592: return null;
593: }
594: }
595:
596: public String transformSelectString(String select) {
597: return _dialect.transformSelectString(select);
598: }
599:
600: public boolean useInputStreamToInsertBlob() {
601: return _dialect.useInputStreamToInsertBlob();
602: }
603:
604: public boolean useMaxForLimit() {
605: return _dialect.useMaxForLimit();
606: }
607:
608: private static Log _log = LogFactory.getLog(DynamicDialect.class);
609:
610: private Dialect _dialect;
611:
612: /** Added by AKA to avoid reference to other Liferay code
613: *
614: * @return
615: * @throws SQLException
616: */
617: public static Connection getConnection() throws SQLException {
618: // this own implementation of getting connection.
619: // we will try to get java connection from the string in configuration file
620: Properties props = new Properties();
621: try {
622: props.load(DynamicDialect.class.getClassLoader()
623: .getResourceAsStream("config.properties"));
624: } catch (IOException ioEx) {
625: _log.error("Cannot read EmForge Properties", ioEx);
626: return null;
627: }
628:
629: String connectionString = props.getProperty("datasource.url");
630:
631: // GlassFish used names like jdbc/__default as JNDI names
632: if (connectionString.startsWith("java")
633: || connectionString.startsWith("jdbc/")) {
634: // datasource name configured as JNDI
635: JndiObjectFactoryBean dsFactoryBean = new JndiObjectFactoryBean();
636: dsFactoryBean.setCache(false);
637: dsFactoryBean.setExpectedType(javax.sql.DataSource.class);
638: dsFactoryBean.setJndiName(connectionString);
639:
640: try {
641: dsFactoryBean.afterPropertiesSet();
642: } catch (NamingException nEx) {
643: _log.error(
644: "Cannot find JNDI name: " + connectionString,
645: nEx);
646: return null;
647: }
648:
649: DataSource ds = (DataSource) dsFactoryBean.getObject();
650:
651: return ds.getConnection();
652: } else {
653: try {
654: // this is normal JDBC connection String
655: Connection conn = DriverManager
656: .getConnection(connectionString);
657:
658: return conn;
659: } catch (Exception ex) {
660: _log.error("Cannot establish connection to :"
661: + connectionString, ex);
662: return null;
663: }
664: }
665: }
666:
667: }
|