blob: 14b804328333a3c0bbee7684bd6d6a4ff6690f59 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Actuate Corporation - added use of default DatabaseRecognizer (BZ 253523),
* plus OSGi stop and restart usage support
* Actuate Corporation - fix for bug 304756
*******************************************************************************/
package org.eclipse.datatools.connectivity.sqm.internal.core.definition;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.datatools.connectivity.services.PluginResourceLocator;
import org.eclipse.datatools.connectivity.sqm.core.definition.DatabaseDefinition;
import org.eclipse.datatools.connectivity.sqm.core.definition.DatabaseDefinitionRegistry;
import org.eclipse.datatools.connectivity.sqm.core.definition.IDatabaseRecognizer;
import org.eclipse.datatools.connectivity.sqm.internal.core.RDBCorePlugin;
import org.eclipse.datatools.modelbase.sql.schema.Database;
import org.eclipse.emf.common.util.URI;
public final class DatabaseDefinitionRegistryImpl implements DatabaseDefinitionRegistry {
public static DatabaseDefinitionRegistry INSTANCE = new DatabaseDefinitionRegistryImpl();
private static final String uriPlatformScheme = "platform:/plugin"; //$NON-NLS-1$
public static DatabaseDefinitionRegistry getInstance() {
if( INSTANCE == null )
{
synchronized( DatabaseDefinitionRegistryImpl.class )
{
if( INSTANCE == null )
INSTANCE = new DatabaseDefinitionRegistryImpl();
}
}
return INSTANCE;
}
public static void releaseInstance() {
if( INSTANCE == null )
return; // nothing to release
synchronized( DatabaseDefinitionRegistryImpl.class )
{
INSTANCE = null;
}
}
private Collection recognizers = null;
private Map products = new TreeMap();
private Map connectibleProductVersions = new TreeMap();
public Iterator getProducts() {
return this.products.keySet().iterator();
}
public Iterator getConnectibleProducts() {
return this.connectibleProductVersions.keySet().iterator();
}
public Iterator getVersions(String product) {
Map versions = (Map) this.products.get(product);
if(versions == null) {
return new TreeMap().keySet().iterator();
}
else {
return versions.keySet().iterator();
}
}
public Iterator getConnectibleVersions(String product) {
Map versions = (Map) this.connectibleProductVersions.get(product);
if(versions == null) {
return new TreeMap().keySet().iterator();
}
else {
return versions.keySet().iterator();
}
}
public DatabaseDefinition getDefinition(Database database) {
return this.getDefinition(database.getVendor(), database.getVersion());
}
public DatabaseDefinition getDefinition(String product, String version) {
if (product == null) return null;
Map versions = (Map) this.products.get(product);
if(versions == null) {
return null;
}
else {
return (DatabaseDefinition) versions.get(version);
}
}
public DatabaseDefinition recognize(Connection connection) {
if(this.recognizers == null) {
synchronized( this ) {
if(this.recognizers == null)
loadRecognizers();
}
}
Iterator it = this.recognizers.iterator();
while(it.hasNext()) {
IDatabaseRecognizer recognizer = (IDatabaseRecognizer) it.next();
try {
DatabaseDefinition def = recognizer.recognize(connection);
if(def != null) return def;
}
catch(Exception e) {
IStatus status = new Status(IStatus.ERROR, RDBCorePlugin.getSymbolicName(), IStatus.ERROR,
"An exception was thrown from database recognizer " + recognizer.getClass().getName(), e); //$NON-NLS-1$
RDBCorePlugin.getDefault().getLog().log(status);
it.remove();
}
}
return null;
}
private DatabaseDefinitionRegistryImpl() {
URL modelURL = null;
IExtensionRegistry pluginRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = pluginRegistry.getExtensionPoint("org.eclipse.datatools.connectivity.sqm.core", "databaseDefinition"); //$NON-NLS-1$ //$NON-NLS-2$
IExtension[] extensions = extensionPoint.getExtensions();
for(int i=0; i<extensions.length; ++i) {
IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
for(int j=0; j<configElements.length; ++j) {
if(configElements[j].getName().equals("definition")) { //$NON-NLS-1$
String product = configElements[j].getAttribute("product"); //$NON-NLS-1$
String version = configElements[j].getAttribute("version"); //$NON-NLS-1$
String desc = configElements[j].getAttribute("description"); //$NON-NLS-1$
String allowsConnections = configElements[j].getAttribute("allowsConnections"); //$NON-NLS-1$
String productDisplayString = configElements[j].getAttribute("productDisplayString"); //$NON-NLS-1$
String versionDisplayString = configElements[j].getAttribute("versionDisplayString"); //$NON-NLS-1$
String modelLocation = configElements[j].getAttribute("file"); //$NON-NLS-1$
if( modelLocation.startsWith(uriPlatformScheme)) {
URI modelURI = URI.createURI(modelLocation);
try {
modelURL = new URL(modelURI.toString());
} catch (MalformedURLException e) {
IStatus status = new Status(IStatus.ERROR, RDBCorePlugin.getSymbolicName(), IStatus.ERROR,
"The error was detected when creating the model url for " + modelLocation + " in "+ product + " " +version, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
e);
RDBCorePlugin.getDefault().getLog().log(status);
}
}
else {
modelURL = modelLocation == null ?
null :
PluginResourceLocator.getPluginEntry( configElements[j], modelLocation );
}
DatabaseDefinitionImpl definition = new DatabaseDefinitionImpl(product, version, desc, productDisplayString, versionDisplayString, modelURL);
if(this.products.containsKey(product)) {
((Map) this.products.get(product)).put(version, definition);
}
else {
Map versions = new TreeMap();
versions.put(version, definition);
this.products.put(product, versions);
}
if ((allowsConnections == null) || (!allowsConnections.equals("false"))){ //$NON-NLS-1$
if(this.connectibleProductVersions.containsKey(product)) {
((Map) this.connectibleProductVersions.get(product)).put(version, definition);
}
else {
Map versions = new TreeMap();
versions.put(version, definition);
this.connectibleProductVersions.put(product, versions);
}
}
}
}
}
}
private void loadRecognizers() {
this.recognizers = new LinkedList();
IExtensionRegistry pluginRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = pluginRegistry.getExtensionPoint("org.eclipse.datatools.connectivity.sqm.core", "databaseRecognition"); //$NON-NLS-1$ //$NON-NLS-2$
IExtension[] extensions = extensionPoint.getExtensions();
for(int i=0; i<extensions.length; ++i) {
IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
boolean isDefaultRecognizer = false;
for(int j=0; j<configElements.length; ++j) {
if(configElements[j].getName().equals("recognizer")) { //$NON-NLS-1$
String className = configElements[j].getAttribute("class"); //$NON-NLS-1$
try {
IDatabaseRecognizer recognizer = (IDatabaseRecognizer) configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
this.recognizers.add(recognizer);
if( recognizer instanceof ConfigElementDatabaseRecognizer )
isDefaultRecognizer = true;
break; // expects only 1 recognizer element
}
catch(CoreException e) {
IStatus status = new Status(IStatus.ERROR, RDBCorePlugin.getSymbolicName(), IStatus.ERROR,
"The error was detected when creating the database recognizer " + className, e); //$NON-NLS-1$
RDBCorePlugin.getDefault().getLog().log(status);
}
}
}
if( isDefaultRecognizer )
continue; // has already loaded a ConfigElementDatabaseRecognizer for the extension
// adds the default database recognizer if extension has mapped JDBC product to DatabaseDefinition
try {
ConfigElementDatabaseRecognizer defaultRecognizer = new ConfigElementDatabaseRecognizer( extensions[i] );
if( defaultRecognizer.hasJdbcMappings() )
this.recognizers.add( defaultRecognizer );
}
catch( CoreException ex ) {
IStatus status = new Status(IStatus.ERROR, RDBCorePlugin.getSymbolicName(), IStatus.ERROR,
"The error was detected when creating default database recognizer.", ex); //$NON-NLS-1$
RDBCorePlugin.getDefault().getLog().log(status);
}
}
}
}