001: package net.sourceforge.squirrel_sql.plugins.db2;
002:
003: /*
004: * Copyright (C) 2007 Rob Manning
005: * manningr@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021:
022: import java.sql.SQLException;
023:
024: import net.sourceforge.squirrel_sql.client.IApplication;
025: import net.sourceforge.squirrel_sql.client.gui.session.ObjectTreeInternalFrame;
026: import net.sourceforge.squirrel_sql.client.gui.session.SQLInternalFrame;
027: import net.sourceforge.squirrel_sql.client.plugin.DefaultSessionPlugin;
028: import net.sourceforge.squirrel_sql.client.plugin.PluginException;
029: import net.sourceforge.squirrel_sql.client.plugin.PluginSessionCallback;
030: import net.sourceforge.squirrel_sql.client.session.IObjectTreeAPI;
031: import net.sourceforge.squirrel_sql.client.session.ISession;
032: import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.expanders.ITableIndexExtractor;
033: import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.expanders.ITableTriggerExtractor;
034: import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.expanders.TableWithChildNodesExpander;
035: import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs.DatabaseObjectInfoTab;
036: import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory;
037: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
038: import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
039: import net.sourceforge.squirrel_sql.fw.util.StringManager;
040: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
041: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
042: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
043: import net.sourceforge.squirrel_sql.plugins.db2.exp.DB2TableIndexExtractorImpl;
044: import net.sourceforge.squirrel_sql.plugins.db2.exp.DB2TableTriggerExtractorImpl;
045: import net.sourceforge.squirrel_sql.plugins.db2.exp.SchemaExpander;
046: import net.sourceforge.squirrel_sql.plugins.db2.tab.IndexDetailsTab;
047: import net.sourceforge.squirrel_sql.plugins.db2.tab.TableSourceTab;
048: import net.sourceforge.squirrel_sql.plugins.db2.tab.ProcedureSourceTab;
049: import net.sourceforge.squirrel_sql.plugins.db2.tab.SequenceDetailsTab;
050: import net.sourceforge.squirrel_sql.plugins.db2.tab.TriggerDetailsTab;
051: import net.sourceforge.squirrel_sql.plugins.db2.tab.TriggerSourceTab;
052: import net.sourceforge.squirrel_sql.plugins.db2.tab.UDFDetailsTab;
053: import net.sourceforge.squirrel_sql.plugins.db2.tab.UDFSourceTab;
054: import net.sourceforge.squirrel_sql.plugins.db2.tab.ViewSourceTab;
055:
056: /**
057: * The main controller class for the DB2 plugin.
058: *
059: * @author manningr
060: */
061: public class DB2Plugin extends DefaultSessionPlugin {
062:
063: private static final String JCC_DRIVER_NAME = "IBM DB2 JDBC Universal Driver Architecture";
064:
065: /** The product name that indicates we need to use os/400 queries */
066: private static final String OS_400_PRODUCT_NAME = "DB2 UDB for AS/400";
067:
068: private static final StringManager s_stringMgr = StringManagerFactory
069: .getStringManager(DB2Plugin.class);
070:
071: /** Logger for this class. */
072: private final static ILogger s_log = LoggerController
073: .createLogger(DB2Plugin.class);
074:
075: /** API for the Object Tree. */
076: private IObjectTreeAPI _treeAPI;
077:
078: static interface i18n {
079: //i18n[DB2Plugin.showUdfSource=Show UDF source]
080: String SHOW_UDF_SOURCE = s_stringMgr
081: .getString("DB2Plugin.showUdfSource");
082:
083: //i18n[DB2Plugin.showViewSource=Show view source]
084: String SHOW_VIEW_SOURCE = s_stringMgr
085: .getString("DB2Plugin.showViewSource");
086:
087: //i18n[DB2Plugin.showProcedureSource=Show procedure source]
088: String SHOW_PROCEDURE_SOURCE = s_stringMgr
089: .getString("DB2Plugin.showProcedureSource");
090:
091: //i18n[DB2Plugin.showTriggerSource=Show trigger source]
092: String SHOW_TRIGGER_SOURCE = s_stringMgr
093: .getString("DB2Plugin.showTriggerSource");
094:
095: }
096:
097: /**
098: * Return the internal name of this plugin.
099: *
100: * @return the internal name of this plugin.
101: */
102: public String getInternalName() {
103: return "db2";
104: }
105:
106: /**
107: * Return the descriptive name of this plugin.
108: *
109: * @return the descriptive name of this plugin.
110: */
111: public String getDescriptiveName() {
112: return "DB2 Plugin";
113: }
114:
115: /**
116: * Returns the current version of this plugin.
117: *
118: * @return the current version of this plugin.
119: */
120: public String getVersion() {
121: return "0.03";
122: }
123:
124: /**
125: * Returns the authors name.
126: *
127: * @return the authors name.
128: */
129: public String getAuthor() {
130: return "Rob Manning";
131: }
132:
133: /**
134: * Returns a comma separated list of other contributors.
135: *
136: * @return Contributors names.
137: */
138: public String getContributors() {
139: return "Christoph Schmitz, Tilmann Brenk";
140: }
141:
142: /**
143: * @see net.sourceforge.squirrel_sql.client.plugin.IPlugin#getChangeLogFileName()
144: */
145: public String getChangeLogFileName() {
146: return "changes.txt";
147: }
148:
149: /**
150: * @see net.sourceforge.squirrel_sql.client.plugin.IPlugin#getHelpFileName()
151: */
152: public String getHelpFileName() {
153: return "readme.html";
154: }
155:
156: /**
157: * @see net.sourceforge.squirrel_sql.client.plugin.IPlugin#getLicenceFileName()
158: */
159: public String getLicenceFileName() {
160: return "licence.txt";
161: }
162:
163: /**
164: * Load this plugin.
165: *
166: * @param app Application API.
167: */
168: public synchronized void load(IApplication app)
169: throws PluginException {
170: super .load(app);
171: }
172:
173: /**
174: * Initialize this plugin.
175: */
176: public synchronized void initialize() throws PluginException {
177: super .initialize();
178: }
179:
180: /**
181: * Application is shutting down so save preferences.
182: */
183: public void unload() {
184: super .unload();
185: }
186:
187: public boolean allowsSessionStartedInBackground() {
188: return true;
189: }
190:
191: /**
192: * Session has been started. Update the tree api in using the event thread
193: *
194: * @param session Session that has started.
195: *
196: * @return <TT>true</TT> if session is Oracle in which case this plugin
197: * is interested in it.
198: */
199: public PluginSessionCallback sessionStarted(final ISession session) {
200:
201: if (!isPluginSession(session)) {
202: return null;
203: }
204: GUIUtils.processOnSwingEventThread(new Runnable() {
205: public void run() {
206: updateTreeApi(session);
207: }
208: });
209:
210: // Install DB2JCCExceptionFormatter iff we're using the JCC driver
211: try {
212: if (JCC_DRIVER_NAME.equals(session.getMetaData()
213: .getJDBCMetaData().getDriverName())) {
214: session
215: .setExceptionFormatter(new DB2JCCExceptionFormatter());
216: }
217: } catch (SQLException e) {
218: s_log.error("Problem installing exception formatter: "
219: + e.getMessage());
220: }
221:
222: return new PluginSessionCallback() {
223: public void sqlInternalFrameOpened(
224: SQLInternalFrame sqlInternalFrame, ISession sess) {
225: // Supports Session main window only
226: }
227:
228: public void objectTreeInternalFrameOpened(
229: ObjectTreeInternalFrame objectTreeInternalFrame,
230: ISession sess) {
231: // Supports Session main window only
232: }
233: };
234:
235: }
236:
237: @Override
238: protected boolean isPluginSession(ISession session) {
239: return DialectFactory.isDB2(session.getMetaData());
240: }
241:
242: private void updateTreeApi(ISession session) {
243: String stmtSep = session.getQueryTokenizer()
244: .getSQLStatementSeparator();
245: boolean isOS400 = isOS400(session);
246:
247: _treeAPI = session.getSessionInternalFrame().getObjectTreeAPI();
248: _treeAPI.addDetailTab(DatabaseObjectType.PROCEDURE,
249: new ProcedureSourceTab(i18n.SHOW_PROCEDURE_SOURCE,
250: isOS400, stmtSep));
251: _treeAPI.addDetailTab(DatabaseObjectType.VIEW,
252: new ViewSourceTab(i18n.SHOW_VIEW_SOURCE, stmtSep,
253: isOS400));
254:
255: _treeAPI.addDetailTab(DatabaseObjectType.INDEX,
256: new DatabaseObjectInfoTab());
257: _treeAPI.addDetailTab(DatabaseObjectType.INDEX,
258: new IndexDetailsTab(isOS400));
259:
260: _treeAPI.addDetailTab(DatabaseObjectType.TRIGGER,
261: new DatabaseObjectInfoTab());
262: _treeAPI.addDetailTab(DatabaseObjectType.TRIGGER_TYPE_DBO,
263: new DatabaseObjectInfoTab());
264:
265: _treeAPI.addDetailTab(DatabaseObjectType.SEQUENCE,
266: new DatabaseObjectInfoTab());
267: _treeAPI.addDetailTab(DatabaseObjectType.SEQUENCE,
268: new SequenceDetailsTab(isOS400));
269:
270: _treeAPI.addDetailTab(DatabaseObjectType.UDF,
271: new DatabaseObjectInfoTab());
272: _treeAPI.addDetailTab(DatabaseObjectType.UDF, new UDFSourceTab(
273: i18n.SHOW_UDF_SOURCE, stmtSep, isOS400));
274: _treeAPI.addDetailTab(DatabaseObjectType.UDF,
275: new UDFDetailsTab(isOS400));
276:
277: _treeAPI
278: .addDetailTab(DatabaseObjectType.TABLE,
279: new TableSourceTab("Show MQT Source", stmtSep,
280: isOS400));
281:
282: // Expanders - trigger and index expanders are added inside the table
283: // expander
284: _treeAPI.addExpander(DatabaseObjectType.SCHEMA,
285: new SchemaExpander(isOS400));
286:
287: // Expanders - trigger and index expanders are added inside the table
288: // expander
289: TableWithChildNodesExpander tableExpander = new TableWithChildNodesExpander();
290:
291: //tableExpander.setTableIndexExtractor(extractor);
292: ITableIndexExtractor indexExtractor = new DB2TableIndexExtractorImpl(
293: isOS400);
294: tableExpander.setTableIndexExtractor(indexExtractor);
295:
296: ITableTriggerExtractor triggerExtractor = new DB2TableTriggerExtractorImpl(
297: isOS400);
298: tableExpander.setTableTriggerExtractor(triggerExtractor);
299:
300: _treeAPI.addExpander(DatabaseObjectType.TABLE, tableExpander);
301:
302: _treeAPI.addDetailTab(DatabaseObjectType.TRIGGER,
303: new TriggerDetailsTab());
304: _treeAPI.addDetailTab(DatabaseObjectType.TRIGGER,
305: new TriggerSourceTab(i18n.SHOW_TRIGGER_SOURCE, isOS400,
306: stmtSep));
307:
308: }
309:
310: /**
311: * Determines whether or not we've connected to DB2 on OS/400.
312: *
313: * @param session
314: * @return
315: */
316: private boolean isOS400(ISession session) {
317: boolean result = false;
318: try {
319: String prodName = session.getMetaData()
320: .getDatabaseProductName();
321: if (prodName == null || prodName.equals("")) {
322: s_log.info("isOS400: product name is null or empty. "
323: + "Assuming not an OS/400 DB2 session.");
324: } else if (prodName.equals(OS_400_PRODUCT_NAME)) {
325: s_log
326: .info("isOS400: session appears to be an OS/400 DB2");
327: result = true;
328: } else {
329: s_log
330: .info("isOS400: session doesn't appear to be an OS/400 DB2");
331: }
332: } catch (SQLException e) {
333: s_log.error(
334: "isOS400: unable to determine the product name: "
335: + e.getMessage(), e);
336: }
337: return result;
338: }
339: }
|