/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.metamodel.schema;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Immutable implementation of the Relationship interface.
*
* The immutability help ensure integrity of object-relationships. To create
* relationsips use the <code>createRelationship</code> method.
*/
public class MutableRelationship extends AbstractRelationship implements
Serializable, Relationship {
private static final long serialVersionUID = 238786848828528822L;
private static final Logger logger = LoggerFactory
.getLogger(MutableRelationship.class);
private final Column[] _primaryColumns;
private final 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);
MutableRelationship relation = new MutableRelationship(primaryColumns,
foreignColumns);
if (primaryTable instanceof MutableTable) {
try {
((MutableTable) primaryTable).addRelationship(relation);
} catch (UnsupportedOperationException e) {
// this is an allowed behaviour - not all tables need to support
// this method.
logger.debug(
"primary table ({}) threw exception when adding relationship",
primaryTable);
}
// Ticket #144: Some tables have relations with them selves and then
// the
// relationship should only be added once.
if (foreignTable != primaryTable
&& foreignTable instanceof MutableTable) {
try {
((MutableTable) foreignTable).addRelationship(relation);
} catch (UnsupportedOperationException e) {
// this is an allowed behaviour - not all tables need to
// support this method.
logger.debug(
"foreign table ({}) threw exception when adding relationship",
foreignTable);
}
}
}
return relation;
}
public void remove() {
Table primaryTable = getPrimaryTable();
if (primaryTable instanceof MutableTable) {
((MutableTable) primaryTable).removeRelationship(this);
}
Table foreignTable = getForeignTable();
if (foreignTable instanceof MutableTable) {
((MutableTable) foreignTable).removeRelationship(this);
}
}
@Override
protected void finalize() throws Throwable {
super.finalize();
remove();
}
public static Relationship createRelationship(Column primaryColumn,
Column foreignColumn) {
return createRelationship(new Column[] { primaryColumn },
new Column[] { foreignColumn });
}
/**
* Prevent external instantiation
*/
private MutableRelationship(Column[] primaryColumns, Column[] foreignColumns) {
_primaryColumns = primaryColumns;
_foreignColumns = foreignColumns;
}
@Override
public Column[] getPrimaryColumns() {
return _primaryColumns;
}
@Override
public Column[] getForeignColumns() {
return _foreignColumns;
}
}