blob: 6b271b8c9c87129b80d46e111ccd1f9d86db4722 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2008 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.List;
import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject;
import org.eclipse.datatools.modelbase.sql.constraints.PrimaryKey;
import org.eclipse.datatools.modelbase.sql.tables.BaseTable;
import org.eclipse.jpt.db.Column;
import org.eclipse.jpt.db.ForeignKey;
import org.eclipse.jpt.db.Table;
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.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
/**
* Wrap a DTP Table
*/
final class DTPTableWrapper
extends DTPWrapper
implements Table
{
// backpointer to parent
private final DTPSchemaWrapper schema;
// the wrapped DTP table
private final org.eclipse.datatools.modelbase.sql.tables.Table dtpTable;
// lazy-initialized
private DTPColumnWrapper[] columns;
// lazy-initialized
private DTPColumnWrapper[] primaryKeyColumns;
// lazy-initialized
private DTPForeignKeyWrapper[] foreignKeys;
private static final DTPColumnWrapper[] EMPTY_COLUMNS = new DTPColumnWrapper[0];
private static final DTPForeignKeyWrapper[] EMPTY_FOREIGN_KEYS = new DTPForeignKeyWrapper[0];
// ********** constructor **********
DTPTableWrapper(DTPSchemaWrapper schema, org.eclipse.datatools.modelbase.sql.tables.Table dtpTable) {
super(schema);
this.schema = schema;
this.dtpTable = dtpTable;
}
// ********** DTPWrapper implementation **********
@Override
ICatalogObject getCatalogObject() {
return (ICatalogObject) this.dtpTable;
}
@Override
synchronized void catalogObjectChanged(int eventType) {
// clear stuff so it can be rebuilt
this.dispose_();
this.getConnectionProfile().tableChanged(this, eventType);
}
// ********** Table implementation **********
@Override
public String getName() {
return this.dtpTable.getName();
}
public String getShortJavaClassName() {
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 getJavaFieldName() {
String jName = this.getName();
if ( ! this.isCaseSensitive()) {
jName = jName.toLowerCase();
}
return NameTools.convertToJavaIdentifier(jName);
}
// ***** columns
public Iterator<Column> columns() {
return new ArrayIterator<Column>(this.columns_());
}
private Iterator<DTPColumnWrapper> columnWrappers() {
return new ArrayIterator<DTPColumnWrapper>(this.columns_());
}
private synchronized DTPColumnWrapper[] columns_() {
if (this.columns == null) {
this.columns = this.buildColumns();
}
return this.columns;
}
private DTPColumnWrapper[] buildColumns() {
List<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns = this.dtpColumns();
DTPColumnWrapper[] result = new DTPColumnWrapper[dtpColumns.size()];
for (int i = result.length; i-- > 0;) {
result[i] = new DTPColumnWrapper(this, dtpColumns.get(i));
}
return result;
}
// minimize scope of suppressed warnings
@SuppressWarnings("unchecked")
private List<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns() {
return this.dtpTable.getColumns();
}
public int columnsSize() {
return this.columns_().length;
}
public Iterator<String> columnNames() {
return new TransformationIterator<DTPColumnWrapper, String>(this.columnWrappers()) {
@Override
protected String transform(DTPColumnWrapper next) {
return next.getName();
}
};
}
public boolean containsColumnNamed(String name) {
return this.columnNamed(name) != null;
}
public DTPColumnWrapper columnNamed(String name) {
return this.isCaseSensitive() ? this.columnNamedCaseSensitive(name) : this.columnNamedIgnoreCase(name);
}
private DTPColumnWrapper columnNamedCaseSensitive(String name) {
for (Iterator<DTPColumnWrapper> stream = this.columnWrappers(); stream.hasNext(); ) {
DTPColumnWrapper column = stream.next();
if (column.getName().equals(name)) {
return column;
}
}
return null;
}
private DTPColumnWrapper columnNamedIgnoreCase(String name) {
for (Iterator<DTPColumnWrapper> stream = this.columnWrappers(); stream.hasNext(); ) {
DTPColumnWrapper column = stream.next();
if (StringTools.stringsAreEqualIgnoreCase(column.getName(), name)) {
return column;
}
}
return null;
}
/**
* return the column for the specified DTP column
*/
DTPColumnWrapper column(org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) {
if (dtpColumn.getTable() != this.dtpTable) {
return this.schema.column(dtpColumn);
}
for (DTPColumnWrapper column : this.columns_()) {
if (column.wraps(dtpColumn)) {
return column;
}
}
throw new IllegalArgumentException("invalid DTP column: " + dtpColumn); //$NON-NLS-1$
}
// ***** primaryKeyColumns
public Iterator<Column> primaryKeyColumns() {
return new ArrayIterator<Column>(this.primaryKeyColumns_());
}
public DTPColumnWrapper primaryKeyColumn() {
DTPColumnWrapper[] pkColumns = this.primaryKeyColumns_();
if (pkColumns.length != 1) {
throw new IllegalStateException("multiple primary key columns: " + pkColumns.length); //$NON-NLS-1$
}
return pkColumns[0];
}
private synchronized DTPColumnWrapper[] primaryKeyColumns_() {
if (this.primaryKeyColumns == null) {
this.primaryKeyColumns = this.buildPrimaryKeyColumns();
}
return this.primaryKeyColumns;
}
private DTPColumnWrapper[] buildPrimaryKeyColumns() {
if ( ! (this.dtpTable instanceof BaseTable)) {
return EMPTY_COLUMNS;
}
PrimaryKey pk = ((BaseTable) this.dtpTable).getPrimaryKey();
if (pk == null) {
// no PK was defined
return EMPTY_COLUMNS;
}
List<org.eclipse.datatools.modelbase.sql.tables.Column> pkColumns = this.columns(pk);
DTPColumnWrapper[] result = new DTPColumnWrapper[pkColumns.size()];
for (int i = result.length; i-- > 0;) {
result[i] = this.column(pkColumns.get(i));
}
return result;
}
// minimize scope of suppressed warnings
@SuppressWarnings("unchecked")
private List<org.eclipse.datatools.modelbase.sql.tables.Column> columns(PrimaryKey pk) {
return pk.getMembers();
}
public int primaryKeyColumnsSize() {
return this.primaryKeyColumns_().length;
}
public boolean primaryKeyColumnsContains(Column column) {
return CollectionTools.contains(this.primaryKeyColumns_(), column);
}
// ***** foreignKeys
public Iterator<ForeignKey> foreignKeys() {
return new ArrayIterator<ForeignKey>(this.foreignKeys_());
}
private Iterator<DTPForeignKeyWrapper> foreignKeyWrappers() {
return new ArrayIterator<DTPForeignKeyWrapper>(this.foreignKeys_());
}
private synchronized DTPForeignKeyWrapper[] foreignKeys_() {
if (this.foreignKeys == null) {
this.foreignKeys = this.buildForeignKeys();
}
return this.foreignKeys;
}
private DTPForeignKeyWrapper[] buildForeignKeys() {
if ( ! (this.dtpTable instanceof BaseTable)) {
return EMPTY_FOREIGN_KEYS;
}
List<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys = this.dtpForeignKeys();
DTPForeignKeyWrapper[] result = new DTPForeignKeyWrapper[dtpForeignKeys.size()];
for (int i = result.length; i-- > 0;) {
result[i] = new DTPForeignKeyWrapper(this, dtpForeignKeys.get(i));
}
return result;
}
@SuppressWarnings("unchecked")
private List<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys() {
return ((BaseTable) this.dtpTable).getForeignKeys();
}
public int foreignKeysSize() {
return this.foreignKeys_().length;
}
public boolean foreignKeyBaseColumnsContains(Column column) {
for (Iterator<DTPForeignKeyWrapper> stream = this.foreignKeyWrappers(); stream.hasNext(); ) {
DTPForeignKeyWrapper foreignKey = stream.next();
if (foreignKey.baseColumnsContains(column)) {
return true;
}
}
return false;
}
// ********** Comparable implementation **********
public int compareTo(Table table) {
return Collator.getInstance().compare(this.getName(), table.getName());
}
// ********** internal methods **********
boolean wraps(org.eclipse.datatools.modelbase.sql.tables.Table table) {
return this.dtpTable == table;
}
boolean isCaseSensitive() {
return this.schema.isCaseSensitive();
}
DTPTableWrapper table(org.eclipse.datatools.modelbase.sql.tables.Table table) {
return this.schema.table(table);
}
DTPDatabaseWrapper database() {
return this.schema.database();
}
// ********** disposal **********
@Override
synchronized void dispose() {
this.dispose_();
super.dispose();
}
private void dispose_() {
this.disposeForeignKeys();
// the table does not "contain" the pk columns, so no need to forward #dispose()
this.primaryKeyColumns = null;
this.disposeColumns();
}
private void disposeForeignKeys() {
if (this.foreignKeys != null) {
for (DTPForeignKeyWrapper foreignKey : this.foreignKeys) {
foreignKey.dispose();
}
this.foreignKeys = null;
}
}
private void disposeColumns() {
if (this.columns != null) {
for (DTPColumnWrapper column : this.columns) {
column.dispose();
}
this.columns = null;
}
}
}