Merge pull request #2 from ogf/master
Improve create/reload bindings situation
This commit is contained in:
commit
cc7f0388b9
10 changed files with 125 additions and 58 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ public interface ITab {
|
|||
|
||||
void show();
|
||||
|
||||
void showWithoutAfterCreate();
|
||||
|
||||
void hide();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,11 +53,6 @@ public class TabProxy implements ITab {
|
|||
proxiedTab.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showWithoutAfterCreate() {
|
||||
proxiedTab.showWithoutAfterCreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCssClass() {
|
||||
return proxiedTab.getCssClass();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -471,8 +471,7 @@ public class MultipleTabsPlannerController implements Composer,
|
|||
|
||||
@Override
|
||||
public void goToOrdersList() {
|
||||
// ordersTab.show();
|
||||
getTabsRegistry().showWithoutAfterCreate(ordersTab);
|
||||
getTabsRegistry().show(ordersTab);
|
||||
}
|
||||
|
||||
public void goToCreateForm() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -140,13 +140,4 @@ public class TabOnModeType implements ITab {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showWithoutAfterCreate() {
|
||||
beingShown = true;
|
||||
ITab currentTab = getCurrentTab();
|
||||
if (currentTab != null) {
|
||||
currentTab.showWithoutAfterCreate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue