//if rowIdValue != null --> 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);
Object matchId = rowContext.getValue(this.uniqueRowIdPath);
if (matchId != null && this.uniqueRowIdConvertor != null) {
if (matchId instanceof String) {
matchId = this.uniqueRowIdConvertor.convertFromString((String)matchId, this.uniqueRowIdConvertorLocale, null);
} else {
getLogger().warn("Convertor ignored on backend-value which isn't of type String.");
}
}
if (rowIdValue.equals(matchId)) {
// match! --> bind to children
this.rowBinding.saveFormToModel(thisRow, rowContext);
// --> store rowIdValue in list of updatedRowIds
updatedRowIds.add(rowIdValue);
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
updatedRowIds.add(rowIdValue);
}
} else {
//if rowId == null --> remember to insert this one later
rowsToInsert.add(thisRow);
}
}
//again iterate 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());
Object matchId = rowContext.getValue(this.uniqueRowIdPath);
if (matchId != null && this.uniqueRowIdConvertor != null) {
if (matchId instanceof String) {
matchId = this.uniqueRowIdConvertor.convertFromString((String)matchId, this.uniqueRowIdConvertorLocale, null);
} else {
getLogger().warn("Convertor ignored on backend-value which isn't of type String.");
}
}
// check if matchPath was in list of updates, if not --> bind for delete
if (!updatedRowIds.contains(matchId)) {
rowsToDelete.add(rowContext);
}
}
if (rowsToDelete.size() > 0) {
if (this.deleteRowBinding == null) {
getLogger().warn("RepeaterBinding has detected rows to delete, " +
"but misses the <on-delete-row> binding to do it.");
}
else {
// 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));
}
}
// 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!
//this.insertRowBinding.saveFormToModel(repeater, repeaterContext);
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++;
}