Merge pull request #2 from ogf/master

Improve create/reload bindings situation
This commit is contained in:
Manuel Rego Casasnovas 2012-12-11 07:55:43 -08:00
commit cc7f0388b9
10 changed files with 125 additions and 58 deletions

View file

@ -65,23 +65,10 @@ public class TabsRegistry {
show(tab, DO_NOTHING);
}
public void showWithoutAfterCreate(ITab tab) {
show(tab, DO_NOTHING, false);
}
public void show(ITab tab, IBeforeShowAction beforeShowAction) {
show(tab, beforeShowAction, true);
}
private void show(ITab tab, IBeforeShowAction beforeShowAction,
boolean afterCreate) {
hideAllExcept(tab);
beforeShowAction.doAction();
if (afterCreate) {
tab.show();
} else {
tab.showWithoutAfterCreate();
}
tab.show();
parent.invalidate();
activateMenuIfRegistered(tab);
}

View file

@ -37,8 +37,6 @@ public interface ITab {
void show();
void showWithoutAfterCreate();
void hide();
}

View file

@ -53,11 +53,6 @@ public class TabProxy implements ITab {
proxiedTab.show();
}
@Override
public void showWithoutAfterCreate() {
proxiedTab.showWithoutAfterCreate();
}
@Override
public String getCssClass() {
return proxiedTab.getCssClass();

View file

@ -27,9 +27,12 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
@ -85,18 +88,103 @@ public class Util {
private static final String[] DECIMAL_FORMAT_SPECIAL_CHARS = { "0", ",",
".", "\u2030", "%", "#", ";", "-" };
private static final String RELOADED_COMPONENTS_ATTR = Util.class.getName()
+ ":" + "reloaded";
private Util() {
}
/**
* Forces to reload the bindings of the provided components if there is an
* associated {@link DataBinder}.
*
* @param toReload
* the components to reload
*/
public static void reloadBindings(Component... toReload) {
reloadBindings(ReloadStrategy.FORCE, toReload);
}
public enum ReloadStrategy {
/**
* If the {@link DataBinder} exists the bindings are reloaded no matter
* what.
*/
FORCE,
/**
* Once the bindings for a component have been manually loaded in one
* request, subsequent calls for reload the bindings of the same
* component or descendants using this strategy are ignored.
*/
ONE_PER_REQUEST;
public static boolean isForced(ReloadStrategy reloadStrategy) {
return reloadStrategy == ReloadStrategy.FORCE;
}
}
/**
* Reload the bindings of the provided components if there is an associated
* {@link DataBinder} and the {@link ReloadStrategy} allows it.
*
* @param toReload
* the components to reload
*/
public static void reloadBindings(ReloadStrategy reloadStrategy,
Component... toReload) {
reloadBindings(ReloadStrategy.isForced(reloadStrategy), toReload);
}
private static void reloadBindings(boolean forceReload,
Component... toReload) {
for (Component reload : toReload) {
DataBinder binder = Util.getBinder(reload);
if (binder != null) {
if (binder != null
&& (forceReload || notReloadedInThisRequest(reload))) {
binder.loadComponent(reload);
markAsReloadedForThisRequest(reload);
}
}
}
private static boolean notReloadedInThisRequest(Component reload) {
return !getReloadedComponents(reload).contains(reload);
}
private static Set<Component> getReloadedComponents(Component component) {
Execution execution = component.getDesktop().getExecution();
@SuppressWarnings("unchecked")
Set<Component> result = (Set<Component>) execution
.getAttribute(RELOADED_COMPONENTS_ATTR);
if (result == null) {
result = new HashSet<Component>();
execution.setAttribute(RELOADED_COMPONENTS_ATTR, result);
}
return result;
}
private static void markAsReloadedForThisRequest(Component component) {
Set<Component> reloadedComponents = getReloadedComponents(component);
reloadedComponents.add(component);
reloadedComponents.addAll(getAllDescendants(component));
}
private static void markAsNotReloadedForThisRequest(Component component) {
Set<Component> reloadedComponents = getReloadedComponents(component);
reloadedComponents.remove(component);
reloadedComponents.removeAll(getAllDescendants(component));
}
@SuppressWarnings("unchecked")
private static List<Component> getAllDescendants(Component component) {
List<Component> result = new ArrayList<Component>();
for (Component each : (List<Component>) component.getChildren()) {
result.add(each);
result.addAll(getAllDescendants(each));
}
return result;
}
public static void saveBindings(Component... toReload) {
for (Component reload : toReload) {
DataBinder binder = Util.getBinder(reload);
@ -110,9 +198,28 @@ public class Util {
return (DataBinder) component.getVariable("binder", false);
}
private static final ThreadLocal<Boolean> ignoreCreateBindings = new ThreadLocal<Boolean>() {
protected Boolean initialValue() {
return false;
};
};
public static void executeIgnoringCreationOfBindings(Runnable action) {
try {
ignoreCreateBindings.set(true);
action.run();
} finally {
ignoreCreateBindings.set(false);
}
}
public static void createBindingsFor(org.zkoss.zk.ui.Component result) {
if (ignoreCreateBindings.get()) {
return;
}
AnnotateDataBinder binder = new AnnotateDataBinder(result, true);
result.setVariable("binder", binder, true);
markAsNotReloadedForThisRequest(result);
}
/**

View file

@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.converters.IConverter;
import org.libreplan.web.common.converters.IConverterFactory;
import org.zkoss.zk.ui.Execution;
@ -283,20 +284,25 @@ public class EntryPointsHandler<T> {
return applyIfMatches(controller, matrixParams);
}
private <S> boolean applyIfMatches(S controller,
private <S> boolean applyIfMatches(final S controller,
Map<String, String> matrixParams) {
flagAlreadyExecutedInThisRequest();
Set<String> matrixParamsNames = matrixParams.keySet();
for (Entry<String, EntryPointMetadata> entry : metadata.entrySet()) {
EntryPointMetadata entryPointMetadata = entry.getValue();
final EntryPointMetadata entryPointMetadata = entry.getValue();
EntryPoint entryPointAnnotation = entryPointMetadata.annotation;
HashSet<String> requiredParams = new HashSet<String>(Arrays
.asList(entryPointAnnotation.value()));
if (matrixParamsNames.equals(requiredParams)) {
Object[] arguments = retrieveArguments(matrixParams,
final Object[] arguments = retrieveArguments(matrixParams,
entryPointAnnotation, entryPointMetadata.method
.getParameterTypes());
callMethod(controller, entryPointMetadata.method, arguments);
Util.executeIgnoringCreationOfBindings(new Runnable() {
public void run() {
callMethod(controller, entryPointMetadata.method,
arguments);
}
});
return true;
}
}

View file

@ -55,6 +55,7 @@ import org.libreplan.web.common.Level;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.common.OnlyOneVisible;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.Util.ReloadStrategy;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.libreplan.web.common.components.finders.FilterPair;
@ -799,7 +800,7 @@ public class OrderCRUDController extends GenericForwardComposer {
private void showWindow(Window window) {
getVisibility().showOnly(window);
Util.reloadBindings(window);
Util.reloadBindings(ReloadStrategy.ONE_PER_REQUEST, window);
}
public void reloadHoursGroupOrder() {

View file

@ -72,21 +72,9 @@ public class CreatedOnDemandTab implements ITab {
@Override
public void show() {
show(true);
}
@Override
public void showWithoutAfterCreate() {
show(false);
}
private void show(boolean afterCreate) {
beforeShowAction();
if (component == null) {
component = componentCreator.create(parent);
if (afterCreate) {
afterCreateAction(component);
}
}
component.setParent(parent);
afterShowAction();
@ -102,9 +90,6 @@ public class CreatedOnDemandTab implements ITab {
protected void beforeShowAction() {
}
protected void afterCreateAction(Component component) {
}
protected void afterShowAction() {
}

View file

@ -471,8 +471,7 @@ public class MultipleTabsPlannerController implements Composer,
@Override
public void goToOrdersList() {
// ordersTab.show();
getTabsRegistry().showWithoutAfterCreate(ordersTab);
getTabsRegistry().show(ordersTab);
}
public void goToCreateForm() {

View file

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.Map;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.Util.ReloadStrategy;
import org.libreplan.web.orders.OrderCRUDController;
import org.libreplan.web.planner.order.IOrderPlanningGate;
import org.libreplan.web.planner.tabs.CreatedOnDemandTab.IComponentCreator;
@ -68,6 +69,8 @@ public class OrdersTabCreator {
args.put("orderController", setupOrderCrudController());
result = Executions.createComponents("/orders/_ordersTab.zul",
parent, args);
Util.createBindingsFor(result);
Util.reloadBindings(ReloadStrategy.ONE_PER_REQUEST, result);
return result;
}
@ -108,11 +111,6 @@ public class OrdersTabCreator {
}
}
@Override
protected void afterCreateAction(org.zkoss.zk.ui.Component component) {
Util.createBindingsFor(component);
}
@Override
protected void afterShowAction() {
orderCRUDController.goToList();

View file

@ -140,13 +140,4 @@ public class TabOnModeType implements ITab {
}
}
@Override
public void showWithoutAfterCreate() {
beingShown = true;
ITab currentTab = getCurrentTab();
if (currentTab != null) {
currentTab.showWithoutAfterCreate();
}
}
}