blob: 7b49b72f8c087661d930684ba0671715f6d7e6b1 [file] [log] [blame]
/*******************************************************************************
* 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 implements Comparable<Table> {
final Schema schema;
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);
}
}
@Override
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);
}
}
};
}
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<Column> stream = this.columns(); stream.hasNext(); ) {
stream.next().dispose();
}
}
}
private void disposeForeignKey() {
if( this.foreignKeys != null) {
for( Iterator<ForeignKey> stream = this.foreignKeys(); stream.hasNext(); ) {
stream.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 Collection<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns() {
return this.dtpTable.getColumns();
}
private Set<Column> buildColumns() {
Collection<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns = this.dtpColumns();
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 Collection<org.eclipse.datatools.modelbase.sql.tables.Column> columns(PrimaryKey pk) {
return pk.getMembers();
}
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 = this.columns(pk);
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 Collection<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys() {
return ((BaseTable) this.dtpTable).getForeignKeys();
}
private Set<ForeignKey> buildForeignKeys() {
if ( ! (this.dtpTable instanceof BaseTable)) {
return Collections.emptySet();
}
Collection<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys = this.dtpForeignKeys();
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( Table table) {
return Collator.getInstance().compare( this.getName(), table.getName());
}
}