Table local = table;
Table foreign = rel.getTable();
boolean fullName = false;
boolean inverse = false;
if (!DBIdentifier.isNull(name)) {
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(name);
if (!DBIdentifier.isNull(path.getObjectTableName())) {
if (DBIdentifier.isEmpty(path.getObjectTableName()))
local = foreign;
else
local = findTable(context, path.getObjectTableName(),
local, foreign, null);
fullName = true;
name = path.getIdentifier().getUnqualifiedName();
// if inverse join, then swap local and foreign tables
if (local != table) {
foreign = table;
inverse = true;
}
}
}
boolean forceInverse = !fullName && _join == JOIN_INVERSE;
if (forceInverse) {
local = foreign;
foreign = table;
inverse = true;
}
// determine target
DBIdentifier targetName = given.getTargetIdentifier();
Object target = null;
Table ttable = null;
boolean constant = false;
boolean fullTarget = false;
if (DBIdentifier.isNull(targetName) && given.getTargetField() != null) {
ClassMapping tcls = (inverse) ? cls : rel;
String fieldName = given.getTargetField();
String[] names = Normalizer.splitName(fieldName);
fullTarget = names.length > 1;
if (names.length > 1 && StringUtils.isEmpty(names[0])) {
// allow use of '.' without prefix to mean "use expected local
// cls"; but if we already inversed no need to switch again
if (!inverse)
tcls = cls;
fieldName = names[1];
} else if (names.length > 1) {
// must be class + field name
tcls = findClassMapping(context, names[0], cls, rel);
fieldName = names[1];
}
if (tcls == null)
throw new MetaDataException(_loc.get(prefix
+ "-bad-fktargetcls", context, fieldName, name));
FieldMapping field = tcls.getFieldMapping(fieldName);
if (field == null)
throw new MetaDataException(_loc.get(prefix
+ "-bad-fktargetfield", new Object[]{ context, fieldName,
name, tcls }));
if (field.getColumns().length != 1)
throw new MetaDataException(_loc.get(prefix
+ "-fktargetfield-cols", context, fieldName, name));
ttable = (field.getJoinForeignKey() != null) ? field.getTable()
: field.getDefiningMapping().getTable();
targetName = field.getColumns()[0].getIdentifier();
} else if (!DBIdentifier.isNull(targetName)) {
String targetNameStr = targetName.getName();
if (targetNameStr.charAt(0) == '\'') {
constant = true;
target = targetNameStr.substring(1, targetNameStr.length() - 1);
} else if (targetNameStr.charAt(0) == '-'
|| targetNameStr.charAt(0) == '.'
|| Character.isDigit(targetNameStr.charAt(0))) {
constant = true;
try {
if (targetNameStr.indexOf('.') == -1)
target = new Integer(targetNameStr);
else
target = new Double(targetNameStr);
} catch (RuntimeException re) {
throw new MetaDataException(_loc.get(prefix
+ "-bad-fkconst", context, targetName, name));
}
} else if ("null".equalsIgnoreCase(targetNameStr))
constant = true;
else {
QualifiedDBIdentifier path = QualifiedDBIdentifier.getPath(targetName);
fullTarget = (!DBIdentifier.isNull(path.getObjectTableName()));
if (!DBIdentifier.isNull(path.getObjectTableName()) &&
DBIdentifier.isEmpty(path.getObjectTableName())) {
// allow use of '.' without prefix to mean "use expected
// local table", but ignore if we're already inversed
if (!inverse)
ttable = local;
targetName = path.getIdentifier().getUnqualifiedName();
} else if (!DBIdentifier.isNull(path.getObjectTableName())) {
ttable = findTable(context, path.getObjectTableName(), foreign, local, (inverse) ? cls : rel);
targetName = path.getIdentifier().getUnqualifiedName();
}
}
}
// use explicit target table if available