diff options
author | pfullbright | 2007-04-25 20:14:47 +0000 |
---|---|---|
committer | pfullbright | 2007-04-25 20:14:47 +0000 |
commit | aa104ed609e52f19bd20b90f841d34dde10497cd (patch) | |
tree | 06a37885d10b35004c01ad701f445bb4a7de246a /jpa/plugins | |
parent | 5a50ff3aeafeb18e74f2ae005e86953fb4e38ceb (diff) | |
download | webtools.dali-aa104ed609e52f19bd20b90f841d34dde10497cd.tar.gz webtools.dali-aa104ed609e52f19bd20b90f841d34dde10497cd.tar.xz webtools.dali-aa104ed609e52f19bd20b90f841d34dde10497cd.zip |
renamed
Diffstat (limited to 'jpa/plugins')
28 files changed, 3378 insertions, 0 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.db/.classpath b/jpa/plugins/org.eclipse.jpt.db/.classpath new file mode 100644 index 0000000000..751c8f2e50 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/jpa/plugins/org.eclipse.jpt.db/.cvsignore b/jpa/plugins/org.eclipse.jpt.db/.cvsignore new file mode 100644 index 0000000000..814c6a80a6 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/.cvsignore @@ -0,0 +1,3 @@ +bin +build.xml +javaCompiler...args
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.db/.project b/jpa/plugins/org.eclipse.jpt.db/.project new file mode 100644 index 0000000000..5675a48e3a --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.jpt.db</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/jpa/plugins/org.eclipse.jpt.db/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.db/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..2c83f77564 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-Vendor: %providerName +Bundle-SymbolicName: org.eclipse.jpt.db +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.jpt.db.internal.PersistenceDbPlugin +Bundle-ClassPath: . +Bundle-Localization: plugin +Eclipse-AutoStart: true +Export-Package: org.eclipse.jpt.db.internal +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.datatools.sqltools.editor.core, + org.eclipse.jpt.utility +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/jpa/plugins/org.eclipse.jpt.db/build.properties b/jpa/plugins/org.eclipse.jpt.db/build.properties new file mode 100644 index 0000000000..029f55f626 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/build.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2006 Oracle. +# 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: +# Oracle. - initial API and implementation +############################################################################### +javacSource=1.5 +javacTarget=1.5 +source.. = src/ +output.. = bin/ +bin.includes = .,\ + META-INF/,\ + plugin.properties +jars.compile.order = . diff --git a/jpa/plugins/org.eclipse.jpt.db/component.xml b/jpa/plugins/org.eclipse.jpt.db/component.xml new file mode 100644 index 0000000000..644c396149 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/component.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><component xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt.db"><description url=""></description><component-depends unrestricted="true"></component-depends><plugin id="org.eclipse.jpt.db" fragment="false"/></component>
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.db/plugin.properties b/jpa/plugins/org.eclipse.jpt.db/plugin.properties new file mode 100644 index 0000000000..e87a2d3972 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/plugin.properties @@ -0,0 +1,25 @@ +############################################################################### +# Copyright (c) 2006 Oracle. +# 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: +# Oracle. - initial API and implementation +############################################################################### +# ==================================================================== +# To code developer: +# Do NOT change the properties between this line and the +# "%%% END OF TRANSLATED PROPERTIES %%%" line. +# Make a new property name, append to the end of the file and change +# the code to use the new property. +# ==================================================================== + +# ==================================================================== +# %%% END OF TRANSLATED PROPERTIES %%% +# ==================================================================== + +pluginName = Java Persistence API Tools - DB +providerName = Eclipse.org + diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Catalog.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Catalog.java new file mode 100644 index 0000000000..4097b08014 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Catalog.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; + +/** + * Wrap a DTP Catalogs + */ +final class Catalog extends DTPWrapper { + private final Database database; + private final org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog; + private ICatalogObjectListener catalogListener; //TODO listen for change + + // ********** constructors ********** + + Catalog( Database database, org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog) { + super(); + this.database = database; + this.dtpCatalog = dtpCatalog; + } + + // ********** behavior ********** + + protected boolean connectionIsOnline() { + return this.database.connectionIsOnline(); + } + + private ICatalogObjectListener buildCatalogListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject catalog, final int eventType) { + if( catalog == Catalog.this.dtpCatalog) { +// Catalog.this.refresh(); +// Catalog.this.database.catalogChanged( Catalog.this, eventType); + } + } + }; + } + + protected void dispose() { +// this.removeCatalogObjectListener(( ICatalogObject) this.dtpCatalog, this.catalogListener); + } + + boolean wraps( org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog) { + return this.dtpCatalog == dtpCatalog; + } + + // ********** queries ********** + + public String getName() { + return this.dtpCatalog.getName(); + } + + boolean isCaseSensitive() { + return this.database.isCaseSensitive(); + } + + Column column( org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { + return this.database.column(dtpColumn); + } + + // ***** schemata + + synchronized Set buildSchemata() { + Collection dtpSchemata = this.dtpCatalog.getSchemas(); + + Set result = new HashSet( dtpSchemata.size()); + for( Iterator i = dtpSchemata.iterator(); i.hasNext(); ) { + result.add( this.wrap(( org.eclipse.datatools.modelbase.sql.schema.Schema)i.next())); + } + return result; + } + + private Schema wrap( org.eclipse.datatools.modelbase.sql.schema.Schema schema) { + + return new Schema( this.database, schema); + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Catalog)o).getName()); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Column.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Column.java new file mode 100644 index 0000000000..54ff56f94f --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Column.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.datatools.modelbase.sql.datatypes.DataType; +import org.eclipse.datatools.modelbase.sql.datatypes.PredefinedDataType; +import org.eclipse.jpt.utility.internal.JavaType; +import org.eclipse.jpt.utility.internal.NameTools; + +/** + * Wrap a DTP Column + */ +public final class Column extends DTPWrapper { + private final Table table; + private final org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn; + private ICatalogObjectListener columnListener; + + // TODO Object is the default? + private static final JavaType DEFAULT_JAVA_TYPE = new JavaType(java.lang.Object.class); + + // ********** constructors ********** + + Column( Table table, org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { + super(); + this.table = table; + this.dtpColumn = dtpColumn; + this.initialize(); + } + + // ********** behavior ********** + + private void initialize() { + if( this.connectionIsOnline()) { + this.columnListener = this.buildColumnListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpColumn, this.columnListener); + } + } + + protected boolean connectionIsOnline() { + return this.table.connectionIsOnline(); + } + + private ICatalogObjectListener buildColumnListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject column, final int eventType) { +// TODO +// if( column == Column.this.dtpColumn) { +// Column.this.table.columnChanged( Column.this, eventType); +// } + } + }; + } + + protected void dispose() { + + this.removeCatalogObjectListener(( ICatalogObject) this.dtpColumn, this.columnListener); + } + + // ********** queries ********** + + public String getName() { + return this.dtpColumn.getName(); + } + + boolean isCaseSensitive() { + return this.table.isCaseSensitive(); + } + + public String dataTypeName() { + DataType dataType = this.dtpColumn.getDataType(); + return (dataType == null) ? null : dataType.getName(); + } + + public String javaFieldName() { + String jName = this.getName(); + if ( ! this.isCaseSensitive()) { + jName = jName.toLowerCase(); + } + return NameTools.convertToJavaIdentifier(jName); + } + + public boolean matchesJavaFieldName(String javaFieldName) { + return this.isCaseSensitive() ? + this.getName().equals(javaFieldName) + : + this.getName().equalsIgnoreCase(javaFieldName); + } + + /** + * Return a Java type declaration that is reasonably + * similar to the column's data type. + */ + public String javaTypeDeclaration() { + return this.javaType().declaration(); + } + + /** + * Return a Java type that is reasonably + * similar to the column's data type. + */ + public JavaType javaType() { + DataType dataType = this.dtpColumn.getDataType(); + return (dataType instanceof PredefinedDataType) ? + DTPTools.javaTypeFor(((PredefinedDataType) dataType).getPrimitiveType()) + : + DEFAULT_JAVA_TYPE; + } + + boolean wraps( org.eclipse.datatools.modelbase.sql.tables.Column column) { + return this.dtpColumn == column; + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Column)o).getName()); + } +} + diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Connection.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Connection.java new file mode 100644 index 0000000000..e3ce55897c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Connection.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; + + +/** + * Connection wrapper base class. + */ +public abstract class Connection extends DTPWrapper { + + // ********** constructors ********** + + /** + * Create a wrapper for the given IManagedConnection. + */ + static Connection createConnection( org.eclipse.datatools.connectivity.IManagedConnection dtpConnection) { + return ( dtpConnection == null) ? NullConnection.instance() : new DTPConnectionWrapper( dtpConnection); + } + + Connection() { + super(); + } + + // ********** listeners ********** + + public abstract void addConnectionListener( ConnectionListener listener); + + public abstract void removeConnectionListener( ConnectionListener listener); + + + // ********** behavior ********** + + abstract void databaseChanged( Database database, int eventType); + + abstract void schemaChanged( Schema schema, Database database, int eventType); + + abstract void tableChanged( Table table, Schema schema, Database database, int eventType); + + + // ********** queries ********** + + public abstract boolean isConnected(); + + public abstract String getFactoryId(); + + protected boolean connectionIsOnline() { + return this.isConnected(); + } + + // ********** Comparable implementation ********** + + public int compareTo(Object o) { + return Collator.getInstance().compare( this.getName(), ((Connection)o).getName()); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionListener.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionListener.java new file mode 100644 index 0000000000..32528cf083 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + + +/** + * ConnectionListener integrate th DTP IManagedConnectionListener listener. + * This class purpose is to decouple from the DTP listeners by accepting wrappers as parameter. + * + * @see org.eclipse.datatools.connectivity.IManagedConnectionListener + */ +public interface ConnectionListener { + + public void opened( Connection connection); + public void modified( Connection connection); + public boolean okToClose( Connection connection); + public void aboutToClose( Connection connection); + public void closed( Connection connection); + + public void databaseChanged( Connection connection, Database database); + public void schemaChanged( Connection connection, Schema schema); + public void tableChanged( Connection connection, Table table); + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfile.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfile.java new file mode 100644 index 0000000000..91cc4a8934 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfile.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.NoSuchElementException; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; + +/** + * ConnectionProfile wrapper base class. + */ +public abstract class ConnectionProfile extends DTPWrapper { + + private Connection connection; // Lazy initialized + private Database database; // Lazy initialized + private String catalogName; // Catalog used for this profile + + private ConnectionListener connectionListener; + + private ConnectionProfileRepository profileRepository; + + // ********** constructors ********** + + static ConnectionProfile createProfile( ConnectionProfileRepository profileRepository, org.eclipse.datatools.connectivity.IConnectionProfile dtpProfile) { + return ( dtpProfile == null) ? NullConnectionProfile.instance() : new DTPConnectionProfileWrapper( profileRepository, dtpProfile); + } + + ConnectionProfile( ConnectionProfileRepository profileRepository) { + super(); + this.profileRepository = profileRepository; + this.connectionListener = buildConnectionListener(); + this.catalogName = ""; + } + + // ********** behavior ********** + + public abstract void connect(); + + public abstract void disconnect(); + + protected abstract Connection buildConnection(); + + protected abstract Database buildDatabase(); + + abstract void databaseChanged( Database database, int eventType); + + abstract void catalogChanged( Catalog catalog, Database database, int eventType); + + abstract void schemaChanged( Schema schema, Database database, int eventType); + + abstract void tableChanged( Table table, Schema schema, Database database, int eventType); + + protected void refreshDatabase() { + this.disposeDatabase(); + this.database = null; + } + + protected void dispose() { + this.disengageConnectionListener(); + + this.disposeConnection(); + this.disposeDatabase(); + } + + private void disposeConnection() { + if( this.connection != null) { + this.getConnection().dispose(); + } + } + + private void disposeDatabase() { + if( this.database != null) { + this.getDatabase().dispose(); + } + } + + // ********** queries ********** + + public Connection getConnection() { + + if( this.connection == null) { + this.connection = this.buildConnection(); + this.engageConnectionListener(); + + } + return this.connection; + } + + public Database getDatabase() { + + if( this.database == null) { + this.database = this.buildDatabase(); + this.setDefaultCatalogName(); + } + return this.database; + } + + public abstract String getDatabaseName(); + + public abstract String getDatabaseProduct(); + + public abstract String getDatabaseVendor(); + + public abstract String getDatabaseVersion(); + + public abstract String getUserName(); + + public abstract String getInstanceId(); + + public abstract String getProviderId(); + + public abstract boolean isConnected(); + + protected boolean connectionIsOnline() { + return this.isConnected(); + } + + abstract boolean wraps( org.eclipse.datatools.connectivity.IConnectionProfile dtpProfile); + + public boolean isNull() { + return true; + } + + ConnectionProfileRepository getProfileRepository() { + return this.profileRepository; + } + + public String getCatalogName() { + return this.catalogName; + } + + /** + * Set the default catalog name for this profile. + */ + public void setDefaultCatalogName() { + this.setCatalogName( this.database.getDefaultCatalogName()); + } + + /** + * Can only set the catalog to use for this profile, when the database supports catalogs. + */ + public void setCatalogName( String catalogName) { + if( this.catalogName == catalogName) { + return; + } + if( this.database.supportsCatalogs()) { + Catalog catalog = this.database.catalogNamed( catalogName); + if( catalog == null) { + throw new NoSuchElementException(); + } + this.catalogName = catalogName; + this.database.refresh(); + this.catalogChanged( catalog, this.database, ICatalogObjectListener.EventTypeEnumeration.ELEMENT_REFRESH); + } + else { + this.catalogName = ""; + this.database.refresh(); + } + } + + // ********** listeners ********** + + abstract public void addProfileListener( ProfileListener listener); + + abstract public void removeProfileListener( ProfileListener listener); + + abstract public void addConnectionListener( ConnectionListener listener); + + abstract public void removeConnectionListener( ConnectionListener listener); + + private ConnectionListener buildConnectionListener() { + return new ConnectionListener() { + + public void aboutToClose(Connection connection) { + // not interested to this event. + } + + public void closed(Connection connection) { + ConnectionProfile.this.refreshDatabase(); + } + + public void modified(Connection connection) { + // not interested to this event. + return; + } + + public boolean okToClose(Connection connection) { + // not interested to this event. + return true; + } + + public void opened(Connection connection) { + ConnectionProfile.this.refreshDatabase(); + } + + public void databaseChanged(Connection connection, final Database database) { + // not interested to this event. + return; + } + + public void schemaChanged(Connection connection, final Schema schema) { + // not interested to this event. + return; + } + + public void tableChanged(Connection connection, final Table table) { + // not interested to this event. + return; + } + }; + } + + protected void disengageConnectionListener() { + this.removeConnectionListener(); + } + + protected void engageConnectionListener() { + this.addConnectionListener(); + } + + private void addConnectionListener() { + this.addConnectionListener( this.connectionListener); + } + + private void removeConnectionListener() { + this.removeConnectionListener( this.connectionListener); + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( ConnectionProfile)o).getName()); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfileRepository.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfileRepository.java new file mode 100644 index 0000000000..e23c37572c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ConnectionProfileRepository.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import org.eclipse.datatools.connectivity.IConnectionProfile; +import org.eclipse.datatools.connectivity.IProfileListener; +import org.eclipse.datatools.connectivity.ProfileManager; +import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; + +/** + * ConnectionProfileRepository is a mediator to the DTP ProfileManager. + */ +public class ConnectionProfileRepository { + private ProfileManager dtpProfileManager; + + private LocalRepositoryListener repositoryListener; + private LocalProfileListener profileListener; + private Set profiles; + + private static ConnectionProfileRepository INSTANCE; + + public static final String DATABASE_CATEGORY_ID = "org.eclipse.datatools.connectivity.db.category"; //$NON-NLS-1$ + + /** + * singleton support + */ + public static ConnectionProfileRepository instance() { + if (INSTANCE == null) { + INSTANCE = new ConnectionProfileRepository(); + } + return INSTANCE; + } + + // ********** constructors ********** + + private ConnectionProfileRepository() { + super(); + this.dtpProfileManager = ProfileManager.getInstance(); + } + + // ********** behavior ********** + + public void initializeListeners() { + + if( this.repositoryListener == null) { + this.repositoryListener = new LocalRepositoryListener(); + this.dtpProfileManager.addProfileListener( this.repositoryListener); + } + if( this.profileListener == null) { + this.profileListener = new LocalProfileListener(); + this.dtpProfileManager.addProfileListener( this.profileListener); + } + } + + public void disposeListeners() { + for( Iterator i = profiles(); i.hasNext(); ) { + (( ConnectionProfile) i.next()).dispose(); + } + if( this.repositoryListener != null) { + this.dtpProfileManager.removeProfileListener( this.repositoryListener); + this.repositoryListener = null; + } + if( this.profileListener != null) { + this.dtpProfileManager.removeProfileListener( this.profileListener); + this.profileListener = null; + } + } + + public Connection getConnectionWithProfileNamed( String name) { + return this.profileNamed( name).getConnection(); + } + + + public String toString() { + return this.profiles.toString(); + } + + // ********** profiles + + public Iterator profiles() { + return this.getProfiles().iterator(); + } + + public Iterator profileNames() { + return new TransformationIterator( this.profiles()) { + protected Object transform( Object next) { + return (( ConnectionProfile)next).getName(); + } + }; + } + + public ConnectionProfile profileNamed( String name) { + for( Iterator stream = this.profiles(); stream.hasNext(); ) { + ConnectionProfile profile = ( ConnectionProfile) stream.next(); + if( profile.getName().equals( name)) { + return profile; + } + } + return NullConnectionProfile.instance(); + } + + private Set getProfiles() { + + if( this.profiles == null) { + this.profiles = this.buildProfiles(); + } + return this.profiles; + } + + private Set buildProfiles() { + IConnectionProfile[] profiles = this.dtpProfileManager.getProfiles(); + Set result = new HashSet( profiles.length); + for( int i = profiles.length; i-- > 0; ) { + result.add( ConnectionProfile.createProfile( this, profiles[i])); + } + return result; + } + + private void addProfile( IConnectionProfile dtpProfile) { + + if( !this.profileExists( dtpProfile)) { + ConnectionProfile newProfile = ConnectionProfile.createProfile( ConnectionProfileRepository.this, dtpProfile); + this.profiles.add( newProfile); + } + } + + private void removeProfile( IConnectionProfile dtpProfile) { + + this.profiles.remove( this.getProfile( dtpProfile)); + } + + private boolean profileExists( IConnectionProfile dtpProfile) { + + return ( this.getProfile( dtpProfile) == null) ? false : true; + } + + private ConnectionProfile getProfile( IConnectionProfile dtpProfile) { + + for( Iterator i = this.profiles(); i.hasNext(); ) { + ConnectionProfile profile = ( ConnectionProfile)i.next(); + if( profile.wraps( dtpProfile)) { + return profile; + } + } + return null; + } + + // ********** listeners ********** + + public void addProfileListener( ProfileListener listener) { + + this.profileListener.addProfileListener( listener); + } + + public void removeProfileListener( ProfileListener listener) { + + this.profileListener.removeProfileListener( listener); + } + + private void addInternalProfileListener( IProfileListener listener) { + + this.dtpProfileManager.addProfileListener( listener); + } + + private void removeInternalProfileListener( IProfileListener listener) { + + this.dtpProfileManager.removeProfileListener( listener); + } + + // ********** member class ********** + /** + * Listens to ProfileManager events and updates the repository. + */ + private class LocalRepositoryListener implements IProfileListener { + + public void profileAdded( IConnectionProfile connectionProfile) { + ConnectionProfileRepository.this.addProfile( connectionProfile); + } + + public void profileChanged( IConnectionProfile connectionProfile) { + // do nothing + } + + public void profileDeleted( IConnectionProfile connectionProfile) { + ConnectionProfileRepository.this.removeProfile( connectionProfile); + } + } + + + /** + * This listener translates and forwards IProfileListener events to ProfileListener. + */ + private class LocalProfileListener implements IProfileListener { + private Collection listeners = new ArrayList(); + + void addProfileListener( ProfileListener listener) { + this.listeners.add( listener); + } + + void removeProfileListener( ProfileListener listener) { + this.listeners.remove( listener); + } + + // ********** behavior ********** + + public void profileAdded( IConnectionProfile dtpProfile) { + ConnectionProfile profile = getProfile( dtpProfile); + for( Iterator j = listeners.iterator(); j.hasNext(); ) { + (( ProfileListener)j.next()).profileAdded( profile); + } + } + + public void profileChanged( IConnectionProfile dtpProfile) { + ConnectionProfile profile = getProfile( dtpProfile); + for( Iterator j = listeners.iterator(); j.hasNext(); ) { + (( ProfileListener)j.next()).profileChanged( profile); + } + } + + public void profileDeleted( IConnectionProfile dtpProfile) { + String profileName = dtpProfile.getName(); + for( Iterator j = listeners.iterator(); j.hasNext(); ) { + (( ProfileListener)j.next()).profileDeleted( profileName); + } + } + } +} + + diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java new file mode 100644 index 0000000000..f570999001 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionProfileWrapper.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.util.Properties; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.datatools.connectivity.IManagedConnection; +import org.eclipse.datatools.connectivity.db.generic.IDBDriverDefinitionConstants; +import org.eclipse.datatools.sqltools.core.DatabaseIdentifier; +import org.eclipse.datatools.sqltools.core.profile.ProfileUtil; + +/** + * Wrap a DTP ConnectionProfile + */ +public final class DTPConnectionProfileWrapper extends ConnectionProfile { + + final private org.eclipse.datatools.connectivity.IConnectionProfile dtpConnectionProfile; + + public static final String CONNECTION_TYPE = "java.sql.Connection"; //$NON-NLS-1$ + public static final String CONNECTION_PROFILE_TYPE = "org.eclipse.datatools.connectivity.db.generic.connectionProfile"; //$NON-NLS-1$ + public static final String DATABASE_PRODUCT_PROPERTY = "org.eclipse.datatools.connectivity.server.version"; //$NON-NLS-1$ + /** + * This property is used in ConnectionProfile creation. + */ + public static final String DATABASE_SAVE_PWD_PROP_ID = IDBDriverDefinitionConstants.PROP_PREFIX + "savePWD"; //$NON-NLS-1$ + /** + * This property is used in ConnectionProfile creation. + */ + public static final String DRIVER_DEFINITION_PROP_ID = "org.eclipse.datatools.connectivity.driverDefinitionID"; //$NON-NLS-1$ + /** + * This property is used in DriverDefinition creation. + */ + public static final String DRIVER_DEFINITION_TYPE_PROP_ID = "org.eclipse.datatools.connectivity.drivers.defnType"; //$NON-NLS-1$ + /** + * This property is used in DriverDefinition creation. + */ + public static final String DRIVER_JAR_LIST_PROP_ID = "jarList"; //$NON-NLS-1$ + + // ********** constructors ********** + + DTPConnectionProfileWrapper( ConnectionProfileRepository profileRepository, org.eclipse.datatools.connectivity.IConnectionProfile dtpConnectionProfile) { + super( profileRepository); + this.dtpConnectionProfile = dtpConnectionProfile; + } + + // ********** listeners ********** + + public void addProfileListener( ProfileListener listener) { + + this.getProfileRepository().addProfileListener( listener); + } + + public void removeProfileListener( ProfileListener listener) { + + this.getProfileRepository().removeProfileListener( listener); + } + + public void addConnectionListener( ConnectionListener listener) { + + this.getConnection().addConnectionListener( listener); + } + + public void removeConnectionListener( ConnectionListener listener) { + + this.getConnection().removeConnectionListener( listener); + } + + // ********** behavior ********** + + private IManagedConnection buildDtpManagedConnection( org.eclipse.datatools.connectivity.IConnectionProfile dtpProfile) { + return dtpProfile.getManagedConnection( CONNECTION_TYPE); + } + /** + * Connect using this profile. + */ + public void connect() { + if( !this.dtpConnectionProfile.isConnected()) { + + IStatus status = this.dtpConnectionProfile.connect(); + if( !status.isOK()) { + if( status.isMultiStatus()) { + IStatus[] statusChildren = status.getChildren(); + throw new RuntimeException( statusChildren[ 0].getMessage(), statusChildren[ 0].getException()); + } + else { + throw new RuntimeException( status.getMessage(), status.getException()); + } + } + } + } + + public void disconnect() { + + IStatus status = this.dtpConnectionProfile.disconnect(); + if( !status.isOK()) { + if( status.isMultiStatus()) { + IStatus[] statusChildren = status.getChildren(); + throw new RuntimeException( statusChildren[ 0].getMessage(), statusChildren[ 0].getException()); + } + else { + throw new RuntimeException( status.getMessage(), status.getException()); + } + } + } + + void databaseChanged( Database database, int eventType) { + this.getConnection().databaseChanged( database, eventType); + return; + } + + void catalogChanged( Catalog catalog, Database database, int eventType) { + //TODO +// this.getConnection().catalogChanged( catalog, eventType); + return; + } + + void schemaChanged( Schema schema, Database database, int eventType) { + this.getConnection().schemaChanged( schema, database, eventType); + } + + void tableChanged( Table table, Schema schema, Database database, int eventType) { + this.getConnection().tableChanged( table, schema, database, eventType); + } + + // ********** queries ********** + + public boolean isConnected() { + + return this.getConnection().isConnected(); + } + + public boolean isNull() { + return false; + } + + public String getName() { + + return this.dtpConnectionProfile.getName(); + } + + public String getDatabaseName() { + return this.getProperties().getProperty( IDBDriverDefinitionConstants.DATABASE_NAME_PROP_ID); + } + + public String getDatabaseProduct() { + return this.getProperties().getProperty( DATABASE_PRODUCT_PROPERTY); + } + + public String getDatabaseVendor() { + return this.getProperties().getProperty( IDBDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID); + } + + public String getDatabaseVersion() { + return this.getProperties().getProperty( IDBDriverDefinitionConstants.DATABASE_VERSION_PROP_ID); + } + + public String getUserName() { + return this.getProperties().getProperty( IDBDriverDefinitionConstants.USERNAME_PROP_ID); + } + + public String getInstanceId() { + return this.dtpConnectionProfile.getInstanceID(); + } + + public String getProviderId() { + return this.dtpConnectionProfile.getProviderId(); + } + + private Properties getProperties() { + return this.dtpConnectionProfile.getBaseProperties(); + } + + protected Connection buildConnection() { + + Connection connection = Connection.createConnection( this.buildDtpManagedConnection( this.dtpConnectionProfile)); //$NON-NLS-1$ + return connection; + } + + protected Database buildDatabase() { + + org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase; + if( this.isConnected()) { + dtpDatabase = ProfileUtil.getDatabase( new DatabaseIdentifier( this.getName(), this.getDatabaseName()), false); + return Database.createDatabase( this, dtpDatabase); + } + else { + return NullDatabase.instance(); + } + } + + boolean wraps( org.eclipse.datatools.connectivity.IConnectionProfile dtpProfile) { + return this.dtpConnectionProfile == dtpProfile; + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionWrapper.java new file mode 100644 index 0000000000..3454754994 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPConnectionWrapper.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Vector; +import org.eclipse.datatools.connectivity.ConnectEvent; +import org.eclipse.datatools.connectivity.IManagedConnectionListener; + +/** + * Wrap a DTP Connection + */ +public final class DTPConnectionWrapper extends Connection { + + final private org.eclipse.datatools.connectivity.IManagedConnection dtpConnection; + private LocalConnectionListener connectionListener; + + // ********** constructors ********** + + DTPConnectionWrapper( org.eclipse.datatools.connectivity.IManagedConnection dtpConnection) { + super(); + this.dtpConnection = dtpConnection; + this.initialize(); + } + + // ********** behavior ********** + + protected void initialize() { + this.connectionListener = new LocalConnectionListener(); + this.dtpConnection.addConnectionListener( this.connectionListener); + } + + protected void dispose() { + this.dtpConnection.removeConnectionListener( this.connectionListener); + } + + public String getName() { + + return this.dtpConnection.getConnection().getConnectionProfile().getName(); + } + + public boolean isConnected() { + + return this.dtpConnection.isConnected(); + } + + public String getFactoryId() { + + return this.dtpConnection.getFactoryID(); + } + + void databaseChanged( Database database, int eventType) { + + this.connectionListener.databaseChanged( database, eventType); + } + + void schemaChanged( Schema schema, Database database, int eventType) { + + this.connectionListener.schemaChanged( schema, database, eventType); + } + + void tableChanged( Table table, Schema schema, Database database, int eventType) { + + this.connectionListener.tableChanged( table, schema, database, eventType); + } + + // ********** listeners ********** + + public void addConnectionListener( ConnectionListener listener) { + // hook up the specified listener to our intermediate listeners + this.connectionListener.addConnectionListener( listener); + } + + public void removeConnectionListener( ConnectionListener listener) { + + this.connectionListener.removeConnectionListener( listener); + } + + // ********** member classes ********** + + /** + * This listener translates and forwards IManagedConnectionListener events to ConnectionListeners. + */ + private class LocalConnectionListener implements IManagedConnectionListener { + private Collection listeners = new Vector(); + + void addConnectionListener( ConnectionListener listener) { + this.listeners.add( listener); + } + + void removeConnectionListener( ConnectionListener listener) { + this.listeners.remove( listener); + } + + // ********** behavior ********** + + public void aboutToClose( ConnectEvent event) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).aboutToClose( DTPConnectionWrapper.this); + } + } + + public void closed( ConnectEvent event) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).closed( DTPConnectionWrapper.this); + } + } + + public void modified( ConnectEvent event) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).modified( DTPConnectionWrapper.this); + } + } + + public boolean okToClose( ConnectEvent event) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + if( !(( ConnectionListener)i.next()).okToClose( DTPConnectionWrapper.this)) { + return false; + } + } + return true; + } + + public void opened( ConnectEvent event) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).opened( DTPConnectionWrapper.this); + } + } + + void databaseChanged( Database database, int eventType) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).databaseChanged( DTPConnectionWrapper.this, database); + } + } + + void schemaChanged( Schema schema, Database database, int eventType) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).schemaChanged( DTPConnectionWrapper.this, schema); + } + } + + void tableChanged( Table table, Schema schema, Database database, int eventType) { + for( Iterator i = listeners.iterator(); i.hasNext(); ) { + (( ConnectionListener)i.next()).tableChanged( DTPConnectionWrapper.this, table); + } + } + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java new file mode 100644 index 0000000000..aa3bd9f19f --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPDatabaseWrapper.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.emf.common.util.EList; + +/** + * Wrap a DTP Database + */ +public final class DTPDatabaseWrapper extends Database { + + final private ConnectionProfile profile; + final private org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase; + private ICatalogObjectListener databaseListener; + + private Set catalogs; // lazy-initialized + private Set schemata; // lazy-initialized + + DTPDatabaseWrapper( ConnectionProfile profile, org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase) { + super(); + this.dtpDatabase = dtpDatabase; + this.profile = profile; + this.initialize(); + } + + // ********** behavior ********** + + private void initialize() { + + if( this.connectionIsOnline()) { + this.databaseListener = this.buildDatabaseListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpDatabase, this.databaseListener); + } + } + + protected boolean connectionIsOnline() { + return this.profile.isConnected(); + } + + private ICatalogObjectListener buildDatabaseListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject database, final int eventType) { + if( database == DTPDatabaseWrapper.this.dtpDatabase) { + DTPDatabaseWrapper.this.refresh(); + DTPDatabaseWrapper.this.profile.databaseChanged( DTPDatabaseWrapper.this, eventType); + } + } + }; + } + + void refresh() { + this.disposeSchemata(); + this.disposeCatalogs(); + + this.schemata = null; + this.catalogs = null; + } + + void catalogChanged( Catalog catalog, int eventType) { + this.profile.catalogChanged( catalog, this, eventType); + return; + } + + void schemaChanged( Schema schema, int eventType) { + this.profile.schemaChanged( schema, this, eventType); + return; + } + + void tableChanged( Table table, Schema schema, int eventType) { + this.profile.tableChanged( table, schema, this, eventType); + return; + } + + protected void dispose() { + this.removeCatalogObjectListener(( ICatalogObject) this.dtpDatabase, this.databaseListener); + + this.disposeSchemata(); + this.disposeCatalogs(); + } + + private void disposeSchemata() { + if( this.schemata != null) { + for( Iterator i = this.schemata(); i.hasNext(); ) { + (( Schema)i.next()).dispose(); + } + } + } + + private void disposeCatalogs() { + if( this.catalogs != null) { + for( Iterator i = this.catalogs(); i.hasNext(); ) { + (( Catalog)i.next()).dispose(); + } + } + } + + // ********** queries ********** + + public String getName() { + + return this.dtpDatabase.getName(); + } + + public String getVendor() { + + return this.dtpDatabase.getVendor(); + } + + public String getVersion() { + + return this.dtpDatabase.getVersion(); + } + + + // ***** schemata + + synchronized Set getSchemata() { + if( this.schemata == null) { + this.schemata = this.buildSchemata(); + } + return this.schemata; + } + + private Set buildSchemata() { + Set result; + if( this.supportsCatalogs()) { + result = this.getSchemataForCatalogNamed( this.profile.getCatalogName()); + } + else { + EList dtpSchemata = this.dtpDatabase.getSchemas(); + result = new HashSet( dtpSchemata.size()); + for( Iterator i = dtpSchemata.iterator(); i.hasNext(); ) { + result.add( this.wrap(( org.eclipse.datatools.modelbase.sql.schema.Schema)i.next())); + } + } + return result; + } + + // ***** catalogs + + public boolean supportsCatalogs() { + EList schemata = this.dtpDatabase.getSchemas(); + return ( schemata == null || schemata.size() == 0); + } + + @Override + public String getDefaultCatalogName() { + + if( !this.supportsCatalogs()) { // this database doesn't support catalogs + return ""; + } + else { + String userName = this.profile.getUserName(); + List dtpCatalogs = this.dtpDatabase.getCatalogs(); + for( Iterator i = dtpCatalogs.iterator(); i.hasNext(); ) { + org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog = ( org.eclipse.datatools.modelbase.sql.schema.Catalog)i.next(); + if( dtpCatalog.getName().length() == 0) { // special catalog that contains all schemata + return ""; + } + else if( dtpCatalog.getName().equals( userName)) { + return userName; // returns user name as default catalog + } + } + throw new NoSuchElementException(); + } + } + + synchronized Set getCatalogs() { + if( this.catalogs == null) { + this.catalogs = this.buildCatalogs(); + } + return this.catalogs; + } + + private Set buildCatalogs() { + + EList dtpCatalogs = this.dtpDatabase.getCatalogs(); + if( dtpCatalogs == null) { + return Collections.emptySet(); + } + Set result = new HashSet( dtpCatalogs.size()); + for( Iterator i = dtpCatalogs.iterator(); i.hasNext(); ) { + result.add( this.wrap(( org.eclipse.datatools.modelbase.sql.schema.Catalog)i.next())); + } + return result; + } + + //TODO case insensitive search + // + private Set getSchemataForCatalogNamed( String catalogName) { + + Catalog catalog = this.catalogNamed( catalogName); + return ( catalog != null) ? catalog.buildSchemata() : Collections.emptySet(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTools.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTools.java new file mode 100644 index 0000000000..c16a56cd56 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPTools.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.sql.Types; +import java.util.HashMap; +import org.eclipse.datatools.modelbase.sql.datatypes.PrimitiveType; +import org.eclipse.jpt.utility.internal.JDBCTools; +import org.eclipse.jpt.utility.internal.JDBCType; +import org.eclipse.jpt.utility.internal.JavaType; + +/** + * Helper methods for dealing with Eclipse DTP. + */ +public final class DTPTools { + + /** + * Return the JDBC type corresponding to the specified Primitive type. + */ + public static JDBCType jdbcTypeForPrimitiveTypeNamed(String primitiveTypeName) { + PrimitiveToJDBCTypeMapping mapping = primitiveToJDBCTypeMapping(primitiveTypeName); + return (mapping == null) ? DEFAULT_JDBC_TYPE : mapping.getJDBCType(); + } + + /** + * Return the JDBC type corresponding to the specified Primitive type. + */ + public static JDBCType jdbcTypeFor(PrimitiveType primitiveType) { + return jdbcTypeForPrimitiveTypeNamed(primitiveType.getName()); + } + + /** + * Return the JDBC type corresponding to the specified Primitive type. + */ + public static JDBCType jdbcTypeForPrimitiveTypeCode(int primitiveTypeCode) { + return jdbcTypeFor(PrimitiveType.get(primitiveTypeCode)); + } + + /** + * Return the Java type corresponding to the specified Primitive type. + */ + public static JavaType javaTypeForPrimitiveTypeNamed(String primitiveTypeName) { + return JDBCTools.javaTypeFor(jdbcTypeForPrimitiveTypeNamed(primitiveTypeName)); + } + + /** + * Return the Java type corresponding to the specified Primitive type. + */ + public static JavaType javaTypeFor(PrimitiveType primitiveType) { + return JDBCTools.javaTypeFor(jdbcTypeFor(primitiveType)); + } + + /** + * Return the Java type corresponding to the specified Primitive type. + */ + public static JavaType javaTypeForPrimitiveTypeCode(int primitiveTypeCode) { + return JDBCTools.javaTypeFor(jdbcTypeForPrimitiveTypeCode(primitiveTypeCode)); + } + + + // ********** internal stuff ********** + + + // ********** DTP Primitive => JDBC ********** + + /** + * Primitive => JDBC type mappings, keyed by Primitive type name (e.g. "CHARACTER_VARYING") + */ + private static HashMap PRIMITIVE_TO_JDBC_TYPE_MAPPINGS; // pseudo 'final' - lazy-initialized + private static final JDBCType DEFAULT_JDBC_TYPE = JDBCType.type(Types.VARCHAR); // TODO VARCHAR is the default? + + + private static PrimitiveToJDBCTypeMapping primitiveToJDBCTypeMapping(String primitiveTypeName) { + return (PrimitiveToJDBCTypeMapping) primitiveToJDBCTypeMappings().get(primitiveTypeName); + } + + private static synchronized HashMap primitiveToJDBCTypeMappings() { + if (PRIMITIVE_TO_JDBC_TYPE_MAPPINGS == null) { + PRIMITIVE_TO_JDBC_TYPE_MAPPINGS = buildPrimitiveToJDBCTypeMappings(); + } + return PRIMITIVE_TO_JDBC_TYPE_MAPPINGS; + } + + private static HashMap buildPrimitiveToJDBCTypeMappings() { + HashMap mappings = new HashMap(); + addPrimitiveToJDBCTypeMappingsTo(mappings); + return mappings; + } + + /** + * hard code the default mappings from the DTP primitive types to the + * appropriate JDBC types; + * pretty much a straight one-to-one mapping based on similar names; + * TODO some JDBC types are missing: INTERVAL, XML_TYPE + */ + private static void addPrimitiveToJDBCTypeMappingsTo(HashMap mappings) { + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.BIGINT_LITERAL, Types.BIGINT, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.BINARY_LARGE_OBJECT_LITERAL, Types.BLOB, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.BINARY_LITERAL, Types.BINARY, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.BINARY_VARYING_LITERAL, Types.VARBINARY, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.BOOLEAN_LITERAL, Types.BOOLEAN, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.CHARACTER_LARGE_OBJECT_LITERAL, Types.CLOB, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.CHARACTER_LITERAL, Types.CHAR, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.CHARACTER_VARYING_LITERAL, Types.VARCHAR, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.DATALINK_LITERAL, Types.DATALINK, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.DATE_LITERAL, Types.DATE, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.DECIMAL_LITERAL, Types.DECIMAL, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.DOUBLE_PRECISION_LITERAL, Types.DOUBLE, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.FLOAT_LITERAL, Types.FLOAT, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.INTEGER_LITERAL, Types.INTEGER, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.INTERVAL_LITERAL, Types.OTHER, mappings); // ??? + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.NATIONAL_CHARACTER_LARGE_OBJECT_LITERAL, Types.CLOB, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.NATIONAL_CHARACTER_LITERAL, Types.CHAR, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.NATIONAL_CHARACTER_VARYING_LITERAL, Types.VARCHAR, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.NUMERIC_LITERAL, Types.NUMERIC, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.REAL_LITERAL, Types.REAL, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.SMALLINT_LITERAL, Types.SMALLINT, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.TIME_LITERAL, Types.TIME, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.TIMESTAMP_LITERAL, Types.TIMESTAMP, mappings); + addPrimitiveToJDBCTypeMappingTo(PrimitiveType.XML_TYPE_LITERAL, Types.OTHER, mappings); // ??? + } + + private static void addPrimitiveToJDBCTypeMappingTo(PrimitiveType primitiveType, int jdbcTypeCode, HashMap mappings) { + // check for duplicates + Object prev = mappings.put(primitiveType.getName(), buildPrimitiveToJDBCTypeMapping(primitiveType, jdbcTypeCode)); + if (prev != null) { + throw new IllegalArgumentException("duplicate Java class: " + ((PrimitiveToJDBCTypeMapping) prev).getPrimitiveType().getName()); + } + } + + private static PrimitiveToJDBCTypeMapping buildPrimitiveToJDBCTypeMapping(PrimitiveType primitiveType, int jdbcTypeCode) { + return new PrimitiveToJDBCTypeMapping(primitiveType, JDBCType.type(jdbcTypeCode)); + } + + + // ********** constructor ********** + + /** + * Suppress default constructor, ensuring non-instantiability. + */ + private DTPTools() { + super(); + throw new UnsupportedOperationException(); + } + + + // ********** member classes ********** + + /** + * Primitive => JDBC + */ + private static class PrimitiveToJDBCTypeMapping { + private final PrimitiveType primitiveType; + private final JDBCType jdbcType; + + PrimitiveToJDBCTypeMapping(PrimitiveType primitiveType, JDBCType jdbcType) { + super(); + this.primitiveType = primitiveType; + this.jdbcType = jdbcType; + } + + public PrimitiveType getPrimitiveType() { + return this.primitiveType; + } + + public JDBCType getJDBCType() { + return this.jdbcType; + } + + public boolean maps(PrimitiveType pt) { + return this.primitiveType.equals(pt); + } + + public boolean maps(String primitiveTypeName) { + return this.primitiveType.getName().equals(primitiveTypeName); + } + + public boolean maps(int primitiveTypeCode) { + return this.primitiveType.getValue() == primitiveTypeCode; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + this.appendTo(sb); + return sb.toString(); + } + + public void appendTo(StringBuffer sb) { + sb.append(this.primitiveType.getName()); + sb.append(" => "); + this.jdbcType.appendTo(sb); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPWrapper.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPWrapper.java new file mode 100644 index 0000000000..62ad0b4d0f --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/DTPWrapper.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.datatools.connectivity.sqm.core.rte.RefreshManager; +import org.eclipse.jpt.utility.internal.StringTools; + +/** + * DataTools Wrapper base class. + */ +public abstract class DTPWrapper implements Comparable { + + DTPWrapper() { + super(); + } + + // ********** behavior ********** + + protected abstract void dispose(); + + protected abstract boolean connectionIsOnline(); + + protected void addCatalogObjectListener( ICatalogObject catalogObject, ICatalogObjectListener catalogObjectListener) { + if( this.connectionIsOnline()) { + RefreshManager.getInstance().AddListener( catalogObject, catalogObjectListener); + } + } + + protected void removeCatalogObjectListener( ICatalogObject catalogObject, ICatalogObjectListener catalogObjectListener) { + if( this.connectionIsOnline()) { + RefreshManager.getInstance().removeListener( catalogObject, catalogObjectListener); + } + } + + // ********** queries ********** + + public abstract String getName(); + + public String toString() { + return StringTools.buildToStringFor( this, this.getName()); + } +}
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Database.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Database.java new file mode 100644 index 0000000000..b56d32dc2e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Database.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.Iterator; +import java.util.Set; +import org.eclipse.jpt.utility.internal.StringTools; +import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; + +/** + * Database wrapper base class. + */ +public abstract class Database extends DTPWrapper { + + private boolean caseSensitive = false; // TODO allow user to configure + + // ********** constructors ********** + + static Database createDatabase( ConnectionProfile profile, org.eclipse.datatools.modelbase.sql.schema.Database dtpDatabase) { + return ( dtpDatabase == null) ? NullDatabase.instance() : new DTPDatabaseWrapper( profile, dtpDatabase); + } + + Database() { + super(); + } + + // ********** behavior ********** + + abstract void catalogChanged( Catalog catalog, int eventType); + + abstract void schemaChanged( Schema schema, int eventType); + + abstract void tableChanged( Table table, Schema schema, int eventType); + + abstract void refresh(); + + protected Schema wrap( org.eclipse.datatools.modelbase.sql.schema.Schema schema) { + return new Schema( this, schema); + } + + protected Catalog wrap( org.eclipse.datatools.modelbase.sql.schema.Catalog catalog) { + return new Catalog( this, catalog); + } + + // ********** queries ********** + + public abstract String getVendor(); + + public abstract String getVersion(); + + /** + * return the column for the specified dtp column + */ + Column column( org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { + return this.table( dtpColumn.getTable()).column( dtpColumn); + } + + /** + * return the table for the specified dtp table + */ + Table table( org.eclipse.datatools.modelbase.sql.tables.Table dtpTable) { + return this.schema( dtpTable.getSchema()).table( dtpTable); + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Database)o).getName()); + } + + // ***** caseSensitive + + public boolean isCaseSensitive() { + return this.caseSensitive; + } + + public void setCaseSensitive( boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } + + // ***** catalogs + + abstract Set getCatalogs(); + + /** + * Returns true if this database accepts catalogs. + */ + public abstract boolean supportsCatalogs(); + + /** + * Returns the catalog to use by default. + */ + public abstract String getDefaultCatalogName(); + + public Iterator catalogs() { + return this.getCatalogs().iterator(); + } + + public int catalogSize() { + return this.getCatalogs().size(); + } + + public Iterator catalogNames() { + return new TransformationIterator( this.catalogs()) { + protected Object transform( Object next) { + return (( Catalog) next).getName(); + } + }; + } + + public boolean containsCatalogNamed( String name) { + return this.catalogNamed( name) != null; + } + + public Catalog catalogNamed( String name) { + return this.isCaseSensitive() ? this.catalogNamedInternal( name) : this.catalogNamedIgnoreCase( name); + } + + private Catalog catalogNamedInternal( String name) { + for ( Iterator stream = this.catalogs(); stream.hasNext(); ) { + Catalog catalog = ( Catalog) stream.next(); + if ( catalog.getName().equals( name)) { + return catalog; + } + } + return null; + } + + private Catalog catalogNamedIgnoreCase( String name) { + for ( Iterator stream = this.catalogs(); stream.hasNext(); ) { + Catalog catalog = ( Catalog) stream.next(); + if ( StringTools.stringsAreEqualIgnoreCase( catalog.getName(), name)) { + return catalog; + } + } + return null; + } + + /** + * return the catalog for the specified dtp catalog + */ + Catalog catalog( org.eclipse.datatools.modelbase.sql.schema.Catalog dtpCatalog) { + for ( Iterator stream = this.catalogs(); stream.hasNext(); ) { + Catalog catalog = ( Catalog) stream.next(); + if (catalog.wraps( dtpCatalog)) { + return catalog; + } + } + throw new IllegalArgumentException( "invalid dtp catalog: " + dtpCatalog); + } + + + // ***** schemata + + abstract Set getSchemata(); + + public Iterator schemata() { + return this.getSchemata().iterator(); + } + + public int schemataSize() { + return this.getSchemata().size(); + } + + public boolean schemataContains( Column column) { + return this.getSchemata().contains( column); + } + + public Iterator schemaNames() { + return new TransformationIterator( this.schemata()) { + protected Object transform( Object next) { + return (( Schema) next).getName(); + } + }; + } + + public boolean containsSchemaNamed( String name) { + return this.schemaNamed( name) != null; + } + + public Schema schemaNamed( String name) { + return this.isCaseSensitive() ? this.schemaNamedInternal( name) : this.schemaNamedIgnoreCase( name); + } + + private Schema schemaNamedInternal( String name) { + for ( Iterator stream = this.schemata(); stream.hasNext(); ) { + Schema schema = ( Schema) stream.next(); + if ( schema.getName().equals( name)) { + return schema; + } + } + return null; + } + + private Schema schemaNamedIgnoreCase( String name) { + for ( Iterator stream = this.schemata(); stream.hasNext(); ) { + Schema schema = ( Schema) stream.next(); + if ( StringTools.stringsAreEqualIgnoreCase( schema.getName(), name)) { + return schema; + } + } + return null; + } + + /** + * return the schema for the specified dtp schema + */ + Schema schema( org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema) { + for ( Iterator stream = this.schemata(); stream.hasNext(); ) { + Schema schema = ( Schema) stream.next(); + if ( schema.wraps( dtpSchema)) { + return schema; + } + } + throw new IllegalArgumentException( "invalid dtp schema: " + dtpSchema); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ForeignKey.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ForeignKey.java new file mode 100644 index 0000000000..8a6edb586b --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ForeignKey.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.jpt.utility.internal.StringTools; +import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; + +/** + * Wrap a DTP ForeignKey + */ +public final class ForeignKey extends DTPWrapper { + private final Table baseTable; + private final org.eclipse.datatools.modelbase.sql.constraints.ForeignKey dtpForeignKey; + private ICatalogObjectListener foreignKeyListener; + + private Table referencedTable; // lazy-initialized + private Set<ColumnPair> columnPairs; // lazy-initialized + private String defaultEntityFieldName; // lazy-initialized + private boolean defaultEntityFieldNameCalculated = false; + + + // ********** constructors ********** + + ForeignKey(Table baseTable, org.eclipse.datatools.modelbase.sql.constraints.ForeignKey dtpForeignKey) { + super(); + this.baseTable = baseTable; + this.dtpForeignKey = dtpForeignKey; + this.initialize(); + } + + // ********** behavior ********** + + private void initialize() { + if( this.connectionIsOnline()) { + this.foreignKeyListener = this.buildForeignKeyListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpForeignKey, this.foreignKeyListener); + } + } + + protected boolean connectionIsOnline() { + return this.baseTable.connectionIsOnline(); + } + + private ICatalogObjectListener buildForeignKeyListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject foreignKey, final int eventType) { +// TODO +// if( foreignKey == ForeignKey.this.dtpForeignKey) { +// ForeignKey.this.baseTable.foreignKeyChanged( ForeignKey.this, eventType); +// } + } + }; + } + + protected void dispose() { + + this.removeCatalogObjectListener(( ICatalogObject) this.dtpForeignKey, this.foreignKeyListener); + } + + // ********** queries ********** + + public Table getBaseTable() { + return this.baseTable; + } + + @Override + public String getName() { + return this.dtpForeignKey.getName(); + } + + boolean isCaseSensitive() { + return this.baseTable.isCaseSensitive(); + } + + boolean wraps(org.eclipse.datatools.modelbase.sql.constraints.ForeignKey foreignKey) { + return this.dtpForeignKey == foreignKey; + } + + @Override + public String toString() { + return StringTools.buildToStringFor(this, this.getName() + ": " + this.getColumnPairs()); + } + + public Table getReferencedTable() { + if (this.referencedTable == null) { + this.referencedTable = this.baseTable.table(this.dtpForeignKey.getUniqueConstraint().getBaseTable()); + } + return this.referencedTable; + } + + /** + * return the foreign key's "base" columns + */ + public Iterator<Column> baseColumns() { + return new TransformationIterator<ColumnPair, Column>(this.columnPairs()) { + @Override + protected Column transform(ColumnPair pair) { + return pair.getBaseColumn(); + } + }; + } + + /** + * return the foreign key's "base" columns that are not part of + * the base table's primary key + */ + public Iterator<Column> nonPrimaryKeyBaseColumns() { + return new FilteringIterator(this.baseColumns()) { + @Override + protected boolean accept(Object o) { + return ! ForeignKey.this.getBaseTable().primaryKeyColumnsContains((Column) o); + } + }; + } + + /** + * return the foreign key's "referenced" columns + */ + public Iterator<Column> referencedColumns() { + return new TransformationIterator(this.columnPairs()) { + @Override + protected Object transform(Object next) { + return ((ColumnPair) next).getReferencedColumn(); + } + }; + } + + public String javaFieldName() { + String fieldName = this.getDefaultEntityFieldName(); + return (fieldName == null) ? + this.nonDefaultEntityFieldName() + : + fieldName; + } + + public boolean matchesJavaFieldName(String javaFieldName) { + return this.isCaseSensitive() ? + javaFieldName.equals(this.getDefaultEntityFieldName()) + : + javaFieldName.equalsIgnoreCase(this.getDefaultEntityFieldName()); + } + + public boolean isDefaultFor(String javaFieldName) { + if (this.columnPairsSize() != 1) { + return false; + } + + if (this.getReferencedTable().primaryKeyColumnsSize() != 1) { + return false; + } + + ColumnPair columnPair = this.columnPairs().next(); + Column pkColumn = (Column) this.getReferencedTable().primaryKeyColumns().next(); + if (columnPair.getReferencedColumn() != pkColumn) { + return false; + } + + return columnPair.getBaseColumn().matchesJavaFieldName(javaFieldName + "_" + pkColumn.getName()); + } + + + // ***** column pairs + + private synchronized Set<ColumnPair> getColumnPairs() { + if (this.columnPairs == null) { + this.columnPairs = this.buildColumnPairs(); + } + return this.columnPairs; + } + + private Set<ColumnPair> buildColumnPairs() { + List<org.eclipse.datatools.modelbase.sql.tables.Column> baseColumns = this.dtpForeignKey.getMembers(); + int size = baseColumns.size(); + List<org.eclipse.datatools.modelbase.sql.tables.Column> refColumns = this.dtpForeignKey.getUniqueConstraint().getMembers(); + if (refColumns.size() != size) { + throw new IllegalStateException("mismatched sizes: " + size + " vs. " + refColumns.size()); + } + Set<ColumnPair> result = new HashSet<ColumnPair>(baseColumns.size()); + for (int i = baseColumns.size(); i-- > 0; ) { + Column baseColumn = this.baseTable.column(baseColumns.get(i)); + Column refColumn = this.baseTable.column(refColumns.get(i)); + result.add(new ColumnPair(baseColumn, refColumn)); + } + return result; + } + + public Iterator<ColumnPair> columnPairs() { + return this.getColumnPairs().iterator(); + } + + public int columnPairsSize() { + return this.getColumnPairs().size(); + } + + + // ***** default entity field name + + /** + * If the name of the "base" column adheres to the EJB standard for a + * default mapping (i.e. it ends with an underscore followed by the name + * of the "referenced" column, and the "referenced" column is the single + * primary key column of the "referenced" table), return the corresponding + * default entity field name: + * ForeignKey(EMP.CUBICLE_ID => CUBICLE.ID) => "CUBICLE" + * Return a null if it does not adhere to the EJB standard: + * ForeignKey(EMP.CUBICLE_ID => CUBICLE.CUBICLE_ID) => null + */ + private String getDefaultEntityFieldName() { + if ( ! this.defaultEntityFieldNameCalculated) { + this.defaultEntityFieldNameCalculated = true; + this.defaultEntityFieldName = this.buildDefaultEntityFieldName(); + } + return this.defaultEntityFieldName; + } + + /** + * @see #getDefaultEntityFieldName() + */ + private String buildDefaultEntityFieldName() { + if ( ! this.referencesSingleColumnPrimaryKey()) { + return null; + } + ColumnPair columnPair = this.columnPairs().next(); + String baseColName = columnPair.getBaseColumn().getName(); + String refColName = columnPair.getReferencedColumn().getName(); + if (baseColName.length() <= (refColName.length() + 1)) { + return null; + } + if ( ! baseColName.endsWith(refColName)) { + return null; + } + int _index = baseColName.length() - refColName.length() - 1; + if (baseColName.charAt(_index) != '_') { + return null; + } + String name = baseColName.substring(0, _index); + return this.isCaseSensitive() ? name : name.toLowerCase(); + } + + /** + * Return whether the foreign key references the primary key of the + * "referenced" table and that primary key has only a single column. + */ + public boolean referencesSingleColumnPrimaryKey() { + if (this.columnPairsSize() != 1) { + return false; + } + if (this.getReferencedTable().primaryKeyColumnsSize() != 1) { + return false; + } + + ColumnPair columnPair = this.columnPairs().next(); + return columnPair.getReferencedColumn() == this.getReferencedTable().primaryKeyColumns().next(); + } + + /** + * If this is a simple (single-column) foreign key, return the java field + * name of the single base column. If this is a compound foreign key, + * return the java field name of the referenced table. + */ + // TODO if there is only one FK to a given table, use the table's name instead of the column's name? + // TODO if the FK column name ends with the PK column name, strip the PK column name? + private String nonDefaultEntityFieldName() { + return (this.columnPairsSize() == 1) ? + this.columnPairs().next().getBaseColumn().javaFieldName() + : + this.getReferencedTable().javaFieldName(); + } + + + // ********** Comparable implementation ********** + + public int compareTo(Object o) { + return Collator.getInstance().compare(this.getName(), ((ForeignKey) o).getName()); + } + + + // ********** member class ********** + + public static class ColumnPair implements Comparable<ColumnPair> { + private final Column baseColumn; + private final Column referencedColumn; + + ColumnPair(Column baseColumn, Column referencedColumn) { + super(); + this.baseColumn = baseColumn; + this.referencedColumn = referencedColumn; + } + + public Column getBaseColumn() { + return this.baseColumn; + } + + public Column getReferencedColumn() { + return this.referencedColumn; + } + + @Override + public String toString() { + return StringTools.buildToStringFor(this, baseColumn.getName() + "=>" + this.referencedColumn.getName()); + } + + public int compareTo(ColumnPair cp) { + return Collator.getInstance().compare(this.getBaseColumn().getName(), cp.getBaseColumn().getName()); + } + + } + +}
\ No newline at end of file diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnection.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnection.java new file mode 100644 index 0000000000..d71998ca88 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnection.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import org.eclipse.jpt.utility.internal.ClassTools; + +/** + * NullConnection + */ +public final class NullConnection extends Connection { + + private static NullConnection INSTANCE; + + /** + * singleton support + */ + static synchronized Connection instance() { + if( INSTANCE == null) { + INSTANCE = new NullConnection(); + } + return INSTANCE; + } + + private NullConnection() { + super(); + } + + // ********** behavior ********** + + protected void dispose() { + // do nothing + } + + public String getName() { + return ClassTools.shortClassNameForObject( this); + } + + void databaseChanged( Database database, int eventType) { + // do nothing + } + + void schemaChanged( Schema schema, Database database, int eventType) { + // do nothing + } + + void tableChanged( Table table, Schema schema, Database database, int eventType) { + // do nothing + } + + public boolean isConnected() { + return false; + } + + public String getFactoryId() { + return ""; + } + + public void addConnectionListener( ConnectionListener listener) { + // do nothing + } + + public void removeConnectionListener( ConnectionListener listener) { + // do nothing + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnectionProfile.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnectionProfile.java new file mode 100644 index 0000000000..45c36d1652 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullConnectionProfile.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import org.eclipse.jpt.utility.internal.ClassTools; + +/** + * NullConnectionProfile + */ +public final class NullConnectionProfile extends ConnectionProfile { + + private static NullConnectionProfile INSTANCE; + + /** + * singleton support + */ + static synchronized ConnectionProfile instance() { + if( INSTANCE == null) { + INSTANCE = new NullConnectionProfile(); + } + return INSTANCE; + } + + private NullConnectionProfile() { + super( null); + } + + // ********** behavior ********** + + protected Connection buildConnection() { + return NullConnection.instance(); + } + + protected Database buildDatabase() { + return NullDatabase.instance(); + } + + public void connect() { + // do nothing + } + + public void disconnect() { + // do nothing + } + + void databaseChanged( Database database, int eventType) { + // do nothing + } + + void catalogChanged( Catalog catalog, Database database, int eventType) { + // do nothing + } + + void schemaChanged( Schema schema, Database database, int eventType) { + // do nothing + } + + void tableChanged( Table table, Schema schema, Database database, int eventType) { + // do nothing + } + + // ********** queries ********** + + public Connection getConnection() { + return NullConnection.instance(); + } + + public Database getDatabase() { + return NullDatabase.instance(); + } + + public String getName() { + return ClassTools.shortClassNameForObject( this); + } + + public String getDatabaseName() { + return ""; + } + + public String getDatabaseProduct() { + return ""; + } + + public String getDatabaseVendor() { + return ""; + } + + public String getDatabaseVersion() { + return ""; + } + + public String getUserName() { + return ""; + } + + public String getInstanceId() { + return ""; + } + + public String getProviderId() { + return ""; + } + + public boolean isConnected() { + return false; + } + + boolean wraps( org.eclipse.datatools.connectivity.IConnectionProfile dtpProfile) { + return false; + } + + // ********** listeners ********** + + public void addProfileListener( ProfileListener listener) { + // do nothing + } + + public void removeProfileListener( ProfileListener listener) { + // do nothing + } + + public void addConnectionListener( ConnectionListener listener) { + // do nothing + } + + public void removeConnectionListener( ConnectionListener listener) { + // do nothing + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullDatabase.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullDatabase.java new file mode 100644 index 0000000000..96d145f019 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/NullDatabase.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.util.Collections; +import java.util.Set; +import org.eclipse.jpt.utility.internal.ClassTools; + +/** + * NullDatabase + */ +public final class NullDatabase extends Database { + + private static NullDatabase INSTANCE; + + /** + * singleton support + */ + static synchronized Database instance() { + if( INSTANCE == null) { + INSTANCE = new NullDatabase(); + } + return INSTANCE; + } + + private NullDatabase() { + super(); + } + + // ********** behavior ********** + + void catalogChanged( Catalog catalog, int eventType) { + // do nothing + } + + void schemaChanged( Schema schema, int eventType) { + // do nothing + } + + void tableChanged( Table table, Schema schema,int eventType) { + // do nothing + } + + void refresh() { + // do nothing + } + + protected void dispose() { + // do nothing + } + + protected boolean connectionIsOnline() { + return false; + } + + // ********** queries ********** + + public String getName() { + return ClassTools.shortClassNameForObject( this); + } + + public String getVendor() { + return this.getName(); + } + + public String getVersion() { + return ""; + } + + // ***** catalogs + + @Override + public boolean supportsCatalogs() { + return false; + } + + @Override + public String getDefaultCatalogName() { + return ""; + } + + @Override + Set getCatalogs() { + return Collections.emptySet(); + } + + // ***** schemata + + @Override + Set getSchemata() { + return Collections.emptySet(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/PersistenceDbPlugin.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/PersistenceDbPlugin.java new file mode 100644 index 0000000000..bd5aed817c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/PersistenceDbPlugin.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class PersistenceDbPlugin extends Plugin { + private ConnectionProfileRepository connectionProfileRepository; + + // The shared instance + private static PersistenceDbPlugin plugin; + + /** + * Returns the shared instance + */ + public static PersistenceDbPlugin getDefault() { + return plugin; + } + + /** + * The constructor + */ + public PersistenceDbPlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + this.connectionProfileRepository = ConnectionProfileRepository.instance(); + this.connectionProfileRepository.initializeListeners(); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + this.connectionProfileRepository.disposeListeners(); + this.connectionProfileRepository = null; + plugin = null; + super.stop(context); + } + + + public ConnectionProfileRepository getConnectionProfileRepository() { + return this.connectionProfileRepository; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ProfileListener.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ProfileListener.java new file mode 100644 index 0000000000..a83e5b0f02 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/ProfileListener.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +/** + * ProfileListener integrate th DTP IProfileListener listener. + * This class purpose is to decouple from the DTP listeners by accepting wrappers as parameter. + * + * @see org.eclipse.datatools.connectivity.IProfileListener + */ +public interface ProfileListener { + /** + * The specified profile has been added. + */ + public void profileAdded( ConnectionProfile profile); + + /** + * The specified profile has been deleted. + */ + public void profileDeleted( String profileName); + + /** + * The specified profile has been modified. Modification includes + * changes to any properties, the name, auto-connect flag, etc. + */ + public void profileChanged( ConnectionProfile profile); + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Schema.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Schema.java new file mode 100644 index 0000000000..02921dee91 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Schema.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.jpt.utility.internal.StringTools; +import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; + +/** + * Wrap a DTP Schema + */ +public final class Schema extends DTPWrapper { + private final Database database; + private final org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema; + private ICatalogObjectListener schemaListener; + + private Set tables; // lazy-initialized + private Set sequences; // lazy-initialized + + + // ********** constructors ********** + + Schema( Database database, org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema) { + super(); + this.database = database; + this.dtpSchema = dtpSchema; + this.initialize(); + } + + // ********** behavior ********** + + private void initialize() { + if( this.connectionIsOnline()) { + this.schemaListener = this.buildSchemaListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpSchema, this.schemaListener); + } + } + + protected boolean connectionIsOnline() { + return this.database.connectionIsOnline(); + } + + private ICatalogObjectListener buildSchemaListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject schema, final int eventType) { + if( schema == Schema.this.dtpSchema) { + Schema.this.refresh(); + Schema.this.database.schemaChanged( Schema.this, eventType); + } + } + }; + } + + private void refresh() { + this.disposeTables(); + this.disposeSequences(); + + this.tables = null; + this.sequences = null; + } + + void tableChanged( Table table, int eventType) { + this.database.tableChanged( table, this, eventType); + } + + protected Table wrap( org.eclipse.datatools.modelbase.sql.tables.Table table) { + return new Table( this, table); + } + + protected Sequence wrap( org.eclipse.datatools.modelbase.sql.schema.Sequence sequence) { + return new Sequence( this, sequence); + } + + protected void dispose() { + this.removeCatalogObjectListener(( ICatalogObject) this.dtpSchema, this.schemaListener); + + this.disposeTables(); + this.disposeSequences(); + } + + private void disposeTables() { + if( this.tables != null) { + for( Iterator i = this.tables(); i.hasNext(); ) { + (( Table)i.next()).dispose(); + } + } + } + + private void disposeSequences() { + if( this.sequences != null) { + for( Iterator i = this.sequences(); i.hasNext(); ) { + (( Sequence)i.next()).dispose(); + } + } + } + + // ********** queries ********** + + public String getName() { + return this.dtpSchema.getName(); + } + + boolean isCaseSensitive() { + return this.database.isCaseSensitive(); + } + + Column column( org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { + return this.database.column(dtpColumn); + } + + + // ********** tables ********** + + private synchronized Collection getTables() { + if( this.tables == null) { + this.tables = this.buildTables(); + } + return this.tables; + } + + private Set buildTables() { + Collection dtpTables = this.dtpSchema.getTables(); + Set result = new HashSet( dtpTables.size()); + for( Iterator i = dtpTables.iterator(); i.hasNext(); ) { + result.add( this.wrap(( org.eclipse.datatools.modelbase.sql.tables.Table) i.next())); + } + return result; + } + + public Iterator tables() { + return this.getTables().iterator(); + } + + public int tablesSize() { + return this.getTables().size(); + } + + public boolean tablesContains( Column column) { + return this.getTables().contains( column); + } + + public Iterator<String> tableNames() { + return new TransformationIterator( this.tables()) { + protected Object transform( Object next) { + return (( Table) next).getName(); + } + }; + } + + public boolean containsTableNamed( String name) { + return this.tableNamed( name) != null; + } + + public Table tableNamed( String name) { + return this.isCaseSensitive() ? this.tableNamedInternal( name) : this.tableNamedIgnoreCase( name); + } + + private Table tableNamedInternal( String name) { + for( Iterator i = this.tables(); i.hasNext(); ) { + Table table = ( Table) i.next(); + if( table.getName().equals( name)) { + return table; + } + } + return null; + } + + private Table tableNamedIgnoreCase( String name) { + for( Iterator i = this.tables(); i.hasNext(); ) { + Table table = ( Table) i.next(); + if( StringTools.stringsAreEqualIgnoreCase( table.getName(), name)) { + return table; + } + } + return null; + } + + /** + * return the table for the specified dtp table + */ + Table table( org.eclipse.datatools.modelbase.sql.tables.Table dtpTable) { + if( dtpTable.getSchema() != this.dtpSchema) { + return this.database.table( dtpTable); + } + for( Iterator i = this.tables(); i.hasNext(); ) { + Table table = ( Table) i.next(); + if( table.wraps( dtpTable)) { + return table; + } + } + throw new IllegalArgumentException( "invalid DTP table: " + dtpTable); + } + + // ***** sequences + + private synchronized Collection getSequences() { + if( this.sequences == null) { + this.sequences = this.buildSequences(); + } + return this.sequences; + } + + private Set buildSequences() { + Collection dtpSequences = this.dtpSchema.getSequences(); + Set result = new HashSet( dtpSequences.size()); + for( Iterator i = dtpSequences.iterator(); i.hasNext(); ) { + result.add( this.wrap(( org.eclipse.datatools.modelbase.sql.schema.Sequence) i.next())); + } + return result; + } + + public Iterator sequences() { + return this.getSequences().iterator(); + } + + public int sequencesSize() { + return this.getSequences().size(); + } + + public boolean sequencesContains( Column column) { + return this.getSequences().contains( column); + } + + public Iterator sequenceNames() { + return new TransformationIterator(this.sequences()) { + protected Object transform( Object next) { + return (( Sequence)next).getName(); + } + }; + } + + public boolean containsSequenceNamed( String name) { + return this.sequenceNamed( name) != null; + } + + public Sequence sequenceNamed( String name) { + return this.isCaseSensitive() ? this.sequenceNamedInternal( name) : this.sequenceNamedIgnoreCase( name); + } + + private Sequence sequenceNamedInternal( String name) { + for( Iterator i = this.sequences(); i.hasNext(); ) { + Sequence sequence = ( Sequence) i.next(); + if( sequence.getName().equals( name)) { + return sequence; + } + } + return null; + } + + private Sequence sequenceNamedIgnoreCase( String name) { + for( Iterator i = this.sequences(); i.hasNext(); ) { + Sequence sequence = ( Sequence) i.next(); + if( sequence.getName().equalsIgnoreCase( name)) { + return sequence; + } + } + return null; + } + + boolean wraps( org.eclipse.datatools.modelbase.sql.schema.Schema dtpSchema) { + return this.dtpSchema == dtpSchema; + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Schema)o).getName()); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Sequence.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Sequence.java new file mode 100644 index 0000000000..c03520e1d7 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Sequence.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; + +/** + * Wrap a DTP Sequence + */ +public final class Sequence extends DTPWrapper { + private final Schema schema; + private final org.eclipse.datatools.modelbase.sql.schema.Sequence dtpSequence; + private ICatalogObjectListener sequenceListener; + + Sequence( Schema schema, org.eclipse.datatools.modelbase.sql.schema.Sequence dtpSequence) { + super(); + this.schema = schema; + this.dtpSequence = dtpSequence; + this.initialize(); + } + + // ********** behavior ********** + + private void initialize() { + if( this.connectionIsOnline()) { + this.sequenceListener = this.buildSequenceListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpSequence, this.sequenceListener); + } + } + + protected boolean connectionIsOnline() { + return this.schema.connectionIsOnline(); + } + + private ICatalogObjectListener buildSequenceListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject sequence, final int eventType) { +// TODO +// if( sequence == Sequence.this.dtpSequence) { +// Sequence.this.schema.sequenceChanged( Sequence.this, eventType); +// } + } + }; + } + + + // ********** queries ********** + + protected void dispose() { + + this.removeCatalogObjectListener(( ICatalogObject) this.dtpSequence, this.sequenceListener); + } + + public String getName() { + return this.dtpSequence.getName(); + } + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Sequence)o).getName()); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Table.java b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Table.java new file mode 100644 index 0000000000..34db8b149e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.db/src/org/eclipse/jpt/db/internal/Table.java @@ -0,0 +1,345 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Oracle. 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: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.db.internal; + +import java.text.Collator; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject; +import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObjectListener; +import org.eclipse.datatools.modelbase.sql.constraints.PrimaryKey; +import org.eclipse.datatools.modelbase.sql.tables.BaseTable; +import org.eclipse.jpt.utility.internal.CollectionTools; +import org.eclipse.jpt.utility.internal.NameTools; +import org.eclipse.jpt.utility.internal.StringTools; +import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; + +/** + * Wrap a DTP Table + */ +public final class Table extends DTPWrapper { + private final Schema schema; + private final org.eclipse.datatools.modelbase.sql.tables.Table dtpTable; + private ICatalogObjectListener tableListener; + + private Set<Column> columns; // lazy-initialized + private Set<Column> primaryKeyColumns; // lazy-initialized + private Set<ForeignKey> foreignKeys; // lazy-initialized + private Set<Column> foreignKeyColumns; // lazy-initialized + + // ********** constructors ********** + + Table(Schema schema, org.eclipse.datatools.modelbase.sql.tables.Table dtpTable) { + super(); + this.schema = schema; + this.dtpTable = dtpTable; + this.initialize(); + } + + + // ********** behavior ********** + + private void initialize() { + if( this.connectionIsOnline()) { + this.tableListener = this.buildTableListener(); + this.addCatalogObjectListener(( ICatalogObject) this.dtpTable, this.tableListener); + } + } + + protected boolean connectionIsOnline() { + return this.schema.connectionIsOnline(); + } + + private ICatalogObjectListener buildTableListener() { + return new ICatalogObjectListener() { + public void notifyChanged( final ICatalogObject table, final int eventType) { + if( table == Table.this.dtpTable) { + Table.this.refresh(); + Table.this.schema.tableChanged( Table.this, eventType); + } + } + }; + } + + private void refresh() { + this.disposeColumns(); + + this.columns = null; + this.primaryKeyColumns = null; + this.foreignKeys = null; + this.foreignKeyColumns = null; + } + + @Override + protected void dispose() { + this.removeCatalogObjectListener(( ICatalogObject) this.dtpTable, this.tableListener); + + this.disposeColumns(); + this.disposeForeignKey(); + } + + private void disposeColumns() { + if( this.columns != null) { + for( Iterator i = this.columns(); i.hasNext(); ) { + (( Column)i.next()).dispose(); + } + } + } + + private void disposeForeignKey() { + if( this.foreignKeys != null) { + for( Iterator i = this.foreignKeys(); i.hasNext(); ) { + (( ForeignKey)i.next()).dispose(); + } + } + } + + // ********** queries ********** + + @Override + public String getName() { + return this.dtpTable.getName(); + } + + boolean isCaseSensitive() { + return this.schema.isCaseSensitive(); + } + + public String shortJavaClassName() { + String jName = this.getName(); + if ( ! this.isCaseSensitive()) { + jName = StringTools.capitalize(jName.toLowerCase()); + } + return NameTools.convertToJavaIdentifier(jName); + } + + public boolean matchesShortJavaClassName(String shortJavaClassName) { + return this.isCaseSensitive() ? + this.getName().equals(shortJavaClassName) + : + this.getName().equalsIgnoreCase(shortJavaClassName); + } + + public String javaFieldName() { + String jName = this.getName(); + if ( ! this.isCaseSensitive()) { + jName = jName.toLowerCase(); + } + return NameTools.convertToJavaIdentifier(jName); + } + + boolean wraps(org.eclipse.datatools.modelbase.sql.tables.Table table) { + return this.dtpTable == table; + } + + /** + * return the table for the specified DTP table + */ + Table table(org.eclipse.datatools.modelbase.sql.tables.Table table) { + return this.schema.table(table); + } + + // ***** columns + + private synchronized Set<Column> getColumns() { + if (this.columns == null) { + this.columns = this.buildColumns(); + } + return this.columns; + } + + @SuppressWarnings("unchecked") + private Set<Column> buildColumns() { + Collection<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns = this.dtpTable.getColumns(); + Set<Column> result = new HashSet<Column>(dtpColumns.size()); + for (org.eclipse.datatools.modelbase.sql.tables.Column c : dtpColumns) { + result.add(new Column(this, c)); + } + return result; + } + + public Iterator<Column> columns() { + return this.getColumns().iterator(); + } + + public int columnsSize() { + return this.getColumns().size(); + } + + public boolean columnsContains(Column column) { + return this.getColumns().contains(column); + } + + public Iterator<String> columnNames() { + return new TransformationIterator<Column, String>(this.columns()) { + @Override + protected String transform(Column next) { + return next.getName(); + } + }; + } + + public boolean containsColumnNamed(String name) { + return this.columnNamed(name) != null; + } + + public Column columnNamed(String name) { + return this.isCaseSensitive() ? this.columnNamedInternal(name) : this.columnNamedIgnoreCase(name); + } + + private Column columnNamedInternal(String name) { + for (Iterator<Column> stream = this.columns(); stream.hasNext(); ) { + Column column = stream.next(); + if (column.getName().equals(name)) { + return column; + } + } + return null; + } + + private Column columnNamedIgnoreCase(String name) { + for (Iterator<Column> stream = this.columns(); stream.hasNext(); ) { + Column column = stream.next(); + if (StringTools.stringsAreEqualIgnoreCase(column.getName(), name)) { + return column; + } + } + return null; + } + + /** + * return the column for the specified dtp column + */ + Column column(org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { + if (dtpColumn.getTable() != this.dtpTable) { + return this.schema.column(dtpColumn); + } + for (Iterator<Column> stream = this.columns(); stream.hasNext(); ) { + Column column = stream.next(); + if (column.wraps(dtpColumn)) { + return column; + } + } + throw new IllegalArgumentException("invalid dtp column: " + dtpColumn); + } + + + // ***** primaryKeyColumns + + private synchronized Set<Column> getPrimaryKeyColumns() { + if (this.primaryKeyColumns == null) { + this.primaryKeyColumns = this.buildPrimaryKeyColumns(); + } + return this.primaryKeyColumns; + } + + @SuppressWarnings("unchecked") + private Set<Column> buildPrimaryKeyColumns() { + if ( ! (this.dtpTable instanceof BaseTable)) { + return Collections.emptySet(); + } + PrimaryKey pk = ((BaseTable) this.dtpTable).getPrimaryKey(); + if (pk == null) { + // no PK was defined + return Collections.emptySet(); + } + Collection<org.eclipse.datatools.modelbase.sql.tables.Column> pkColumns = pk.getMembers(); + Set<Column> result = new HashSet<Column>(pkColumns.size()); + for (org.eclipse.datatools.modelbase.sql.tables.Column pkColumn : pkColumns) { + result.add(this.column(pkColumn)); + } + return result; + } + + public Iterator<Column> primaryKeyColumns() { + return this.getPrimaryKeyColumns().iterator(); + } + + public int primaryKeyColumnsSize() { + return this.getPrimaryKeyColumns().size(); + } + + public boolean primaryKeyColumnsContains(Column column) { + return this.getPrimaryKeyColumns().contains(column); + } + + + // ***** foreignKeys + + private synchronized Set<ForeignKey> getForeignKeys() { + if (this.foreignKeys == null) { + this.foreignKeys = this.buildForeignKeys(); + } + return this.foreignKeys; + } + + @SuppressWarnings("unchecked") + private Set<ForeignKey> buildForeignKeys() { + if ( ! (this.dtpTable instanceof BaseTable)) { + return Collections.emptySet(); + } + Collection<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys = ((BaseTable) this.dtpTable).getForeignKeys(); + Set<ForeignKey> result = new HashSet<ForeignKey>(dtpForeignKeys.size()); + for (org.eclipse.datatools.modelbase.sql.constraints.ForeignKey dtpForeignKey : dtpForeignKeys) { + result.add(new ForeignKey(this, dtpForeignKey)); + } + return result; + } + + public Iterator<ForeignKey> foreignKeys() { + return this.getForeignKeys().iterator(); + } + + public int foreignKeysSize() { + return this.getForeignKeys().size(); + } + + + // ***** foreignKeyColumns + + private synchronized Set<Column> getForeignKeyColumns() { + if (this.foreignKeyColumns == null) { + this.foreignKeyColumns = this.buildForeignKeyColumns(); + } + return this.foreignKeyColumns; + } + + private Set<Column> buildForeignKeyColumns() { + if ( ! (this.dtpTable instanceof BaseTable)) { + return Collections.emptySet(); + } + Set<Column> result = new HashSet<Column>(this.columnsSize()); + for (Iterator<ForeignKey> stream = this.foreignKeys(); stream.hasNext(); ) { + CollectionTools.addAll(result, stream.next().baseColumns()); + } + return result; + } + + public Iterator<Column> foreignKeyColumns() { + return this.getForeignKeyColumns().iterator(); + } + + public int foreignKeyColumnsSize() { + return this.getForeignKeyColumns().size(); + } + + public boolean foreignKeyColumnsContains(Column column) { + return this.getForeignKeyColumns().contains(column); + } + + // ********** Comparable implementation ********** + + public int compareTo( Object o) { + return Collator.getInstance().compare( this.getName(), (( Table)o).getName()); + } +} |