From 2b3417af5639da76768b7b465cc4e664d65822f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Thu, 20 May 2010 18:07:38 +0200 Subject: [PATCH] ItEr58S14RecalculosConexionEscenariosItEr57S15: Add feedback. Progress information is shown when doing reassignations. --- .../ganttz/util/LongOperationFeedback.java | 8 ++ .../web/common/ITemplateModel.java | 7 +- .../web/common/TemplateController.java | 12 +- .../web/common/TemplateModel.java | 124 +++++++++++++++++- .../web/scenarios/ScenarioCRUDController.java | 16 ++- 5 files changed, 152 insertions(+), 15 deletions(-) diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java index 0d0c886f2..bbf3e2f7e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java @@ -108,6 +108,14 @@ public class LongOperationFeedback { private static final ExecutorService executor = Executors .newCachedThreadPool(); + public static IDesktopUpdatesEmitter doNothingEmitter() { + return new IDesktopUpdatesEmitter() { + @Override + public void doUpdate(T value) { + } + }; + } + public static IBackGroundOperation withAsyncUpates( final IBackGroundOperation backgroundOperation) { return new IBackGroundOperation() { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ITemplateModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ITemplateModel.java index 5cdd52e19..f50f9852e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ITemplateModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ITemplateModel.java @@ -35,6 +35,11 @@ public interface ITemplateModel { Scenario getScenarioByName(String name); - void setScenario(String loginName, Scenario scenario); + public interface IOnFinished { + public void onWithoutErrorFinish(); + } + + void setScenario(String loginName, Scenario scenario, + IOnFinished onFinish); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateController.java index 9f915b730..6798ba0e9 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateController.java @@ -25,6 +25,7 @@ import java.util.List; import org.navalplanner.business.scenarios.IScenarioManager; import org.navalplanner.business.scenarios.entities.Scenario; +import org.navalplanner.web.common.ITemplateModel.IOnFinished; import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch; import org.navalplanner.web.security.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -82,10 +83,13 @@ public class TemplateController extends GenericForwardComposer { .getSelectedElement(); templateModel.setScenario(SecurityUtils.getSessionUserLoginName(), - scenario); - - window.setVisible(false); - Executions.sendRedirect("/"); + scenario, new IOnFinished() { + @Override + public void onWithoutErrorFinish() { + window.setVisible(false); + Executions.sendRedirect("/"); + } + }); } public void cancel() { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java index b6e3562ad..f5cdf3ffc 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java @@ -20,6 +20,8 @@ package org.navalplanner.web.common; +import static org.navalplanner.business.i18n.I18nHelper._; + import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -29,6 +31,8 @@ import java.util.Set; import java.util.Map.Entry; import org.apache.commons.lang.Validate; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.IOnTransaction; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.orders.entities.TaskSource; @@ -64,6 +68,14 @@ import org.zkoss.ganttz.data.GanttDiagramGraph.PointType; import org.zkoss.ganttz.data.GanttDiagramGraph.TaskPoint; import org.zkoss.ganttz.data.constraint.Constraint; import org.zkoss.ganttz.data.constraint.DateConstraint; +import org.zkoss.ganttz.util.LongOperationFeedback; +import org.zkoss.ganttz.util.LongOperationFeedback.IBackGroundOperation; +import org.zkoss.ganttz.util.LongOperationFeedback.IDesktopUpdate; +import org.zkoss.ganttz.util.LongOperationFeedback.IDesktopUpdatesEmitter; +import org.zkoss.zk.ui.Desktop; +import org.zkoss.zk.ui.Execution; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.util.Clients; /** * Model to manage UI operations from main template. @@ -333,6 +345,9 @@ public class TemplateModel implements ITemplateModel { @Autowired private IResourceDAO resourceDAO; + @Autowired + private IAdHocTransactionService transactionService; + @Override @Transactional(readOnly = true) public List getScenarios() { @@ -351,11 +366,16 @@ public class TemplateModel implements ITemplateModel { @Override @Transactional - public void setScenario(String loginName, Scenario scenario) { - Scenario scenarioReloaded = scenarioDAO.findExistingEntity(scenario - .getId()); + public void setScenario(String loginName, Scenario scenario, + IOnFinished onFinish) { + Scenario scenarioReloaded = reloadScenario(scenario); associateToUser(scenarioReloaded, findUserByLoginName(loginName)); - doReassignations(scenarioReloaded); + doReassignations(scenarioReloaded, onFinish); + } + + private Scenario reloadScenario(Scenario scenario) { + return scenarioDAO.findExistingEntity(scenario + .getId()); } private User findUserByLoginName(String loginName) { @@ -374,9 +394,75 @@ public class TemplateModel implements ITemplateModel { customUser.setScenario(scenario); } - private void doReassignations(Scenario scenario) { + private void doReassignations(final Scenario scenario, + IOnFinished onFinish) { + if (isOnZKExecution()) { + doReassignationsWithFeedback(getDesktop(), scenario, onFinish); + } else { + doReassignations(scenario, LongOperationFeedback + . doNothingEmitter()); + onFinish.onWithoutErrorFinish(); + } + } + + private boolean isOnZKExecution() { + Execution current = Executions.getCurrent(); + return current != null && current.getDesktop() != null; + } + + private Desktop getDesktop() { + Execution current = Executions.getCurrent(); + return current.getDesktop(); + } + + private void doReassignationsWithFeedback(Desktop desktop, + final Scenario scenario, + final IOnFinished onFinish) { + IBackGroundOperation reassignations = new IBackGroundOperation() { + @Override + public void doOperation( + final IDesktopUpdatesEmitter desktopUpdateEmitter) { + try { + transactionService + .runOnTransaction(new IOnTransaction() { + @Override + public Void execute() { + doReassignations(reloadScenario(scenario), + desktopUpdateEmitter); + return null; + } + }); + } finally { + desktopUpdateEmitter.doUpdate(showEnd()); + } + desktopUpdateEmitter.doUpdate(executeFinish(onFinish)); + } + }; + LongOperationFeedback.progressive(desktop, LongOperationFeedback + .withAsyncUpates(reassignations)); + } + + private IDesktopUpdate executeFinish( + final IOnFinished onFinish) { + return new IDesktopUpdate() { + + @Override + public void doUpdate() { + onFinish.onWithoutErrorFinish(); + } + }; + } + + + private void doReassignations(Scenario scenario, + IDesktopUpdatesEmitter emitter) { List> needingReassignation = scenario .getOrderVersionsNeedingReassignation(); + final int total = needingReassignation.size(); + if (!needingReassignation.isEmpty()) { + emitter.doUpdate(showStart(total)); + } + int i = 1; for (Entry each : needingReassignation) { OrderVersion orderVersion = each.getValue(); Order order = each.getKey(); @@ -387,10 +473,38 @@ public class TemplateModel implements ITemplateModel { orderVersion.savingThroughOwner(); orderVersionDAO.save(orderVersion); } + emitter.doUpdate(showProgress(total - i)); } } + private IDesktopUpdate showStart(final int ordersNumber) { + return sendMessage(_("Reassigning {0} orders", ordersNumber)); + } + + private IDesktopUpdate showProgress(int remaining) { + return sendMessage(_("{0} orders reassignation remaining", remaining)); + } + + private IDesktopUpdate sendMessage(final String message) { + return new IDesktopUpdate() { + @Override + public void doUpdate() { + Clients.showBusy(message, true); + } + }; + } + + private IDesktopUpdate showEnd() { + return new IDesktopUpdate() { + + @Override + public void doUpdate() { + Clients.showBusy(null, false); + } + }; + } + private void doReassignationsOn(Order order, Scenario from, Scenario to) { copyAssignments(order, from, to); installDependenciesEnforcer(order, new Adapter(to)); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/scenarios/ScenarioCRUDController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/scenarios/ScenarioCRUDController.java index a1098c589..2f93344d3 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/scenarios/ScenarioCRUDController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/scenarios/ScenarioCRUDController.java @@ -37,6 +37,7 @@ import org.navalplanner.web.common.Level; import org.navalplanner.web.common.MessagesForUser; import org.navalplanner.web.common.OnlyOneVisible; import org.navalplanner.web.common.Util; +import org.navalplanner.web.common.ITemplateModel.IOnFinished; import org.navalplanner.web.security.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.zkoss.zk.ui.Component; @@ -149,7 +150,7 @@ public class ScenarioCRUDController extends GenericForwardComposer { public class ScenariosTreeitemRenderer implements TreeitemRenderer { @Override - public void render(Treeitem item, Object data) throws Exception { + public void render(final Treeitem item, Object data) throws Exception { SimpleTreeNode simpleTreeNode = (SimpleTreeNode) data; final Scenario scenario = (Scenario) simpleTreeNode.getData(); item.setValue(data); @@ -225,11 +226,16 @@ public class ScenarioCRUDController extends GenericForwardComposer { private void connectTo(Scenario scenario) { templateModel.setScenario(SecurityUtils - .getSessionUserLoginName(), scenario); - - Executions.sendRedirect("/scenarios/scenarios.zul"); + .getSessionUserLoginName(), + scenario, + new IOnFinished() { + @Override + public void onWithoutErrorFinish() { + Executions + .sendRedirect("/scenarios/scenarios.zul"); + } + }); } - }); if (isCurrentScenario) { connectButton.setDisabled(true);