From 15ab96e7232bdc08107f0187d1a8cf41a8c0098c Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Wed, 28 Mar 2012 10:08:04 +0200 Subject: [PATCH] OO-198: make the IQ component "more" dynamic to prevent back button --- .../olat/core/gui/components/Component.java | 4 ++ .../core/gui/components/ComponentHelper.java | 30 +++++++++- .../org/olat/core/gui/components/Window.java | 59 +++++++++++++++---- .../java/org/olat/modules/iq/IQComponent.java | 6 +- 4 files changed, 84 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/olat/core/gui/components/Component.java b/src/main/java/org/olat/core/gui/components/Component.java index 31fed6b2156..57271c50675 100644 --- a/src/main/java/org/olat/core/gui/components/Component.java +++ b/src/main/java/org/olat/core/gui/components/Component.java @@ -413,6 +413,10 @@ public abstract class Component { public Container getParent(){ return this.parent; } + + public boolean isHighlyDynamicalCmp() { + return false; + } /** * to be used by Window.java to detect browser back in ajax-mode diff --git a/src/main/java/org/olat/core/gui/components/ComponentHelper.java b/src/main/java/org/olat/core/gui/components/ComponentHelper.java index dc798c085bb..a622517e8a6 100644 --- a/src/main/java/org/olat/core/gui/components/ComponentHelper.java +++ b/src/main/java/org/olat/core/gui/components/ComponentHelper.java @@ -26,6 +26,7 @@ package org.olat.core.gui.components; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -42,7 +43,34 @@ import org.olat.core.util.component.ComponentVisitor; * @author Felix Jost */ public class ComponentHelper { - + + + public static List<Component> findAncestorsOrSelfByID(Component startFrom, Component target) { + List<Component> ancestors = new ArrayList<Component>(); + dofindAncestors(startFrom, target, ancestors); + return ancestors; + } + + private static boolean dofindAncestors(Component current, Component target, List<Component> ancestors) { + if (target == current) { + ancestors.add(target); + return true; + } + if (current instanceof Container) { + Container co = (Container) current; + Map<String,Component> children = co.getComponents(); + for (Iterator<Component> iter = children.values().iterator(); iter.hasNext();) { + Component child = iter.next(); + boolean found = dofindAncestors(child, target, ancestors); + if (found) { + ancestors.add(current); + return found; + } + } + } + return false; + } + /** * @param startFrom * @param id diff --git a/src/main/java/org/olat/core/gui/components/Window.java b/src/main/java/org/olat/core/gui/components/Window.java index 8583faa5c00..27e85ef13ee 100644 --- a/src/main/java/org/olat/core/gui/components/Window.java +++ b/src/main/java/org/olat/core/gui/components/Window.java @@ -129,7 +129,7 @@ public class Window extends Container { private String latestTimestamp; private AsyncMediaResponsible asyncMediaResponsible; private String instanceId; - private final int timestamp = 1; // used to find out when a user has called + private int timestamp = 1; // used to find out when a user has called // back/forward/reload in the browser and to detect // asyncmedia resources @@ -220,7 +220,7 @@ public class Window extends Container { public void dispatchRequest(UserRequest ureq, boolean renderOnly) { final HttpServletRequest request = ureq.getHttpReq(); final HttpServletResponse response = ureq.getHttpResp(); - final String timestampID = "1";//ureq.getTimestampID(); + final String timestampID = ureq.getTimestampID() == null ? "1" : ureq.getTimestampID(); final String componentID = ureq.getComponentID(); // case windowId timestamp componentId @@ -259,7 +259,7 @@ public class Window extends Container { // increase the timestamp, but not if we are in loadperformancemode: then all url's have // to work independant of previous ones -> when no increase: timestamp is always the same here - boolean incTimestamp = !GUIInterna.isLoadPerformanceMode(); + boolean incTimestamp = false;//!GUIInterna.isLoadPerformanceMode(); MediaResource mr = null; final boolean isDebugLog = Tracing.isDebugEnabled(Window.class); @@ -319,7 +319,9 @@ public class Window extends Container { // 3.) return to sender... boolean didDispatch = false; if (validForDispatching) { - didDispatch = doDispatchToComponent(ureq, null); // FIXME:fj:c enable time stats for ajax-mode + DispatchResult dispatchResult = doDispatchToComponent(ureq, null); // FIXME:fj:c enable time stats for ajax-mode + didDispatch = dispatchResult.isDispatch(); + incTimestamp = dispatchResult.isHighDynamical(); if (isDebugLog) { long durationAfterDoDispatchToComponent = System.currentTimeMillis() - debug_start; Tracing.logDebug("Perf-Test: Window durationAfterDoDispatchToComponent=" + durationAfterDoDispatchToComponent, Window.class); @@ -582,7 +584,9 @@ public class Window extends Container { } if (dispatch) { - boolean didDispatch = doDispatchToComponent(ureq, debugMsg); + DispatchResult dispatchResult = doDispatchToComponent(ureq, debugMsg); + boolean didDispatch = dispatchResult.isDispatch(); + incTimestamp = dispatchResult.isHighDynamical(); if (isDebugLog) { long dstop = System.currentTimeMillis(); long diff = dstop - dstart; @@ -681,7 +685,10 @@ public class Window extends Container { String result; synchronized(render_mutex) { //o_clusterOK by:fj // render now - //TODO state-less if (incTimestamp) timestamp++; + //TODO state-less + if (incTimestamp) { + timestamp++; + } final String newTimestamp = String.valueOf(timestamp); // add the businesscontrol path for bookmarking: // each url has a part in it (the so called business path), which, in case of an invalid url or invalidated @@ -1033,9 +1040,9 @@ public class Window extends Container { * otherwise (reasons: no component found with given id, or component * disabled) */ - private boolean doDispatchToComponent(UserRequest ureq, StringBuilder debugMsg) { + private DispatchResult doDispatchToComponent(UserRequest ureq, StringBuilder debugMsg) { String s_compID = ureq.getComponentID(); - if (s_compID == null) return false; //throw new AssertException("no component id found in req:" + ureq.toString()); + if (s_compID == null) return new DispatchResult(false, false); //throw new AssertException("no component id found in req:" + ureq.toString()); Component target; @@ -1092,7 +1099,7 @@ public class Window extends Container { if (target == null) { // there was a component id given, but no matching target could be found fireEvent(ureq, COMPONENTNOTFOUND); - return false; + return new DispatchResult(false, false); // do not dispatch; which means just rerender later; good if // the // gui tree was changed by another thread in the meantime. @@ -1102,8 +1109,9 @@ public class Window extends Container { if (!target.isVisible()) { throw new OLATRuntimeException(Window.class, "target with name: '" + target.getComponentName() + "', was invisible, but called to dispatch", null); } boolean toDispatch = true; //TODO:fj:c is foundpath needed for something else than the enabled-check. if no -> one boolean is enough - for (Iterator iter = foundPath.iterator(); iter.hasNext();) { - Component curComp = (Component) iter.next(); + boolean highDynamical = false; + for (Iterator<Component> iter = foundPath.iterator(); iter.hasNext();) { + Component curComp = iter.next(); if (!curComp.isEnabled()) { toDispatch = false; break; @@ -1117,7 +1125,14 @@ public class Window extends Container { // dispatch wbackofficeImpl.fireCycleEvent(Window.ABOUT_TO_DISPATCH); target.dispatchRequest(ureq); - + + List<Component> ancestors = ComponentHelper.findAncestorsOrSelfByID(getContentPane(), target); + for(Component ancestor:ancestors) { + highDynamical |= ancestor.isHighlyDynamicalCmp(); + //System.out.println("Ancestor -> " + ancestor.getComponentName() + " :: " + ancestor); + } + //System.out.println("Target -> " + highDynamical + " :: " + target); + // after dispatching, commit (docu) DBFactory.getInstance().commit(); @@ -1170,7 +1185,7 @@ public class Window extends Container { // in case we do not reach the next line because of an exception in dispatch(), we clear the value in the exceptionwindowcontroller's error handling latestDispatchedComp = null; } - return toDispatch; + return new DispatchResult(toDispatch, highDynamical); } private List<Component> findComponentsWithChildName(final String childName, Component searchRoot) { @@ -1258,6 +1273,24 @@ public class Window extends Container { } +class DispatchResult { + private final boolean dispatch; + private final boolean highDynamical; + + public DispatchResult(boolean dispatch, boolean highDynamical) { + this.dispatch = dispatch; + this.highDynamical = highDynamical; + } + + public boolean isDispatch() { + return dispatch; + } + + public boolean isHighDynamical() { + return highDynamical; + } +} + class ValidatingVisitor implements ComponentVisitor { private ValidationResult validationResult; diff --git a/src/main/java/org/olat/modules/iq/IQComponent.java b/src/main/java/org/olat/modules/iq/IQComponent.java index 0e57f770f19..c0e3fe2a43e 100644 --- a/src/main/java/org/olat/modules/iq/IQComponent.java +++ b/src/main/java/org/olat/modules/iq/IQComponent.java @@ -85,5 +85,9 @@ public class IQComponent extends Component { public boolean provideMemoField () { return provideMemoField; } - + + @Override + public boolean isHighlyDynamicalCmp() { + return true; + } } -- GitLab