Allow to provide several strategies for saving TaskSources

Sometimes saving must not be done

FEA: ItEr75S11PreventLooseChanges
This commit is contained in:
Óscar González Fernández 2011-09-08 11:33:05 +02:00
parent b84455ab41
commit 3a491ae276
5 changed files with 114 additions and 56 deletions

View file

@ -66,14 +66,83 @@ public class TaskSource extends BaseEntity {
return new TaskSourceMustBeRemoved(taskSource);
}
public static abstract class TaskSourceSynchronization {
public interface IOptionalPersistence {
public TaskElement apply(ITaskSourceDAO taskSourceDAO) {
return apply(taskSourceDAO, true);
public void save(TaskSource taskSource);
public void remove(TaskSource taskSource);
}
public static IOptionalPersistence persistTaskSources(
ITaskSourceDAO taskSourceDAO) {
return new RealPersistence(taskSourceDAO, true);
}
public static IOptionalPersistence persistButDontRemoveTaskSources(
ITaskSourceDAO taskSourceDAO) {
return new RealPersistence(taskSourceDAO, false);
}
public static IOptionalPersistence dontPersist() {
return new NoPersistence();
}
private static class RealPersistence implements IOptionalPersistence {
private final ITaskSourceDAO taskSourceDAO;
private final boolean removeTaskSources;
public RealPersistence(ITaskSourceDAO taskSourceDAO,
boolean removeTaskSources) {
Validate.notNull(taskSourceDAO);
this.taskSourceDAO = taskSourceDAO;
this.removeTaskSources = removeTaskSources;
}
public abstract TaskElement apply(ITaskSourceDAO taskSourceDAO,
boolean preexistent);
@Override
public void save(TaskSource taskSource) {
taskSourceDAO.saveWithoutValidating(taskSource);
}
@Override
public void remove(TaskSource taskSource) {
if (!removeTaskSources) {
return;
}
try {
taskSourceDAO.remove(taskSource.getId());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
// Flushing is required in order to avoid violation of
// unique
// constraint. If flush is not done and there is a task
// source
// that must be removed and another is created for the same
// order element the unique constraint
// "tasksource_orderelement_key" would be violated by
// hibernate
taskSourceDAO.flush();
}
}
private static class NoPersistence implements IOptionalPersistence {
@Override
public void save(TaskSource taskSource) {
}
@Override
public void remove(TaskSource taskSource) {
}
}
public static abstract class TaskSourceSynchronization {
public abstract TaskElement apply(IOptionalPersistence persistence);
}
static class TaskSourceMustBeAdded extends TaskSourceSynchronization {
@ -85,11 +154,10 @@ public class TaskSource extends BaseEntity {
}
@Override
public TaskElement apply(ITaskSourceDAO taskSourceDAO,
boolean preexistent) {
public TaskElement apply(IOptionalPersistence persistence) {
Task result = Task.createTask(taskSource);
taskSource.setTask(result);
taskSourceDAO.saveWithoutValidating(taskSource);
persistence.save(taskSource);
return result;
}
}
@ -103,11 +171,10 @@ public class TaskSource extends BaseEntity {
}
@Override
public TaskElement apply(ITaskSourceDAO taskSourceDAO,
boolean preeexistent) {
public TaskElement apply(IOptionalPersistence persistence) {
updateTaskWithOrderElement(taskSource.getTask(), taskSource.getOrderElement());
updatePositionRestrictions();
taskSourceDAO.saveWithoutValidating(taskSource);
persistence.save(taskSource);
return taskSource.getTask();
}
@ -169,17 +236,15 @@ public class TaskSource extends BaseEntity {
}
@Override
public TaskElement apply(ITaskSourceDAO taskSourceDAO,
boolean preexistent) {
List<TaskElement> children = getChildren(taskSourceDAO, preexistent);
return apply(taskSourceDAO, children, preexistent);
public TaskElement apply(IOptionalPersistence persistence) {
List<TaskElement> children = getChildren(persistence);
return apply(children, persistence);
}
private List<TaskElement> getChildren(ITaskSourceDAO taskSourceDAO,
boolean preexistent) {
private List<TaskElement> getChildren(IOptionalPersistence persistence) {
List<TaskElement> result = new ArrayList<TaskElement>();
for (TaskSourceSynchronization each : synchronizations) {
TaskElement t = each.apply(taskSourceDAO, preexistent);
TaskElement t = each.apply(persistence);
if (t != null) {
// TaskSourceMustBeRemoved gives null
result.add(t);
@ -188,8 +253,8 @@ public class TaskSource extends BaseEntity {
return result;
}
protected abstract TaskElement apply(ITaskSourceDAO taskSourceDAO,
List<TaskElement> children, boolean preexistent);
protected abstract TaskElement apply(List<TaskElement> children,
IOptionalPersistence persistence);
}
static class TaskGroupMustBeAdded extends TaskGroupSynchronization {
@ -200,14 +265,14 @@ public class TaskSource extends BaseEntity {
}
@Override
protected TaskElement apply(ITaskSourceDAO taskSourceDAO,
List<TaskElement> children, boolean preexistent) {
protected TaskElement apply(List<TaskElement> children,
IOptionalPersistence persistence) {
TaskGroup result = TaskGroup.create(taskSource);
for (TaskElement taskElement : children) {
result.addTaskElement(taskElement);
}
taskSource.setTask(result);
taskSourceDAO.saveWithoutValidating(taskSource);
persistence.save(taskSource);
return result;
}
@ -222,12 +287,12 @@ public class TaskSource extends BaseEntity {
}
@Override
protected TaskElement apply(ITaskSourceDAO taskSourceDAO,
List<TaskElement> children, boolean preexistent) {
protected TaskElement apply(List<TaskElement> children,
IOptionalPersistence persistence) {
TaskGroup taskGroup = (TaskGroup) taskSource.getTask();
taskGroup.setTaskChildrenTo(children);
updateTaskWithOrderElement(taskGroup, taskSource.getOrderElement());
taskSourceDAO.saveWithoutValidating(taskSource);
persistence.save(taskSource);
return taskGroup;
}
}
@ -241,26 +306,10 @@ public class TaskSource extends BaseEntity {
}
@Override
public TaskElement apply(ITaskSourceDAO taskSourceDAO,
boolean preexistent) {
public TaskElement apply(IOptionalPersistence optionalPersistence) {
taskSource.getTask().detachFromDependencies();
taskSource.getTask().detachFromParent();
if (preexistent) {
try {
taskSourceDAO.remove(taskSource.getId());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
// Flushing is required in order to avoid violation of
// unique
// constraint. If flush is not done and there is a task
// source
// that must be removed and another is created for the same
// order element the unique constraint
// "tasksource_orderelement_key" would be violated by
// hibernate
taskSourceDAO.flush();
}
optionalPersistence.remove(taskSource);
return null;
}

View file

@ -162,7 +162,7 @@ public class ResourceAllocationDAOTest {
hoursGroups);
TaskSourceSynchronization synchronization = TaskSource
.mustAdd(taskSource);
synchronization.apply(taskSourceDAO);
synchronization.apply(TaskSource.persistTaskSources(taskSourceDAO));
Task task = (Task) taskSource.getTask();
if (ResourceAllocationType.SPECIFIC_RESOURCE_ALLOCATION.equals(type)) {
SpecificResourceAllocation specificResourceAllocation = SpecificResourceAllocation

View file

@ -59,6 +59,7 @@ import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.SchedulingDataForVersion;
import org.navalplanner.business.orders.entities.TaskSource;
import org.navalplanner.business.orders.entities.TaskSource.IOptionalPersistence;
import org.navalplanner.business.orders.entities.TaskSource.TaskGroupSynchronization;
import org.navalplanner.business.orders.entities.TaskSource.TaskSourceSynchronization;
import org.navalplanner.business.planner.daos.ISubcontractedTaskDataDAO;
@ -157,7 +158,7 @@ public class TaskElementDAOTest {
TaskSource taskSource = TaskSource.create(schedulingDataForVersion,
Arrays.asList(associatedHoursGroup));
TaskSourceSynchronization mustAdd = TaskSource.mustAdd(taskSource);
mustAdd.apply(taskSourceDAO);
mustAdd.apply(TaskSource.persistTaskSources(taskSourceDAO));
Task task = (Task) taskSource.getTask();
return task;
}
@ -202,8 +203,8 @@ public class TaskElementDAOTest {
taskSource, Collections.<TaskSourceSynchronization> emptyList()) {
@Override
protected TaskElement apply(ITaskSourceDAO taskSourceDAO,
List<TaskElement> children, boolean preexistent) {
protected TaskElement apply(List<TaskElement> children,
IOptionalPersistence persistence) {
TaskGroup result = TaskGroup.create(taskSource);
Date today = new Date();
result.setStartDate(today);
@ -214,7 +215,7 @@ public class TaskElementDAOTest {
}
};
synchronization.apply(taskSourceDAO);
synchronization.apply(TaskSource.persistTaskSources(taskSourceDAO));
return (TaskGroup) taskSource.getTask();
}

View file

@ -60,6 +60,7 @@ import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.orders.entities.TaskSource;
import org.navalplanner.business.orders.entities.TaskSource.IOptionalPersistence;
import org.navalplanner.business.orders.entities.TaskSource.TaskSourceSynchronization;
import org.navalplanner.business.planner.daos.ITaskElementDAO;
import org.navalplanner.business.planner.daos.ITaskSourceDAO;
@ -558,6 +559,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
calculateAndSetTotalHours();
orderDAO.save(order);
reattachCurrentTaskSources();
if (newOrderVersionNeeded) {
OrderVersion newVersion = OrderVersion
.createInitialVersion(currentScenario);
@ -565,13 +567,15 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
order.writeSchedulingDataChangesTo(currentScenario, newVersion);
createAndSaveNewOrderVersion(scenarioManager.getCurrent(),
newVersion);
synchronizeWithSchedule(order, false);
synchronizeWithSchedule(order,
TaskSource.persistButDontRemoveTaskSources(taskSourceDAO));
order.writeSchedulingDataChanges();
} else {
OrderVersion orderVersion = order.getCurrentVersionInfo()
.getOrderVersion();
orderVersion.savingThroughOwner();
synchronizeWithSchedule(order, true);
synchronizeWithSchedule(order,
TaskSource.persistTaskSources(taskSourceDAO));
order.writeSchedulingDataChanges();
}
saveDerivedScenarios();
@ -697,11 +701,12 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
}
private void synchronizeWithSchedule(OrderElement orderElement,
boolean preexistent) {
IOptionalPersistence persistence) {
List<TaskSourceSynchronization> synchronizationsNeeded = orderElement
.calculateSynchronizationsNeeded();
for (TaskSourceSynchronization each : synchronizationsNeeded) {
each.apply(taskSourceDAO, preexistent);
each.apply(persistence);
}
}

View file

@ -50,6 +50,8 @@ import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderStatusEnum;
import org.navalplanner.business.orders.entities.TaskSource;
import org.navalplanner.business.orders.entities.TaskSource.IOptionalPersistence;
import org.navalplanner.business.orders.entities.TaskSource.TaskSourceSynchronization;
import org.navalplanner.business.planner.daos.ITaskSourceDAO;
import org.navalplanner.business.scenarios.daos.IScenarioDAO;
@ -219,7 +221,8 @@ public class SubcontractServiceREST implements ISubcontractService {
order.setCustomerReference(subcontractedTaskDataDTO.subcontractedCode);
order.setWorkBudget(subcontractedTaskDataDTO.subcontractPrice);
synchronizeWithSchedule(order, true);
synchronizeWithSchedule(order,
TaskSource.persistTaskSources(taskSourceDAO));
order.writeSchedulingDataChanges();
order.validate();
@ -227,11 +230,11 @@ public class SubcontractServiceREST implements ISubcontractService {
}
private void synchronizeWithSchedule(OrderElement orderElement,
boolean preexistent) {
IOptionalPersistence persistence) {
List<TaskSourceSynchronization> synchronizationsNeeded = orderElement
.calculateSynchronizationsNeeded();
for (TaskSourceSynchronization each : synchronizationsNeeded) {
each.apply(taskSourceDAO, preexistent);
each.apply(persistence);
}
}