// and validate the reader/writer schema sets.
// If no matching family/column exists in the reference layout the newly create column is valid.
for (FamilyLayout flayout : layout.getFamilies()) {
final ColumnId lgid = flayout.getLocalityGroup().getId();
LocalityGroupLayout refLGLayout = null;
if (reference != null) {
// If there is a reference layout, check for a locality group matching the ID of the LG for
// this family. Locality Group IDs should not change between layouts.
final String refLGName = reference.getLocalityGroupIdNameMap().get(lgid);
if (refLGName != null) {
// If there is a matching reference LG get its layout by name.
refLGLayout = reference.getLocalityGroupMap().get(refLGName);
}
}
// The ColumnId of the FamilyLayout from the table layout. Also matches the FamilyLayout for
// this family in the reference layout if present.
final ColumnId familyId = flayout.getId();
if (flayout.isMapType()) {
// If the family is map-type, get the CellSchema for all values in the family.
final CellSchema cellSchema = flayout.getDesc().getMapSchema();
FamilyLayout refFamilyLayout = null;
if (refLGLayout != null) {
// If there is a matching reference LG, check for the existence of this family.
final String refFamilyName = refLGLayout.getFamilyIdNameMap().get(familyId);
if (refFamilyName != null) {
refFamilyLayout = refLGLayout.getFamilyMap().get(refFamilyName);
}
}
if (refFamilyLayout != null) {
if (refFamilyLayout.isMapType()) {
// If the FamilyLayout from both table layouts are map type, compare their CellSchemas.
final CellSchema refCellSchema = refFamilyLayout.getDesc().getMapSchema();
incompatabilityMessages.addAll(addColumnNamestoIncompatibilityMessages(
flayout.getName(), null, validateCellSchema(refCellSchema, cellSchema)));
} else if (refFamilyLayout.isGroupType()) {
// If the FamilyLayout changed from group-type to map-type between table layout versions
// that is an incompatible change.
incompatabilityMessages.add(String.format(
"Family: %s changed from group-type to map-type.", refFamilyLayout.getName()));
} else {
throw new InternalKijiError(String.format(
"Family: %s is neither map-type nor group-type.", refFamilyLayout.getName()));
}
} else {
// If the reference FamilyLayout is null this indicates a new family, which is inherently
// compatible, but we still have to validate that the new readers and writers are
// internally compatible.
incompatabilityMessages.addAll(addColumnNamestoIncompatibilityMessages(
flayout.getName(), null, validateCellSchema(null, cellSchema)));
}
} else if (flayout.isGroupType()) {
// Check for a matching family from the reference layout.
FamilyLayout refFamilyLayout = null;
if (refLGLayout != null) {
final String refFamilyName = refLGLayout.getFamilyIdNameMap().get(familyId);
if (refFamilyName != null) {
refFamilyLayout = refLGLayout.getFamilyMap().get(refFamilyName);
}
}
if (refFamilyLayout != null) {
if (refFamilyLayout.isGroupType()) {