/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.osgi.framework.BundleContext;
import org.teiid.core.designer.PluginUtil;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.PluginUtilImpl;
import org.teiid.designer.jdbc.metadata.Includes;
import org.teiid.designer.jdbc.metadata.JdbcDatabase;
import org.teiid.designer.jdbc.metadata.JdbcNode;
import org.teiid.designer.jdbc.metadata.JdbcNodeVisitor;
import org.teiid.designer.jdbc.metadata.impl.ImportSettingsSelectionVisitor;
import org.teiid.designer.jdbc.metadata.impl.JdbcDatabaseImpl;
import org.teiid.designer.jdbc.metadata.impl.JdbcNodeSelections;
/**
* @since 8.0
*/
public class JdbcPlugin extends Plugin {
/**
* The plug-in identifier of this plugin (value <code>"org.teiid.designer.jdbc"</code>).
*/
public static final String PLUGIN_ID = "org.teiid.designer.jdbc"; //$NON-NLS-1$
public static final String PACKAGE_ID = JdbcPlugin.class.getPackage().getName();
/**
* Provides access to the plugin's log and to it's resources.
*/
private static final String I18N_NAME = PACKAGE_ID + ".i18n"; //$NON-NLS-1$
public static final PluginUtil Util = new PluginUtilImpl(PLUGIN_ID, I18N_NAME, ResourceBundle.getBundle(I18N_NAME));
private static final ResourceLocator RESOURCE_LOCATOR = new ResourceLocator() {
@Override
public URL getBaseURL() {
if (INSTANCE != null) {
URL baseUrl;
try {
baseUrl = FileLocator.resolve(INSTANCE.getBundle().getEntry("/")); //$NON-NLS-1$
} catch (final IOException err) {
baseUrl = null;
}
return baseUrl;
}
try {
final URI uri = URI.createURI(getClass().getResource("plugin.properties").toString()); //$NON-NLS-1$
final URL baseUrl = new URL(uri.trimSegments(1).toString() + "/"); //$NON-NLS-1$
return baseUrl;
} catch (final IOException exception) {
throw new WrappedException(exception);
}
}
@Override
public Object getImage( final String key ) {
try {
final URL baseUrl = getBaseURL();
final URL url = new URL(baseUrl + "icons/" + key + ".gif"); //$NON-NLS-1$//$NON-NLS-2$
final InputStream inputStream = url.openStream();
inputStream.close();
return url;
} catch (final MalformedURLException exception) {
throw new WrappedException(exception);
} catch (final IOException exception) {
throw new MissingResourceException(
CommonPlugin.INSTANCE.getString("_UI_StringResourceNotFound_exception", new Object[] {key}), //$NON-NLS-1$
getClass().getName(), key);
}
}
@Override
public String getString( final String key ) {
return Util.getString(key);
}
@Override
public String getString( final String key,
final boolean translate ) {
return getString(key);
}
@Override
public String getString( final String key,
final Object[] substitutions ) {
return Util.getString(key, substitutions);
}
@Override
public String getString( final String key,
final Object[] substitutions,
final boolean translate ) {
return getString(key, substitutions);
}
};
static JdbcPlugin INSTANCE = null;
private static JdbcManagerImpl jdbcMgr;
public static boolean DEBUG = false;
/**
* Starts the manager for the {@link JdbcDriver} instances by loading the instances from the supplied model. This method is safe
* to call more than once; the method returns whether the manager was actually started.
*
* @return the JDBC manager (never <code>null</code>)
*/
public static JdbcManager getJdbcManager() {
if (JdbcPlugin.jdbcMgr == null) {
JdbcPlugin.jdbcMgr = new JdbcManagerImpl(Util.getString("jdbcManagerName")); //$NON-NLS-1$
JdbcPlugin.jdbcMgr.start();
}
return JdbcPlugin.jdbcMgr;
}
/**
* Method that obtains an existing {@link JdbcImportSettings} object from the supplied {@link JdbcSource source}, or creates a
* new {@link JdbcImportSettings} object if needed and sets the reference from the {@link JdbcSource source} to the
* {@link JdbcImportSettings settings}.
*
* @param source the JdbcSource that identifies the JDBC system and in which the node selections are to be recorded; may not be
* null
* @return the {@link JdbcImportSettings} object on the source; never null
*/
public static JdbcImportSettings ensureNonNullImportSettings( final JdbcSource source ) {
CoreArgCheck.isNotNull(source);
// Get (or create) the import settings on the source
JdbcImportSettings settings = source.getImportSettings();
if (settings == null) {
settings = JdbcFactory.eINSTANCE.createJdbcImportSettings();
source.setImportSettings(settings);
}
return settings;
}
/**
* Return the {@link JdbcDatabase} object that provides access to metadata and other information about the JDBC system described
* by the supplied {@link JdbcSource source} and {@link Connection connection}. Each time this method is called, a new
* {@link JdbcDatabase} object will be created, so care should be taken not to make duplicates as this is not efficient.
*
* @param source the JdbcSource that identifies the JDBC system; may not be null
* @param connection the JDBC Connection to the JDBC system; may not be null
* @return the new JdbcDatabase object
*/
public static JdbcDatabase getJdbcDatabase( final JdbcSource source,
final Connection connection ) {
CoreArgCheck.isNotNull(source);
CoreArgCheck.isNotNull(connection);
final JdbcNodeSelections selectionsCache = new JdbcNodeSelections();
// See if there are import settings ...
final JdbcImportSettings settings = source.getImportSettings();
if (settings != null) {
// Populate the selections cache with the what is in the settings
selectionsCache.initialize(settings);
}
// Determine whether there are any selections defined in the settings ...
final boolean existingSelections = selectionsCache.hasSelectionModes();
// Then create the JdbcDatabaseImpl (which may modify the selections)
final JdbcDatabaseImpl result = new JdbcDatabaseImpl(connection, source.getName(), selectionsCache);
if (!existingSelections) {
// There are no existing selections, so make the "default" selections
final IStatus status = result.selectDefaultNodes(source.getUsername());
if (status.getSeverity() == IStatus.ERROR) {
Util.log(status);
}
}
// Grab the "include" options off of the JdbcImportSettings ...
if (settings != null) {
final Includes includes = result.getIncludes();
final List includedTableTypes = settings.getIncludedTableTypes();
final String[] typesToInclude = (String[])includedTableTypes.toArray(new String[includedTableTypes.size()]);
includes.setIncludedTableTypes(typesToInclude);
includes.setApproximateIndexes(settings.isIncludeApproximateIndexes());
includes.setIncludeForeignKeys(settings.isIncludeForeignKeys());
includes.setIncludeIndexes(settings.isIncludeIndexes());
includes.setIncludeProcedures(settings.isIncludeProcedures());
includes.setUniqueIndexesOnly(settings.isIncludeUniqueIndexes());
}
return result;
}
/**
*
* @return the EMF ResourceLocator used when run as a plugin
*/
public static ResourceLocator getPluginResourceLocator() {
return RESOURCE_LOCATOR;
}
/**
* Method that records in the {@link JdbcSource source descriptor} the selected {@link JdbcNode nodes} in the supplied
* {@link JdbcDatabase database tree}. The selections are actually recorded in the {@link JdbcSource#getImportSettings()
* source's import settings}. Consequently, if the import settings
*
* @param source the JdbcSource that identifies the JDBC system and in which the node selections are to be recorded; may not be
* null
* @param database the JDBC database object tree whose selections are to be recorded; may not be null
* @throws JdbcException if there is an error visiting the database
*/
public static void recordJdbcDatabaseSelections( final JdbcSource source,
final JdbcDatabase database ) throws JdbcException {
CoreArgCheck.isNotNull(source);
CoreArgCheck.isNotNull(database);
// Get (or create) the import settings on the source
final JdbcImportSettings settings = ensureNonNullImportSettings(source);
// Use a visitor to navigate the database tree and record those selected nodes
final JdbcNodeVisitor visitor = new ImportSettingsSelectionVisitor(settings);
database.accept(visitor, JdbcNode.DEPTH_INFINITE);
}
/**
* @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
* @since 4.3.2
*/
@Override
public void start( final BundleContext context ) throws Exception {
super.start(context);
INSTANCE = this;
((PluginUtilImpl)Util).initializePlatformLogger(this); // This must be called to initialize the platform logger!
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception {
JdbcManager mgr = JdbcManagerImpl.get();
if ((mgr != null) && (mgr instanceof JdbcManagerImpl)) {
((JdbcManagerImpl)mgr).shutdown();
}
if (JdbcPlugin.jdbcMgr != null) {
JdbcPlugin.jdbcMgr.shutdown();
}
super.stop(context);
}
}