| /******************************************************************************* |
| * 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()); |
| } |
| } |