
dk.eobjects.metamodel.schema.Relationship Maven / Gradle / Ivy
/**
* This file is part of MetaModel.
*
* MetaModel is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MetaModel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MetaModel. If not, see .
*/
package dk.eobjects.metamodel.schema;
import java.io.Serializable;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Represents a relationship between two tables where one set of columns is the
* primary key, and another set is the foreign key. Relationship is unlike most
* of the MetaModel an immutable type. The immutability help ensure integrity of
* object-relationships. To create relationsips use the
* createRelationship
method and to remove them use the
* remove method.
*
* @see Table
* @see Column
*/
public class Relationship implements Serializable, Comparable {
private static final long serialVersionUID = 238786848828528822L;
private Table _primaryTable;
private Column[] _primaryColumns;
private Table _foreignTable;
private Column[] _foreignColumns;
/**
* Factory method to create relations between two tables by specifying which
* columns from the tables that enforce the relationship.
*
* @param primaryColumns
* the columns from the primary key table
* @param foreignColumns
* the columns from the foreign key table
* @return the relation created
*/
public static Relationship createRelationship(Column[] primaryColumns,
Column[] foreignColumns) {
Table primaryTable = checkSameTable(primaryColumns);
Table foreignTable = checkSameTable(foreignColumns);
Relationship relation = new Relationship(primaryTable, primaryColumns,
foreignTable, foreignColumns);
primaryTable.addRelationship(relation);
// Ticket #144: Some tables have relations with them selves and then the
// relationship should only be added once.
if (foreignTable != primaryTable) {
foreignTable.addRelationship(relation);
}
return relation;
}
public static Relationship createRelationship(Column primaryColumn,
Column foreignColumn) {
return createRelationship(new Column[] { primaryColumn },
new Column[] { foreignColumn });
}
private static Table checkSameTable(Column[] columns) {
if (columns == null || columns.length == 0) {
throw new IllegalArgumentException(
"At least one key-column must exist on both "
+ "primary and foreign side for "
+ "a relation to exist.");
}
Table table = null;
for (int i = 0; i < columns.length; i++) {
Column column = columns[i];
if (i == 0) {
table = column.getTable();
} else {
if (table != column.getTable()) {
throw new IllegalArgumentException(
"Key-columns did not have same table");
}
}
}
return table;
}
public void remove() {
_primaryTable.removeRelationship(this);
_foreignTable.removeRelationship(this);
_primaryColumns = null;
_primaryTable = null;
_foreignColumns = null;
_foreignTable = null;
}
/**
* Prevent external instantiation
*/
private Relationship(Table primaryTable, Column[] primaryColumns,
Table foreignTable, Column[] foreignColumns) {
_primaryTable = primaryTable;
_primaryColumns = primaryColumns;
_foreignTable = foreignTable;
_foreignColumns = foreignColumns;
}
public Table getPrimaryTable() {
return _primaryTable;
}
public Column[] getPrimaryColumns() {
return _primaryColumns;
}
public Table getForeignTable() {
return _foreignTable;
}
public Column[] getForeignColumns() {
return _foreignColumns;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Relationship[");
sb.append("primaryTable=" + _primaryTable.getName());
Column[] columns = getPrimaryColumns();
sb.append(",primaryColumns={");
for (int i = 0; i < columns.length; i++) {
if (i != 0) {
sb.append(",");
}
sb.append(columns[i].getName());
}
sb.append("}");
sb.append(",foreignTable=" + _foreignTable.getName());
columns = getForeignColumns();
sb.append(",foreignColumns={");
for (int i = 0; i < columns.length; i++) {
if (i != 0) {
sb.append(",");
}
sb.append(columns[i].getName());
}
sb.append("}");
sb.append("]");
return sb.toString();
}
public int compareTo(Relationship that) {
CompareToBuilder ctb = new CompareToBuilder();
ctb.append(this.getPrimaryTable(), that.getPrimaryTable());
ctb.append(this.getForeignTable(), that.getForeignTable());
ctb.append(this.getPrimaryColumns(), that.getPrimaryColumns());
ctb.append(this.getForeignColumns(), that.getForeignColumns());
return ctb.toComparison();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Relationship) {
Relationship that = (Relationship) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.append(this.getPrimaryColumns(), that.getPrimaryColumns());
eb.append(this.getForeignColumns(), that.getForeignColumns());
return eb.isEquals();
}
return false;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(_foreignColumns).append(
_primaryColumns).toHashCode();
}
/**
* @param pkColumn
* primary key column
* @param fkColumn
* foreign key column
* @return true if this relation contains the specified primary and foreign
* columns as a part of the relation
*/
public boolean containsColumnPair(Column pkColumn, Column fkColumn) {
if (pkColumn != null && fkColumn != null) {
for (int i = 0; i < _primaryColumns.length; i++) {
if (pkColumn.equals(_primaryColumns[i])
&& fkColumn.equals(_foreignColumns[i])) {
return true;
}
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy