001: /*
002: * Copyright (C) 2006 Rob Manning
003: * manningr@users.sourceforge.net
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package net.sourceforge.squirrel_sql.fw.dialects;
020:
021: import java.io.PrintWriter;
022: import java.io.StringWriter;
023: import java.util.Arrays;
024: import java.util.Collection;
025: import java.util.HashMap;
026: import java.util.Set;
027:
028: import javax.swing.JFrame;
029: import javax.swing.JOptionPane;
030:
031: import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
032: import net.sourceforge.squirrel_sql.fw.util.StringManager;
033: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
034: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
035: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
036:
037: /**
038: * This class maps SQLDatabaseMetaData instances to their corresponding
039: * Hibernate dialect.
040: */
041: public class DialectFactory {
042:
043: /** this is used to indicate that the sesion is being copied from */
044: public static final int SOURCE_TYPE = 0;
045:
046: /** this is used to indicate that the sesion is being copied to */
047: public static final int DEST_TYPE = 1;
048:
049: /** Logger for this class. */
050: private final static ILogger s_log = LoggerController
051: .createLogger(DialectFactory.class);
052:
053: private static final AxionDialect axionDialect = new AxionDialect();
054:
055: private static final DB2Dialect db2Dialect = new DB2Dialect();
056:
057: // TODO: subclass these hibernate dialects to provide the "canPasteTo"
058: // api method in HibernateDialect interface.
059: //private static final DB2390Dialect db2390Dialect = new DB2390Dialect();
060:
061: //private static final DB2400Dialect db2400Dialect = new DB2400Dialect();
062:
063: private static final DaffodilDialect daffodilDialect = new DaffodilDialect();
064:
065: private static final DerbyDialect derbyDialect = new DerbyDialect();
066:
067: private static final FirebirdDialect firebirdDialect = new FirebirdDialect();
068:
069: private static final FrontBaseDialect frontbaseDialect = new FrontBaseDialect();
070:
071: private static final HADBDialect hadbDialect = new HADBDialect();
072:
073: private static final H2Dialect h2Dialect = new H2Dialect();
074:
075: private static final HSQLDialect hsqlDialect = new HSQLDialect();
076:
077: private static final InformixDialect informixDialect = new InformixDialect();
078:
079: private static final InterbaseDialect interbaseDialect = new InterbaseDialect();
080:
081: private static final IngresDialect ingresDialect = new IngresDialect();
082:
083: private static final MAXDBDialect maxDbDialect = new MAXDBDialect();
084:
085: private static final McKoiDialect mckoiDialect = new McKoiDialect();
086:
087: private static final MySQLDialect mysqlDialect = new MySQLDialect();
088:
089: private static final MySQL5Dialect mysql5Dialect = new MySQL5Dialect();
090:
091: private static final Oracle9iDialect oracle9iDialect = new Oracle9iDialect();
092:
093: private static final PointbaseDialect pointbaseDialect = new PointbaseDialect();
094:
095: private static final PostgreSQLDialect postgreSQLDialect = new PostgreSQLDialect();
096:
097: private static final ProgressDialect progressDialect = new ProgressDialect();
098:
099: private static final SybaseDialect sybaseDialect = new SybaseDialect();
100:
101: private static final SQLServerDialect sqlserverDialect = new SQLServerDialect();
102:
103: private static final TimesTenDialect timestenDialect = new TimesTenDialect();
104:
105: private static HashMap<String, HibernateDialect> dbNameDialectMap = new HashMap<String, HibernateDialect>();
106:
107: public static boolean isPromptForDialect = false;
108:
109: /** Internationalized strings for this class. */
110: private static final StringManager s_stringMgr = StringManagerFactory
111: .getStringManager(DialectFactory.class);
112:
113: /**
114: * The keys to dbNameDialectMap are displayed to the user in the dialect
115: * chooser widget, so be sure to use something that is intelligable to
116: * an end user
117: */
118: static {
119: dbNameDialectMap.put(axionDialect.getDisplayName(),
120: axionDialect);
121: dbNameDialectMap.put(db2Dialect.getDisplayName(), db2Dialect);
122: //dbNameDialectMap.put("DB2/390", db2390Dialect);
123: //dbNameDialectMap.put("DB2/400", db2400Dialect);
124: dbNameDialectMap.put(daffodilDialect.getDisplayName(),
125: daffodilDialect);
126: dbNameDialectMap.put(derbyDialect.getDisplayName(),
127: derbyDialect);
128: dbNameDialectMap.put(firebirdDialect.getDisplayName(),
129: firebirdDialect);
130: dbNameDialectMap.put(frontbaseDialect.getDisplayName(),
131: frontbaseDialect);
132: dbNameDialectMap.put(hadbDialect.getDisplayName(), hadbDialect);
133: dbNameDialectMap.put(hsqlDialect.getDisplayName(), hsqlDialect);
134: dbNameDialectMap.put(h2Dialect.getDisplayName(), h2Dialect);
135: dbNameDialectMap.put(informixDialect.getDisplayName(),
136: informixDialect);
137: dbNameDialectMap.put(ingresDialect.getDisplayName(),
138: ingresDialect);
139: dbNameDialectMap.put(interbaseDialect.getDisplayName(),
140: interbaseDialect);
141: dbNameDialectMap.put(maxDbDialect.getDisplayName(),
142: maxDbDialect);
143: dbNameDialectMap.put(mckoiDialect.getDisplayName(),
144: mckoiDialect);
145: dbNameDialectMap.put(sqlserverDialect.getDisplayName(),
146: sqlserverDialect);
147: dbNameDialectMap.put(mysqlDialect.getDisplayName(),
148: mysqlDialect);
149: dbNameDialectMap.put(oracle9iDialect.getDisplayName(),
150: oracle9iDialect);
151: dbNameDialectMap.put(pointbaseDialect.getDisplayName(),
152: pointbaseDialect);
153: dbNameDialectMap.put(postgreSQLDialect.getDisplayName(),
154: postgreSQLDialect);
155: dbNameDialectMap.put(progressDialect.getDisplayName(),
156: progressDialect);
157: dbNameDialectMap.put(sybaseDialect.getDisplayName(),
158: sybaseDialect);
159: dbNameDialectMap.put(timestenDialect.getDisplayName(),
160: timestenDialect);
161: }
162:
163: public static boolean isAxion(ISQLDatabaseMetaData md) {
164: return dialectSupportsProduct(md, axionDialect);
165: }
166:
167: public static boolean isDaffodil(ISQLDatabaseMetaData md) {
168: return dialectSupportsProduct(md, daffodilDialect);
169: }
170:
171: public static boolean isDB2(ISQLDatabaseMetaData md) {
172: return dialectSupportsProduct(md, db2Dialect);
173: }
174:
175: public static boolean isDerby(ISQLDatabaseMetaData md) {
176: return dialectSupportsProduct(md, derbyDialect);
177: }
178:
179: public static boolean isFirebird(ISQLDatabaseMetaData md) {
180: return dialectSupportsProduct(md, firebirdDialect);
181: }
182:
183: public static boolean isFrontBase(ISQLDatabaseMetaData md) {
184: return dialectSupportsProduct(md, frontbaseDialect);
185: }
186:
187: public static boolean isHADB(ISQLDatabaseMetaData md) {
188: return dialectSupportsProduct(md, hadbDialect);
189: }
190:
191: public static boolean isH2(ISQLDatabaseMetaData md) {
192: return dialectSupportsProduct(md, h2Dialect);
193: }
194:
195: public static boolean isHSQL(ISQLDatabaseMetaData md) {
196: return dialectSupportsProduct(md, hsqlDialect);
197: }
198:
199: public static boolean isInformix(ISQLDatabaseMetaData md) {
200: return dialectSupportsProduct(md, informixDialect);
201: }
202:
203: public static boolean isIngres(ISQLDatabaseMetaData md) {
204: return dialectSupportsProduct(md, ingresDialect);
205: }
206:
207: public static boolean isInterbase(ISQLDatabaseMetaData md) {
208: return dialectSupportsProduct(md, interbaseDialect);
209: }
210:
211: public static boolean isMaxDB(ISQLDatabaseMetaData md) {
212: return dialectSupportsProduct(md, maxDbDialect);
213: }
214:
215: public static boolean isMcKoi(ISQLDatabaseMetaData md) {
216: return dialectSupportsProduct(md, mckoiDialect);
217: }
218:
219: public static boolean isMSSQLServer(ISQLDatabaseMetaData md) {
220: return dialectSupportsProduct(md, sqlserverDialect);
221: }
222:
223: public static boolean isMySQL(ISQLDatabaseMetaData md) {
224: return dialectSupportsProduct(md, mysqlDialect);
225: }
226:
227: public static boolean isMySQL5(ISQLDatabaseMetaData md) {
228: return dialectSupportsProduct(md, mysql5Dialect);
229: }
230:
231: public static boolean isOracle(ISQLDatabaseMetaData md) {
232: return dialectSupportsProduct(md, oracle9iDialect);
233: }
234:
235: public static boolean isPointbase(ISQLDatabaseMetaData md) {
236: return dialectSupportsProduct(md, pointbaseDialect);
237: }
238:
239: public static boolean isPostgreSQL(ISQLDatabaseMetaData md) {
240: return dialectSupportsProduct(md, postgreSQLDialect);
241: }
242:
243: public static boolean isProgress(ISQLDatabaseMetaData md) {
244: return dialectSupportsProduct(md, progressDialect);
245: }
246:
247: public static boolean isSyBase(ISQLDatabaseMetaData md) {
248: return dialectSupportsProduct(md, sybaseDialect);
249: }
250:
251: public static boolean isTimesTen(ISQLDatabaseMetaData md) {
252: return dialectSupportsProduct(md, timestenDialect);
253: }
254:
255: /**
256: * Examines the driver class name from the specified session to see if it
257: * begins with any of the space-delimited string tokens in the specified
258: * nameToMatch.
259: *
260: * @param session the ISession to check
261: * @param nameToMatch a space-delimited string of driver class package
262: * prefixes
263: * @return true if there is a match of any string in the nameToMatch and
264: * the ISession's driver class name; false otherwise.
265: */
266: private static boolean dialectSupportsProduct(
267: ISQLDatabaseMetaData data, HibernateDialect dialect) {
268: boolean result = false;
269: if (data != null && dialect != null) {
270: try {
271: String productName = data.getDatabaseProductName();
272: String productVersion = data
273: .getDatabaseProductVersion();
274: result = dialect.supportsProduct(productName,
275: productVersion);
276: } catch (Exception e) {
277: s_log
278: .error("Encountered unexpected exception while attempting to "
279: + "determine database product name/version: "
280: + e.getMessage());
281: if (s_log.isDebugEnabled()) {
282: StringWriter s = new StringWriter();
283: PrintWriter p = new PrintWriter(s);
284: e.printStackTrace(p);
285: s_log.debug(s.getBuffer().toString());
286: }
287: }
288: }
289: return result;
290: }
291:
292: public static HibernateDialect getDialect(String dbName) {
293: return dbNameDialectMap.get(dbName);
294: }
295:
296: /**
297: *
298: * @param md
299: * @return
300: */
301: public static HibernateDialect getDialect(ISQLDatabaseMetaData md)
302: throws UnknownDialectException {
303: if (isAxion(md)) {
304: return axionDialect;
305: }
306: if (isDaffodil(md)) {
307: return daffodilDialect;
308: }
309: if (isDB2(md)) {
310: return db2Dialect;
311: }
312: if (isDerby(md)) {
313: return derbyDialect;
314: }
315: if (isFirebird(md)) {
316: return firebirdDialect;
317: }
318: if (isFrontBase(md)) {
319: return frontbaseDialect;
320: }
321: if (isHADB(md)) {
322: return hadbDialect;
323: }
324: if (isH2(md)) {
325: return h2Dialect;
326: }
327: if (isHSQL(md)) {
328: return hsqlDialect;
329: }
330: if (isInformix(md)) {
331: return informixDialect;
332: }
333: if (isIngres(md)) {
334: return ingresDialect;
335: }
336: if (isInterbase(md)) {
337: return ingresDialect;
338: }
339: if (isMaxDB(md)) {
340: return maxDbDialect;
341: }
342: if (isMcKoi(md)) {
343: return mckoiDialect;
344: }
345: if (isMySQL(md)) {
346: return mysqlDialect;
347: }
348: if (isMSSQLServer(md)) {
349: return sqlserverDialect;
350: }
351: if (isOracle(md)) {
352: return oracle9iDialect;
353: }
354: if (isPointbase(md)) {
355: return pointbaseDialect;
356: }
357: if (isPostgreSQL(md)) {
358: return postgreSQLDialect;
359: }
360: if (isProgress(md)) {
361: return progressDialect;
362: }
363: if (isSyBase(md)) {
364: return sybaseDialect;
365: }
366: if (isTimesTen(md)) {
367: return timestenDialect;
368: }
369: throw new UnknownDialectException();
370: }
371:
372: public static HibernateDialect getDialect(int sessionType,
373: JFrame parent, ISQLDatabaseMetaData md)
374: throws UserCancelledOperationException {
375: HibernateDialect result = null;
376:
377: // User doesn't wish for us to try to auto-detect the dest db.
378: if (isPromptForDialect) {
379: result = showDialectDialog(parent, sessionType);
380: } else {
381: try {
382: result = getDialect(md);
383: } catch (UnknownDialectException e) {
384: // Failed to detect the dialect that should be used. Ask the user.
385: result = showDialectDialog(parent, sessionType);
386: }
387: }
388: return result;
389: }
390:
391: /**
392: * Shows the user a dialog explaining that we failed to detect the dialect
393: * of the destination database, and we are offering the user the
394: * opportunity to pick one from our supported dialects list. If the user
395: * cancels this dialog, null is returned to indicate that the user doesn't
396: * wish to continue the paste operation.
397: *
398: * @param destSession
399: * @param sessionType TODO
400: * @return
401: */
402: private static HibernateDialect showDialectDialog(JFrame parent,
403: int sessionType) throws UserCancelledOperationException {
404: Object[] dbNames = getDbNames();
405: String chooserTitle = s_stringMgr
406: .getString("dialectChooseTitle");
407: String typeStr = null;
408: if (sessionType == SOURCE_TYPE) {
409: typeStr = s_stringMgr.getString("sourceSessionTypeName");
410: }
411: if (sessionType == DEST_TYPE) {
412: typeStr = s_stringMgr.getString("destSessionTypeName");
413: }
414: String message = s_stringMgr.getString(
415: "dialectDetectFailedMessage", typeStr);
416: if (isPromptForDialect) {
417: message = s_stringMgr.getString(
418: "autoDetectDisabledMessage", typeStr);
419: }
420: String dbName = (String) JOptionPane.showInputDialog(parent,
421: message, chooserTitle, JOptionPane.INFORMATION_MESSAGE,
422: null, dbNames, dbNames[0]);
423: if (dbName == null || "".equals(dbName)) {
424: throw new UserCancelledOperationException();
425: }
426: return dbNameDialectMap.get(dbName);
427: }
428:
429: /**
430: * Returns a list of Database server names that can be preented to the
431: * user whenever we want the user to pick a dialect.
432: *
433: * @return
434: */
435: public static Object[] getDbNames() {
436: Set<String> keyset = dbNameDialectMap.keySet();
437: Object[] keys = keyset.toArray();
438: Arrays.sort(keys);
439: return keys;
440: }
441:
442: /**
443: * Returns an array of HibernateDialect instances, one for each supported
444: * dialect.
445: *
446: * @return
447: */
448: public static Object[] getSupportedDialects() {
449: Collection<HibernateDialect> c = dbNameDialectMap.values();
450: return c.toArray();
451: }
452:
453: }
|