* @throws NamingException if there is an error reading entries.
*/
private void refreshTaskDidProgress(NodeRefresher task,
NodeRefresher.State oldState,
NodeRefresher.State newState) throws NamingException {
BasicNode node = task.getNode();
boolean nodeChanged = false;
//task.dump();
// Manage events
if (oldState == NodeRefresher.State.QUEUED) {
checkUpdateEvent(true);
}
if (task.isInFinalState()) {
checkUpdateEvent(false);
}
if (newState == NodeRefresher.State.FAILED) {
// In case of NameNotFoundException, we simply remove the node from the
// tree.
// Except when it's due a to referral resolution: we keep the node
// in order the user can fix the referral.
if (isNameNotFoundException(task.getException()) &&
(oldState != NodeRefresher.State.SOLVING_REFERRAL)) {
removeOneNode(node);
}
else {
if (oldState == NodeRefresher.State.SOLVING_REFERRAL)
{
node.setRemoteUrl(task.getRemoteUrl());
if (task.getRemoteEntry() != null)
{
/* This is the case when there are multiple hops in the referral
and so we have a remote referral entry but not the entry that it
points to */
updateNodeRendering(node, task.getRemoteEntry());
}
/* It is a referral and we try to follow referrals.
We remove its children (that are supposed to be
entries on the remote server).
If this referral entry has children locally (even if this goes
against the recommendation of the standards) these children will
NOT be displayed. */
node.setLeaf(true);
removeAllChildNodes(node, true /* Keep suffixes */);
}
node.setError(new BasicNodeError(oldState, task.getException(),
task.getExceptionArg()));
nodeChanged = updateNodeRendering(node, task.getDisplayedEntry());
}
}
else if ((newState == NodeRefresher.State.CANCELLED) &&
(newState == NodeRefresher.State.INTERRUPTED)) {
// Let's collapse task.getNode()
tree.collapsePath(new TreePath(treeModel.getPathToRoot(node)));
// TODO: should we reflect this situation visually ?
}
else {
if ((oldState != NodeRefresher.State.SEARCHING_CHILDREN) &&
(newState == NodeRefresher.State.SEARCHING_CHILDREN)) {
// The children search is going to start
if (canDoDifferentialUpdate(task)) {
Enumeration<?> e = node.children();
while (e.hasMoreElements()) {
BasicNode child = (BasicNode)e.nextElement();
child.setObsolete(true);
}
}
else {
removeAllChildNodes(node, true /* Keep suffixes */);
}
}
if (oldState == NodeRefresher.State.READING_LOCAL_ENTRY) {
/* The task is going to try to solve the referral if there's one.
If succeeds we will update the remote url. Set it to null for
the case when there was a referral and it has been deleted */
node.setRemoteUrl((String)null);
SearchResult localEntry = task.getLocalEntry();
nodeChanged = updateNodeRendering(node, localEntry);
}
else if (oldState == NodeRefresher.State.SOLVING_REFERRAL) {
node.setRemoteUrl(task.getRemoteUrl());
updateNodeRendering(node, task.getRemoteEntry());
nodeChanged = true;
}
else if (oldState == NodeRefresher.State.DETECTING_CHILDREN) {
if (node.isLeaf() != task.isLeafNode()) {
node.setLeaf(task.isLeafNode());
updateNodeRendering(node, task.getDisplayedEntry());
nodeChanged = true;
if (node.isLeaf()) {
/* We didn't detect any child: remove the previously existing
* ones */
removeAllChildNodes(node, false /* Remove suffixes */);
}
}
}
else if (oldState == NodeRefresher.State.SEARCHING_CHILDREN) {
updateChildNodes(task);
if (newState == NodeRefresher.State.FINISHED) {
// The children search is finished
if (canDoDifferentialUpdate(task)) {
// Remove obsolete child nodes
// Note: we scan in the reverse order to preserve indexes
for (int i = node.getChildCount()-1; i >= 0; i--) {
BasicNode child = (BasicNode)node.getChildAt(i);
if (child.isObsolete()) {
removeOneNode(child);
}
}
}
// The node may have become a leaf.