if (hasNonNullElements(identity)) {
// iterate nodes to find match
Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath);
boolean found = false;
while (rowPointers.hasNext()) {
Pointer jxp = (Pointer) rowPointers.next();
JXPathContext rowContext = repeaterContext.getRelativeContext(jxp);
List contextIdentity = getIdentity(rowContext);
if (ListUtils.isEqualList(identity, contextIdentity)) {
// match! --> bind to children
this.rowBinding.saveFormToModel(thisRow, rowContext);
// --> store rowIdValue in list of updatedRowIds
updatedRows.add(identity);
found = true;
break;
}
}
if (!found) {
// this is a new row
rowsToInsert.add(thisRow);
// also add it to the updated row id's so that this row doesn't get deleted
updatedRows.add(identity);
}
} else {
// if there is no value to determine the identity --> this is a new row
rowsToInsert.add(thisRow);
}
}
// Iterate again nodes for deletion
Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath);
List rowsToDelete = new ArrayList();
while (rowPointers.hasNext()) {
Pointer jxp = (Pointer)rowPointers.next();
JXPathContext rowContext = repeaterContext.getRelativeContext((Pointer)jxp.clone());
List contextIdentity = getIdentity(rowContext);
// check if the identity of the rowContext is in the updated rows
// if not --> bind for delete
if (!isIdentityInUpdatedRows(updatedRows, contextIdentity)) {
rowsToDelete.add(rowContext);
}
}
if (rowsToDelete.size() > 0) {
if (this.deleteRowBinding != null) {
// run backwards through the list, so that we don't get into
// trouble by shifting indexes
for (int i = rowsToDelete.size() - 1; i >= 0; i--) {
this.deleteRowBinding.saveFormToModel(frmModel,
rowsToDelete.get(i));
}
} else {
if (getLogger().isWarnEnabled()) {
getLogger().warn(
"RepeaterBinding has detected rows to delete, " +
"but misses the <on-delete-row> binding to do it."
);
}
}
}
// count how many we have now
int indexCount = 1;
rowPointers = repeaterContext.iteratePointers(this.rowPathForInsert);
while (rowPointers.hasNext()) {
rowPointers.next();
indexCount++;
}
// end with rows to insert (to make sure they don't get deleted!)
if (rowsToInsert.size() > 0) {
if (this.insertRowBinding != null) {
Iterator rowIterator = rowsToInsert.iterator();
//register the factory!
while (rowIterator.hasNext()) {
Repeater.RepeaterRow thisRow = (Repeater.RepeaterRow)rowIterator.next();
// Perform the insert row binding.
this.insertRowBinding.saveFormToModel(repeater, repeaterContext);
// --> create the path to let the context be created
Pointer newRowContextPointer = repeaterContext.createPath(
this.rowPathForInsert + "[" + indexCount + "]");
JXPathContext newRowContext =
repeaterContext.getRelativeContext(newRowContextPointer);
if (getLogger().isDebugEnabled()) {
getLogger().debug("inserted row at " + newRowContextPointer.asPath());
}
// + rebind to children for update
this.rowBinding.saveFormToModel(thisRow, newRowContext);
getLogger().debug("bound new row");
indexCount++;