constant = true;
}
// if this is not a constant join, look for existing foreign key
// on local columns
ForeignKey exist = null;
if (!constant && local.getForeignKeys().length > 0) {
Column[] cols = new Column[joins.length];
Column[] pks = new Column[joins.length];
for (int i = 0; i < joins.length; i++) {
cols[i] = (Column) joins[i][0];
pks[i] = (Column) joins[i][1];
}
ForeignKey[] fks = local.getForeignKeys();
for (int i = 0; i < fks.length; i++) {
if (fks[i].getConstantColumns().length == 0
&& fks[i].getConstantPrimaryKeyColumns().length == 0
&& fks[i].columnsMatch(cols, pks)) {
exist = fks[i];
break;
}
}
}
MappingRepository repos = (MappingRepository) context.getRepository();
DBDictionary dict = repos.getDBDictionary();
if (exist != null) {
// make existing key logical?
if (!_canFK) {
if (exist.getDeleteAction() != exist.ACTION_NONE && !adapt)
throw new MetaDataException(_loc.get(prefix
+ "-fk-exists", context));
exist.setDeleteAction(exist.ACTION_NONE);
}
if (_fk != null && _fk.isDeferred() && !exist.isDeferred()) {
Log log = repos.getLog();
if (log.isWarnEnabled())
log.warn(_loc.get(prefix + "-defer-fk", context));
}
// allow user-given info to override existing key if we're adapting;
// template info cannot override existing key
if (adapt && _fk != null) {
if (_fk.getUpdateAction() != ForeignKey.ACTION_NONE)
exist.setUpdateAction(_fk.getUpdateAction());
if (_fk.getDeleteAction() != ForeignKey.ACTION_NONE)
exist.setDeleteAction(_fk.getDeleteAction());
}
setIOFromJoins(exist, joins);
return exist;
}
String name = null;
int delAction = ForeignKey.ACTION_NONE;
int upAction = ForeignKey.ACTION_NONE;
boolean deferred = false;
boolean fill = repos.getMappingDefaults().defaultMissingInfo();
ForeignKey tmplate = (def == null) ? null
: def.get(local, foreign, _join == JOIN_INVERSE);
if (_fk != null && (tmplate == null || (!adapt && !fill))) {
// if not adapting or no template info use given data
name = _fk.getName();
delAction = _fk.getDeleteAction();
upAction = _fk.getUpdateAction();
deferred = _fk.isDeferred();
} else if (_canFK && (adapt || fill)) {
if (_fk == null && tmplate != null) {
// no user given info; use template data
name = tmplate.getName();
delAction = tmplate.getDeleteAction();
upAction = tmplate.getUpdateAction();
deferred = tmplate.isDeferred();
} else if (_fk != null && tmplate != null) {
// merge user and template data, always letting user info win
name = _fk.getName();
if (name == null && tmplate.getName() != null)
name = tmplate.getName();
delAction = _fk.getDeleteAction();
if (delAction == ForeignKey.ACTION_NONE)
delAction = tmplate.getDeleteAction();
upAction = _fk.getUpdateAction();
if (upAction == ForeignKey.ACTION_NONE)
upAction = tmplate.getUpdateAction();
deferred = _fk.isDeferred();
}
}
if (!dict.supportsDeleteAction(delAction)
|| !dict.supportsUpdateAction(upAction)) {
Log log = repos.getLog();
if (log.isWarnEnabled())
log.warn(_loc.get(prefix + "-unsupported-fk-action", context));
delAction = ForeignKey.ACTION_NONE;
upAction = ForeignKey.ACTION_NONE;
}
if (deferred && !dict.supportsDeferredConstraints) {
Log log = repos.getLog();
if (log.isWarnEnabled())
log.warn(_loc.get(prefix + "-create-defer-fk",
context, dict.platform));
deferred = false;
}
// create foreign key with merged info
ForeignKey fk = local.addForeignKey(name);
fk.setDeleteAction(delAction);
fk.setUpdateAction(upAction);
fk.setDeferred(deferred);
// add joins to key
Column col;
for (int i = 0; i < joins.length; i++) {
col = (Column) joins[i][0];
if (joins[i][1]instanceof Column)
fk.join(col, (Column) joins[i][1]);
else if ((joins[i][2] == Boolean.TRUE) != (_join == JOIN_INVERSE))
fk.joinConstant(joins[i][1], col);
else
fk.joinConstant(col, joins[i][1]);
}
setIOFromJoins(fk, joins);
return fk;
}