*/
@Override()
public void replaceEntry(Entry oldEntry, Entry newEntry,
ModifyOperation modifyOperation) throws DirectoryException
{
DN entryDN = newEntry.getDN();
Lock entryLock = null;
if (! taskScheduler.holdsSchedulerLock())
{
for (int i=0; i < 3; i++)
{
entryLock = LockManager.lockWrite(entryDN);
if (entryLock != null)
{
break;
}
}
if (entryLock == null)
{
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
ERR_TASKBE_MODIFY_CANNOT_LOCK_ENTRY.get(
String.valueOf(entryDN)));
}
}
try
{
// Get the parent for the provided entry DN. It must be either the
// scheduled or recurring task parent DN.
DN parentDN = entryDN.getParentDNInSuffix();
if (parentDN == null)
{
Message message =
ERR_TASKBE_MODIFY_INVALID_ENTRY.get(String.valueOf(entryDN));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
}
else if (parentDN.equals(scheduledTaskParentDN))
{
// It's a scheduled task. Make sure that it exists.
Task t = taskScheduler.getScheduledTask(entryDN);
if (t == null)
{
Message message =
ERR_TASKBE_MODIFY_NO_SUCH_TASK.get(String.valueOf(entryDN));
throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
}
// Look at the state of the task. We will allow anything to be altered
// for a pending task. For a running task, we will only allow the state
// to be altered in order to cancel it. We will not allow any
// modifications for completed tasks.
TaskState state = t.getTaskState();
if (TaskState.isPending(state) && !t.isRecurring())
{
Task newTask = taskScheduler.entryToScheduledTask(newEntry,
modifyOperation);
taskScheduler.removePendingTask(t.getTaskID());
taskScheduler.scheduleTask(newTask, true);
return;
}
else if (TaskState.isRunning(state))
{
// If the task is running, we will only allow it to be cancelled.
// This will only be allowed using the replace modification type on
// the ds-task-state attribute if the value starts with "cancel" or
// "stop". In that case, we'll cancel the task.
boolean acceptable = isReplaceEntryAcceptable(modifyOperation);
if (acceptable)
{
Message message = INFO_TASKBE_RUNNING_TASK_CANCELLED.get();
t.interruptTask(TaskState.STOPPED_BY_ADMINISTRATOR, message);
return;
}
else
{
Message message =
ERR_TASKBE_MODIFY_RUNNING.get(String.valueOf(entryDN));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
message);
}
}
else if (TaskState.isPending(state) && t.isRecurring())
{
// Pending recurring task iterations can only be canceled.
boolean acceptable = isReplaceEntryAcceptable(modifyOperation);
if (acceptable)
{
Task newTask = taskScheduler.entryToScheduledTask(newEntry,
modifyOperation);
if (newTask.getTaskState() ==
TaskState.CANCELED_BEFORE_STARTING)
{
taskScheduler.removePendingTask(t.getTaskID());
long scheduledStartTime = t.getScheduledStartTime();
long currentSystemTime = System.currentTimeMillis();
if (scheduledStartTime < currentSystemTime) {
scheduledStartTime = currentSystemTime;
}
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(scheduledStartTime);
taskScheduler.scheduleNextRecurringTaskIteration(
newTask, calendar);
}
else if (newTask.getTaskState() ==
TaskState.STOPPED_BY_ADMINISTRATOR)
{
Message message = INFO_TASKBE_RUNNING_TASK_CANCELLED.get();
t.interruptTask(TaskState.STOPPED_BY_ADMINISTRATOR, message);
}
return;
}
else
{
Message message =
ERR_TASKBE_MODIFY_RECURRING.get(String.valueOf(entryDN));
throw new DirectoryException(
ResultCode.UNWILLING_TO_PERFORM, message);
}
}
else
{
Message message =
ERR_TASKBE_MODIFY_COMPLETED.get(String.valueOf(entryDN));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
message);
}
}
else if (parentDN.equals(recurringTaskParentDN))
{
// We don't currently support altering recurring tasks.
Message message =
ERR_TASKBE_MODIFY_RECURRING.get(String.valueOf(entryDN));
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);