use of org.olat.core.gui.render.ValidationResult in project OpenOLAT by OpenOLAT.
the class ValidatingVisitor method dispatchRequest.
/**
* @param ureq
* @param renderOnly
*/
public void dispatchRequest(UserRequest ureq, boolean renderOnly) {
final HttpServletRequest request = ureq.getHttpReq();
final HttpServletResponse response = ureq.getHttpResp();
final String timestampID = ureq.getTimestampID() == null ? "1" : ureq.getTimestampID();
final String componentID = ureq.getComponentID();
// case windowId timestamp componentId
// --------------------------------------------
//
// 1 null null null -> if (!renderOnly)-> error else doRenderOnly<br>
// 2 invalid n/a n/a -> not handled here, but in Windows
// 3 valid valid valid -> dispatch and further handling (check for new
// window and res. media resource
// 4 valid valid invalid -> no dispatch (silently) -> rerender (no res.
// media res and no new window check needed)
// 5 valid invalid n/a -> asyncRes == null? "doNotUseReload" :
// getAsyncRes==null? renderInline : serve resource
// 6 valid null n/a -> no timestamp -> just rerender inline
// defs:
// rerender: component validation and inline rendering
// case 1:
// simply rerender, no dispatching
// case 3:
// dispatch, check for new Window
// case 5:
// check newWindow, serve resource/renderInline
// order:
// 1. check for timestamp: valid: case 3,4 ; invalid -> case 5, or -1 ->
// indicator of just rendering and no revalidating needed
// 2. dispatch to component, unless flag renderOnly in method sig., or
// inlineRerender set (timestamps indicates)
boolean inline = false;
boolean validate = false;
boolean checkNewWindow = false;
boolean dispatch = false;
// 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
// !GUIInterna.isLoadPerformanceMode();
boolean incTimestamp = false;
MediaResource mr = null;
final boolean isDebugLog = log.isDebug();
StringBuilder debugMsg = null;
long debug_start = 0;
if (isDebugLog) {
debug_start = System.currentTimeMillis();
debugMsg = new StringBuilder("::winst:");
}
synchronized (this) {
// o_clusterOK by:fj
// sync dispatching per window to avoid rendering problems
// when user repeateadly presses reload, and also to distribute bandwidth more
// evenly.
// postcondition: each controller's events are called by one gui-thread at a time only.
GlobalSettings gsettings = wbackofficeImpl.getGlobalSettings();
boolean bgEnab = gsettings.getAjaxFlags().isIframePostEnabled();
// -------------------------
if (bgEnab && (ureq.getMode() & 1) == 1) {
// first check on "ajax-command-was-not-in-hidden-iframe hint" -> if so, rerender the current window
if (ureq.getParameter("o_win_jsontop") != null) {
renderOnly = true;
} else {
try {
// if target in background (m = mode , 0.bit set)
// 1.) do dispatch to component if component timestamp ok
// REVIEW:PB: this will be the code allowing back forward navigation
// --> boolean inlineAfterBackForward = false;
// FIXME:fj:b avoid double traversal to find component again below
String s_compID = ureq.getComponentID();
if (s_compID == null) {
throw new AssertException("no component id found in req:" + ureq.toString());
}
// throws NumberFormatException if not a number
// long compID = Long.parseLong(s_compID);
List<Component> foundPath = new ArrayList<Component>(10);
Component target = ComponentHelper.findDescendantOrSelfByID(getContentPane(), s_compID, foundPath);
final boolean validForDispatching;
if (target != null) {
// the target was found
String cTimest = target.getTimestamp();
String urlCTimest = ureq.getComponentTimestamp();
validForDispatching = cTimest.equals(urlCTimest);
if (!validForDispatching && isDebugLog) {
log.debug("Invalid timestamp: ureq.compid:" + ureq.getComponentID() + " ureq.win-ts:" + ureq.getTimestampID() + " ureq.comp-ts:" + ureq.getComponentTimestamp() + " target.timestamp:" + cTimest + " target=" + target);
}
} else {
// this can happen e.g. on quick double-clicks, so that the dom-replacement-command never reaches the client.
if (isDebugLog)
log.debug("no ajax dispatch: component not found (target=null)");
validForDispatching = false;
// check no response call
String noResponseMarker = ureq.getParameter("no-response");
if ("oo-no-response".equals(noResponseMarker)) {
return;
}
}
// 2.) collect dirty components (top-down, return from sub-path when first dirty node met)
// 3.) return to sender...
boolean didDispatch = false;
boolean forceReload = false;
if (validForDispatching) {
DispatchResult dispatchResult = doDispatchToComponent(ureq, null);
didDispatch = dispatchResult.isDispatch();
incTimestamp = dispatchResult.isIncTimestamp();
forceReload = dispatchResult.isForceReload();
if (isDebugLog) {
long durationAfterDoDispatchToComponent = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterDoDispatchToComponent=" + durationAfterDoDispatchToComponent);
}
}
MediaResource mmr = null;
// -----> if (didDispatch || inlineAfterBackForward) {
if (forceReload) {
// force RELOAD with a redirect to itself
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
} else if (didDispatch || !validForDispatching) {
if (validForDispatching) {
Window ww = ureq.getDispatchResult().getResultingWindow();
if (ww != null) {
// FIXME:fj:c think about bodyOnLoad -> win.open(new window url)
throw new AssertException("a link in ajax mode should never result in a new window");
}
mmr = ureq.getDispatchResult().getResultingMediaResource();
if (mmr == null) {
inline = true;
} else {
inline = false;
}
}
// -----> if (inline) {
if (inline || !validForDispatching) {
if (!validForDispatching) {
// not valid: fire oldtimestamp event and later rerender
fireEvent(ureq, OLDTIMESTAMPCALL);
}
ComponentCollection top = getContentPane();
// always validate here, since we are never in the case of just rerendering (we are in the bg iframe)
ValidatingVisitor vv = new ValidatingVisitor(gsettings, jsAndCssAdder);
ComponentTraverser ct = new ComponentTraverser(vv, top, false);
if (isDebugLog) {
long durationBeforeVisitAll = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeVisitAll=" + durationBeforeVisitAll);
}
ct.visitAll(ureq);
if (isDebugLog) {
long durationAfterVisitAll = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterVisitAll=" + durationAfterVisitAll);
}
wbackofficeImpl.fireCycleEvent(Window.AFTER_VALIDATING);
ValidationResult vr = vv.getValidationResult();
boolean newJsCssAdded = vr.getJsAndCSSAdder().finishAndCheckChange();
String newModUri = vr.getNewModuleURI();
// !validForDispatching ||
if (newJsCssAdded || newModUri != null) {
// send 302 redirect so the ajax-iframe's parent window gets reloaded to either include new js/css or to prepare the address bar
// url for asynchronous requests when delivering inline-contentpackaging.
// set window id to cur id, timestamp to current timestamp,
// component id to -1 -> indicates rerender
// newModUri == null in case "just" new css or js libs have been added
String uri = buildURIForRedirect(newModUri);
// set this only for the first request (the .html request), but clear it afterwards for asyncmedia
validatingCausedRerendering = true;
Command rmrcom = CommandFactory.createParentRedirectTo(uri);
wbackofficeImpl.sendCommandTo(rmrcom);
// OLAT-4563: so the timestamp is not incremented, we do only a redirect
setDirty(false);
} else {
// inline rendering by selectively replacing the dirty components in the dom tree of the browser
wbackofficeImpl.fireCycleEvent(Window.BEFORE_INLINE_RENDERING);
// wich might be set by later commands
if (!this.isDirty()) {
wbackofficeImpl.sendCommandTo(CommandFactory.createPrepareClientCommand(null));
}
// Add the js and css files and related pre init commands
Command jscsscom = jsAndCssAdder.extractJSCSSCommand();
wbackofficeImpl.sendCommandTo(jscsscom);
// dependencies to previously loaded js libs
if (this.isDirty()) {
// special case: when the window itself is dirty we require
// a full page refresh in any case
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
this.setDirty(false);
} else {
// check for dirty child components in the component tree
if (isDebugLog) {
long durationBeforeHandleDirties = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeHandleDirties=" + durationBeforeHandleDirties);
}
Command co;
try {
co = handleDirties();
} catch (CannotReplaceDOMFragmentException e) {
String reRenderUri = buildURIFor(this, timestampID, null);
co = CommandFactory.createParentRedirectTo(reRenderUri);
}
// update the business path
Command co2 = handleBusinessPath(ureq);
if (isDebugLog) {
long durationAfterHandleDirties = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterHandleDirties=" + durationAfterHandleDirties);
}
wbackofficeImpl.fireCycleEvent(AFTER_INLINE_RENDERING);
if (co != null) {
// see method handleDirties for the rare case of co == null even if there are dirty components;
wbackofficeImpl.sendCommandTo(co);
}
if (co2 != null) {
// see method handleDirties for the rare case of co == null even if there are dirty components;
wbackofficeImpl.sendCommandTo(co2);
}
}
}
} else {
// not inline
if (!validForDispatching) {
// not valid: fire oldtimestamp event
fireEvent(ureq, OLDTIMESTAMPCALL);
throw new AssertException("unreachable code reached");
}
if (isDebugLog) {
long durationBeforeCreateMediaResourceMapper = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeCreateMediaResourceMapper=" + durationBeforeCreateMediaResourceMapper);
}
// not inline, new mediaresource
// send it to the parent window (e.g. an excel download, but could also be a 302 redirect)
// if the browser has e.g. pdf configured to be displayed inline, we want it to fill the whole area (self window), not the hidden iframe.
// the same for 302.
// -> send a command which offers a new location for the main window.
// create a mapper which maps this mediaresource, and serves it once only
MediaResourceMapper extMRM = new MediaResourceMapper();
extMRM.setMediaResource(mmr);
MapperKey mapperKey = CoreSpringFactory.getImpl(MapperService.class).register(ureq.getUserSession(), extMRM);
String resUrl = mapperKey.getUrl() + "/";
// e.g. res = /olat/m/10001/
Command rmrcom = CommandFactory.createParentRedirectForExternalResource(resUrl);
wbackofficeImpl.sendCommandTo(rmrcom);
if (isDebugLog) {
long durationAfterCreateMediaResourceMapper = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterCreateMediaResourceMapper=" + durationAfterCreateMediaResourceMapper);
}
}
} else {
// not dispatched
if (isDebugLog) {
long durationBeforeBuildURIFor = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeBuildURIFor=" + durationBeforeBuildURIFor);
log.debug("Found a valid timestamp but could not dispatch to component: ureq.compid:" + ureq.getComponentID() + " ureq.win-ts:" + ureq.getTimestampID() + " ureq.comp-ts:" + ureq.getComponentTimestamp() + " target.timestamp:" + target.getTimestamp() + " target=" + target);
}
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
}
if (isDebugLog) {
long durationBeforeServeResource = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeServeResource=" + durationBeforeServeResource);
}
wbackofficeImpl.pushCommands(ureq, request, response);
} catch (InvalidRequestParameterException e) {
try {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} catch (IOException e1) {
log.error("An exception occured while handling the invalid request parameter exception...", e1);
}
} catch (Throwable th) {
// create the error window
try {
log.debug("Error in Window, rollback");
DBFactory.getInstance().rollback();
ChiefController msgcc = MsgFactory.createMessageChiefController(ureq, th);
Window errWindow = msgcc.getWindow();
errWindow.setUriPrefix(getUriPrefix());
// register window
Windows.getWindows(ureq).registerWindow(errWindow);
// redirect to the error window
String newWinUri = buildRenderOnlyURIFor(errWindow);
Command rmrcom = CommandFactory.createParentRedirectTo(newWinUri);
wbackofficeImpl.sendCommandTo(rmrcom);
MediaResource jsonmr = wbackofficeImpl.extractCommands(request);
ServletUtil.serveResource(request, response, jsonmr);
} catch (Throwable anotherTh) {
log.error("Exception while handling exception!!!!", anotherTh);
}
}
if (isDebugLog) {
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return from 1 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
// -------------------------
if (renderOnly || timestampID == null) {
inline = true;
validate = true;
wbackofficeImpl.fireCycleEvent(BEFORE_RENDER_ONLY);
} else if (validatingCausedRerendering && timestampID.equals("-1")) {
// the first request after the 302 redirect cause by a component validation
// -> just rerender, but clear the flag for further async media requests
validatingCausedRerendering = false;
inline = true;
// no need to revalidate right now
validate = false;
checkNewWindow = false;
dispatch = false;
} else {
// set), then check for an old timestamp
if (latestTimestamp != null && !timestampID.equals(latestTimestamp)) {
// asynchronous media
if (asyncMediaResponsible == null) {
// "open in new window/tab" in the browser).
if ((componentID != null && componentID.equals("-1")) || (ureq.getParameter("o_winrndo") != null)) {
// just rerender
} else {
// fxdiff BAKS-7: resume controller
if (isDebugLog)
log.debug("Removed old timestamp event");
// fireEvent(ureq, OLDTIMESTAMPCALL);
}
// just rerender current window
inline = true;
// do not increment timestamp so that e.g. url in a iframe remain valid
incTimestamp = false;
} else {
// some component will take care of it for the moment, so be it
mr = asyncMediaResponsible.getAsyncMediaResource(ureq);
if (mr == null) {
// indicates inline rendering
inline = true;
// an inline rendered async link should be
checkNewWindow = true;
// able to produce a new window
validate = true;
} else {
// serve the resource.
// all flags remain at their default value
}
}
} else {
// latestTimestamp == null || timestampID.equals(latestTimestamp)
dispatch = true;
checkNewWindow = true;
validate = true;
}
}
// end of simple flagging.
long dstart = 0;
if (isDebugLog) {
dstart = System.currentTimeMillis();
long syncIntroDiff = dstart - debug_start;
debugMsg.append("sync_bdisp:").append(syncIntroDiff).append(LOG_SEPARATOR);
}
boolean forceReload = false;
if (dispatch) {
DispatchResult dispatchResult = doDispatchToComponent(ureq, debugMsg);
boolean didDispatch = dispatchResult.isDispatch();
forceReload = dispatchResult.isForceReload();
incTimestamp = dispatchResult.isIncTimestamp();
if (isDebugLog) {
long dstop = System.currentTimeMillis();
long diff = dstop - dstart;
debugMsg.append("disp_comp:").append(diff).append(LOG_SEPARATOR);
}
if (didDispatch) {
// the component with the given id was found
mr = ureq.getDispatchResult().getResultingMediaResource();
if (mr == null) {
inline = true;
} else {
inline = false;
}
} else {
// component with id was not found -> probably asynchronous thread changed flow ->
// just rerender
inline = true;
dispatch = false;
checkNewWindow = false;
validate = true;
}
}
if (checkNewWindow) {
Window resWindow = ureq.getDispatchResult().getResultingWindow();
if (resWindow != null) {
// register it first, if not done before
Windows ws = Windows.getWindows(ureq);
if (!ws.isRegistered(resWindow)) {
resWindow.setUriPrefix(uriPrefix);
ws.registerWindow(resWindow);
}
// render initial state of new window by redirecting (302) to the new
// window id. needed for asyncronous data like images loaded
// todo maybe better delegate window registry to the windowbackoffice?
URLBuilder ubu = new URLBuilder(uriPrefix, resWindow.getInstanceId(), String.valueOf(resWindow.timestamp));
StringOutput sout = new StringOutput(30);
ubu.buildURI(sout, null, null);
mr = new RedirectMediaResource(sout.toString());
ServletUtil.serveResource(request, response, mr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("rdirnw:").append(diff).append(LOG_SEPARATOR);
log.debug(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return from 2 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
if (forceReload) {
// force RELOAD with a redirect to itself (http redirect because we are in non-Ajax mode)
String reRenderUri = buildURIFor(this, timestampID, null);
String url = reRenderUri;
DispatcherModule.redirectTo(response, url);
} else if (inline) {
// do inline rendering.
ComponentCollection top = getContentPane();
// the component just got dispatched
if (validate) {
// do not validate if a previous validate lead to a
// redirect; validating makes no sense here
// long t1 = System.currentTimeMillis();
ValidatingVisitor vv = new ValidatingVisitor(gsettings, jsAndCssAdder);
ComponentTraverser ct = new ComponentTraverser(vv, top, false);
ct.visitAll(ureq);
wbackofficeImpl.fireCycleEvent(Window.AFTER_VALIDATING);
ValidationResult vr = vv.getValidationResult();
String newModUri = vr.getNewModuleURI();
// ignore the return value since we are just about rendering anyway
vr.getJsAndCSSAdder().finishAndCheckChange();
if (newModUri != null) {
// send 302 redirect without dispatching, but just rerender
// inline.
// set window id to cur id, timestamp to current timestamp,
// component id to -1 -> indicates rerender
String uri = buildURIForRedirect(newModUri);
MediaResource mrr = new RedirectMediaResource(uri);
// set this only for the first request (the .html request), but clear it afterwards for asyncmedia
validatingCausedRerendering = true;
ServletUtil.serveResource(request, response, mrr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("rdirva:").append(diff).append(LOG_SEPARATOR);
log.debug(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return form 3 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
wbackofficeImpl.fireCycleEvent(BEFORE_INLINE_RENDERING);
StringOutput result;
synchronized (render_mutex) {
// 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
// session, can be used as a bookmark. that is, urls from our framework are bookmarkable, but require some little
// coding effort: setting an appropriate business path and launching for each controller.
// note: the businesspath may also be used as a easy (but of course not perfect) back-button-solution:
// if the timestamp of a request is outdated, simply jump to its bookmarked business control path.
URLBuilder ubu = new URLBuilder(uriPrefix, getInstanceId(), newTimestamp);
RenderResult renderResult = new RenderResult();
// if we have an around-component-interception
// set the handler for this render cycle
InterceptHandler interceptHandler = wbackofficeImpl.getInterceptHandler();
if (interceptHandler != null) {
InterceptHandlerInstance dhri = interceptHandler.createInterceptHandlerInstance();
renderResult.setInterceptHandlerRenderInstance(dhri);
}
Renderer fr = Renderer.getInstance(top, top.getTranslator(), ubu, renderResult, gsettings);
long rstart = 0;
if (isDebugLog) {
rstart = System.currentTimeMillis();
}
result = StringOutputPool.allocStringBuilder(100000);
fr.render(top, result, null);
if (isDebugLog) {
long rstop = System.currentTimeMillis();
long diff = rstop - rstart;
debugMsg.append("render:").append(diff).append(LOG_SEPARATOR);
}
if (renderResult.getRenderException() != null) {
throw new OLATRuntimeException(Window.class, renderResult.getLogMsg(), renderResult.getRenderException());
}
// to check HTML by reload
// System.out.println();
// System.out.println(result.toString());
// System.out.println();
// after rendering we know if some component awaits further async
// calls
// like images, so get a handler
AsyncMediaResponsible amr = renderResult.getAsyncMediaResponsible();
// if amr == null -> we are not
setAsyncMediaResponsible(amr);
// excepting
// any async calls in the near future...
latestTimestamp = newTimestamp;
}
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("inl_comp:").append(diff).append(LOG_SEPARATOR);
}
wbackofficeImpl.fireCycleEvent(AFTER_INLINE_RENDERING);
ServletUtil.serveStringResource(response, result);
StringOutputPool.free(result);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("inl_serve:").append(diff).append(LOG_SEPARATOR);
}
}
// else serve mediaresource, but postpone serving to when lock has been released,
// otherwise e.g. a large download blocks the window, so that the user cannot click until the download is finished
}
if (!inline) {
// it can be an async media resource, or a resulting mediaresource (image, an excel download, a 302 redirect, and so on.)
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("mr_comp:").append(diff).append(LOG_SEPARATOR);
}
ServletUtil.serveResource(request, response, mr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("mr_serve:").append(diff).append(LOG_SEPARATOR);
}
}
if (isDebugLog) {
// log the collected data now
log.info(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationDispatchRequest=" + durationDispatchRequest);
}
}
use of org.olat.core.gui.render.ValidationResult in project OpenOLAT by OpenOLAT.
the class GuiStackNiceImpl method pushCallout.
@Override
public void pushCallout(Component content, String targetId, CalloutSettings settings) {
// wrap the component into a modal foreground dialog with alpha-blended-background
final Panel guiMsgPlace = new Panel("guimsgplace_for_callout");
VelocityContainer inset = new VelocityContainer("inset", VELOCITY_ROOT + "/callout.html", null, null) {
public void validate(UserRequest ureq, ValidationResult vr) {
super.validate(ureq, vr);
// just before rendering, we need to tell the windowbackoffice that we are a favorite for accepting gui-messages.
// the windowbackoffice doesn't know about guimessages, it is only a container that keeps them for one render cycle
List<ZIndexWrapper> zindexed = wbo.getGuiMessages();
zindexed.add(new ZIndexWrapper(guiMsgPlace, 10));
}
};
inset.put("cont", content);
inset.put("guimsgplace", guiMsgPlace);
inset.contextPut("guimsgtarget", targetId);
int zindex = 900 + (modalLayers * 100) + 5;
inset.contextPut("zindexoverlay", zindex + 1);
inset.contextPut("zindexshim", zindex);
inset.contextPut("zindexarea", zindex + 5);
inset.contextPut("zindexextwindows", zindex + 50);
if (settings != null) {
inset.contextPut("arrow", settings.isArrow());
inset.contextPut("orientation", settings.getOrientation().name());
} else {
inset.contextPut("arrow", Boolean.TRUE);
inset.contextPut("orientation", CalloutOrientation.bottom.name());
}
modalPanel.pushContent(inset);
modalLayers++;
}
use of org.olat.core.gui.render.ValidationResult in project OpenOLAT by OpenOLAT.
the class GuiStackNiceImpl method pushModalDialog.
/**
* @param title the title of the modal dialog, can be null
* @param content the component to push as modal dialog
*/
@Override
public void pushModalDialog(Component content) {
wbo.sendCommandTo(new ScrollTopCommand());
// wrap the component into a modal foreground dialog with alpha-blended-background
final Panel guiMsgPlace = new Panel("guimsgplace_for_modaldialog");
VelocityContainer inset = new VelocityContainer("inset", VELOCITY_ROOT + "/modalDialog.html", null, null) {
@Override
public void validate(UserRequest ureq, ValidationResult vr) {
super.validate(ureq, vr);
// just before rendering, we need to tell the windowbackoffice that we are a favorite for accepting gui-messages.
// the windowbackoffice doesn't know about guimessages, it is only a container that keeps them for one render cycle
List<ZIndexWrapper> zindexed = wbo.getGuiMessages();
zindexed.add(new ZIndexWrapper(guiMsgPlace, 10));
}
};
inset.put("cont", content);
inset.put("guimsgplace", guiMsgPlace);
int zindex = 900 + (modalLayers * 100) + 5;
inset.contextPut("zindexoverlay", zindex + 1);
inset.contextPut("zindexshim", zindex);
inset.contextPut("zindexarea", zindex + 5);
inset.contextPut("zindexextwindows", zindex + 50);
modalPanel.pushContent(inset);
// the links in the panel cannot be clicked because of the alpha-blended background over it, but if user chooses own css style ->
// FIXME:fj:b panel.setEnabled(false) causes effects if there is an image component in the panel -> the component is not dispatched
// and thus renders inline and wastes the timestamp.
// Needed:solution (a) a flag (a bit of the mode indicator of the urlbuilder can be used) to indicate that a request always needs to be delivered even
// if the component or a parent is not enabled.
// alternative solution(b): wrap the imagecomponent into a controller and use a mapper
// alternative solution(c): introduce a flag to the component to say "dispatch always", even if a parent component is not enabled
//
// - solution a would be easy, but would allow for forced dispatching by manipulating the url's flag.
// for e.g. a Link button ("make me admin") that is disabled this is a security breach.
// - solution b needs some wrapping, the advantage (for images) would be that they are cached by the browser if requested more than once
// within a controller
// - solution c is a safe and easy way to allow dispatching (only in case a mediaresource is returned as a result of the dispatching) even
// if parent elements are not enabled
// proposal: fix for 5.1.0 with solution c; for 5.0.1 the uncommenting of the line below is okay.
// if (modalLayers == 0) panel.setEnabled(false);
modalLayers++;
}
use of org.olat.core.gui.render.ValidationResult in project openolat by klemens.
the class ValidatingVisitor method dispatchRequest.
/**
* @param ureq
* @param renderOnly
*/
public void dispatchRequest(UserRequest ureq, boolean renderOnly) {
final HttpServletRequest request = ureq.getHttpReq();
final HttpServletResponse response = ureq.getHttpResp();
final String timestampID = ureq.getTimestampID() == null ? "1" : ureq.getTimestampID();
final String componentID = ureq.getComponentID();
// case windowId timestamp componentId
// --------------------------------------------
//
// 1 null null null -> if (!renderOnly)-> error else doRenderOnly<br>
// 2 invalid n/a n/a -> not handled here, but in Windows
// 3 valid valid valid -> dispatch and further handling (check for new
// window and res. media resource
// 4 valid valid invalid -> no dispatch (silently) -> rerender (no res.
// media res and no new window check needed)
// 5 valid invalid n/a -> asyncRes == null? "doNotUseReload" :
// getAsyncRes==null? renderInline : serve resource
// 6 valid null n/a -> no timestamp -> just rerender inline
// defs:
// rerender: component validation and inline rendering
// case 1:
// simply rerender, no dispatching
// case 3:
// dispatch, check for new Window
// case 5:
// check newWindow, serve resource/renderInline
// order:
// 1. check for timestamp: valid: case 3,4 ; invalid -> case 5, or -1 ->
// indicator of just rendering and no revalidating needed
// 2. dispatch to component, unless flag renderOnly in method sig., or
// inlineRerender set (timestamps indicates)
boolean inline = false;
boolean validate = false;
boolean checkNewWindow = false;
boolean dispatch = false;
// 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
// !GUIInterna.isLoadPerformanceMode();
boolean incTimestamp = false;
MediaResource mr = null;
final boolean isDebugLog = log.isDebug();
StringBuilder debugMsg = null;
long debug_start = 0;
if (isDebugLog) {
debug_start = System.currentTimeMillis();
debugMsg = new StringBuilder("::winst:");
}
synchronized (this) {
// o_clusterOK by:fj
// sync dispatching per window to avoid rendering problems
// when user repeateadly presses reload, and also to distribute bandwidth more
// evenly.
// postcondition: each controller's events are called by one gui-thread at a time only.
GlobalSettings gsettings = wbackofficeImpl.getGlobalSettings();
boolean bgEnab = gsettings.getAjaxFlags().isIframePostEnabled();
// -------------------------
if (bgEnab && (ureq.getMode() & 1) == 1) {
// first check on "ajax-command-was-not-in-hidden-iframe hint" -> if so, rerender the current window
if (ureq.getParameter("o_win_jsontop") != null) {
renderOnly = true;
} else {
try {
// if target in background (m = mode , 0.bit set)
// 1.) do dispatch to component if component timestamp ok
// REVIEW:PB: this will be the code allowing back forward navigation
// --> boolean inlineAfterBackForward = false;
// FIXME:fj:b avoid double traversal to find component again below
String s_compID = ureq.getComponentID();
if (s_compID == null) {
throw new AssertException("no component id found in req:" + ureq.toString());
}
// throws NumberFormatException if not a number
// long compID = Long.parseLong(s_compID);
List<Component> foundPath = new ArrayList<Component>(10);
Component target = ComponentHelper.findDescendantOrSelfByID(getContentPane(), s_compID, foundPath);
final boolean validForDispatching;
if (target != null) {
// the target was found
String cTimest = target.getTimestamp();
String urlCTimest = ureq.getComponentTimestamp();
validForDispatching = cTimest.equals(urlCTimest);
if (!validForDispatching && isDebugLog) {
log.debug("Invalid timestamp: ureq.compid:" + ureq.getComponentID() + " ureq.win-ts:" + ureq.getTimestampID() + " ureq.comp-ts:" + ureq.getComponentTimestamp() + " target.timestamp:" + cTimest + " target=" + target);
}
} else {
// this can happen e.g. on quick double-clicks, so that the dom-replacement-command never reaches the client.
if (isDebugLog)
log.debug("no ajax dispatch: component not found (target=null)");
validForDispatching = false;
// check no response call
String noResponseMarker = ureq.getParameter("no-response");
if ("oo-no-response".equals(noResponseMarker)) {
return;
}
}
// 2.) collect dirty components (top-down, return from sub-path when first dirty node met)
// 3.) return to sender...
boolean didDispatch = false;
boolean forceReload = false;
if (validForDispatching) {
DispatchResult dispatchResult = doDispatchToComponent(ureq, null);
didDispatch = dispatchResult.isDispatch();
incTimestamp = dispatchResult.isIncTimestamp();
forceReload = dispatchResult.isForceReload();
if (isDebugLog) {
long durationAfterDoDispatchToComponent = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterDoDispatchToComponent=" + durationAfterDoDispatchToComponent);
}
}
MediaResource mmr = null;
// -----> if (didDispatch || inlineAfterBackForward) {
if (forceReload) {
// force RELOAD with a redirect to itself
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
} else if (didDispatch || !validForDispatching) {
if (validForDispatching) {
Window ww = ureq.getDispatchResult().getResultingWindow();
if (ww != null) {
// FIXME:fj:c think about bodyOnLoad -> win.open(new window url)
throw new AssertException("a link in ajax mode should never result in a new window");
}
mmr = ureq.getDispatchResult().getResultingMediaResource();
if (mmr == null) {
inline = true;
} else {
inline = false;
}
}
// -----> if (inline) {
if (inline || !validForDispatching) {
if (!validForDispatching) {
// not valid: fire oldtimestamp event and later rerender
fireEvent(ureq, OLDTIMESTAMPCALL);
}
ComponentCollection top = getContentPane();
// always validate here, since we are never in the case of just rerendering (we are in the bg iframe)
ValidatingVisitor vv = new ValidatingVisitor(gsettings, jsAndCssAdder);
ComponentTraverser ct = new ComponentTraverser(vv, top, false);
if (isDebugLog) {
long durationBeforeVisitAll = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeVisitAll=" + durationBeforeVisitAll);
}
ct.visitAll(ureq);
if (isDebugLog) {
long durationAfterVisitAll = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterVisitAll=" + durationAfterVisitAll);
}
wbackofficeImpl.fireCycleEvent(Window.AFTER_VALIDATING);
ValidationResult vr = vv.getValidationResult();
boolean newJsCssAdded = vr.getJsAndCSSAdder().finishAndCheckChange();
String newModUri = vr.getNewModuleURI();
// !validForDispatching ||
if (newJsCssAdded || newModUri != null) {
// send 302 redirect so the ajax-iframe's parent window gets reloaded to either include new js/css or to prepare the address bar
// url for asynchronous requests when delivering inline-contentpackaging.
// set window id to cur id, timestamp to current timestamp,
// component id to -1 -> indicates rerender
// newModUri == null in case "just" new css or js libs have been added
String uri = buildURIForRedirect(newModUri);
// set this only for the first request (the .html request), but clear it afterwards for asyncmedia
validatingCausedRerendering = true;
Command rmrcom = CommandFactory.createParentRedirectTo(uri);
wbackofficeImpl.sendCommandTo(rmrcom);
// OLAT-4563: so the timestamp is not incremented, we do only a redirect
setDirty(false);
} else {
// inline rendering by selectively replacing the dirty components in the dom tree of the browser
wbackofficeImpl.fireCycleEvent(Window.BEFORE_INLINE_RENDERING);
// wich might be set by later commands
if (!this.isDirty()) {
wbackofficeImpl.sendCommandTo(CommandFactory.createPrepareClientCommand(null));
}
// Add the js and css files and related pre init commands
Command jscsscom = jsAndCssAdder.extractJSCSSCommand();
wbackofficeImpl.sendCommandTo(jscsscom);
// dependencies to previously loaded js libs
if (this.isDirty()) {
// special case: when the window itself is dirty we require
// a full page refresh in any case
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
this.setDirty(false);
} else {
// check for dirty child components in the component tree
if (isDebugLog) {
long durationBeforeHandleDirties = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeHandleDirties=" + durationBeforeHandleDirties);
}
Command co;
try {
co = handleDirties();
} catch (CannotReplaceDOMFragmentException e) {
String reRenderUri = buildURIFor(this, timestampID, null);
co = CommandFactory.createParentRedirectTo(reRenderUri);
}
// update the business path
Command co2 = handleBusinessPath(ureq);
if (isDebugLog) {
long durationAfterHandleDirties = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterHandleDirties=" + durationAfterHandleDirties);
}
wbackofficeImpl.fireCycleEvent(AFTER_INLINE_RENDERING);
if (co != null) {
// see method handleDirties for the rare case of co == null even if there are dirty components;
wbackofficeImpl.sendCommandTo(co);
}
if (co2 != null) {
// see method handleDirties for the rare case of co == null even if there are dirty components;
wbackofficeImpl.sendCommandTo(co2);
}
}
}
} else {
// not inline
if (!validForDispatching) {
// not valid: fire oldtimestamp event
fireEvent(ureq, OLDTIMESTAMPCALL);
throw new AssertException("unreachable code reached");
}
if (isDebugLog) {
long durationBeforeCreateMediaResourceMapper = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeCreateMediaResourceMapper=" + durationBeforeCreateMediaResourceMapper);
}
// not inline, new mediaresource
// send it to the parent window (e.g. an excel download, but could also be a 302 redirect)
// if the browser has e.g. pdf configured to be displayed inline, we want it to fill the whole area (self window), not the hidden iframe.
// the same for 302.
// -> send a command which offers a new location for the main window.
// create a mapper which maps this mediaresource, and serves it once only
MediaResourceMapper extMRM = new MediaResourceMapper();
extMRM.setMediaResource(mmr);
MapperKey mapperKey = CoreSpringFactory.getImpl(MapperService.class).register(ureq.getUserSession(), extMRM);
String resUrl = mapperKey.getUrl() + "/";
// e.g. res = /olat/m/10001/
Command rmrcom = CommandFactory.createParentRedirectForExternalResource(resUrl);
wbackofficeImpl.sendCommandTo(rmrcom);
if (isDebugLog) {
long durationAfterCreateMediaResourceMapper = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationAfterCreateMediaResourceMapper=" + durationAfterCreateMediaResourceMapper);
}
}
} else {
// not dispatched
if (isDebugLog) {
long durationBeforeBuildURIFor = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeBuildURIFor=" + durationBeforeBuildURIFor);
log.debug("Found a valid timestamp but could not dispatch to component: ureq.compid:" + ureq.getComponentID() + " ureq.win-ts:" + ureq.getTimestampID() + " ureq.comp-ts:" + ureq.getComponentTimestamp() + " target.timestamp:" + target.getTimestamp() + " target=" + target);
}
String reRenderUri = buildURIFor(this, timestampID, null);
Command rmrcom = CommandFactory.createParentRedirectTo(reRenderUri);
wbackofficeImpl.sendCommandTo(rmrcom);
}
if (isDebugLog) {
long durationBeforeServeResource = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationBeforeServeResource=" + durationBeforeServeResource);
}
wbackofficeImpl.pushCommands(ureq, request, response);
} catch (InvalidRequestParameterException e) {
try {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} catch (IOException e1) {
log.error("An exception occured while handling the invalid request parameter exception...", e1);
}
} catch (Throwable th) {
// create the error window
try {
log.debug("Error in Window, rollback");
DBFactory.getInstance().rollback();
ChiefController msgcc = MsgFactory.createMessageChiefController(ureq, th);
Window errWindow = msgcc.getWindow();
errWindow.setUriPrefix(getUriPrefix());
// register window
Windows.getWindows(ureq).registerWindow(errWindow);
// redirect to the error window
String newWinUri = buildRenderOnlyURIFor(errWindow);
Command rmrcom = CommandFactory.createParentRedirectTo(newWinUri);
wbackofficeImpl.sendCommandTo(rmrcom);
MediaResource jsonmr = wbackofficeImpl.extractCommands(request);
ServletUtil.serveResource(request, response, jsonmr);
} catch (Throwable anotherTh) {
log.error("Exception while handling exception!!!!", anotherTh);
}
}
if (isDebugLog) {
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return from 1 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
// -------------------------
if (renderOnly || timestampID == null) {
inline = true;
validate = true;
wbackofficeImpl.fireCycleEvent(BEFORE_RENDER_ONLY);
} else if (validatingCausedRerendering && timestampID.equals("-1")) {
// the first request after the 302 redirect cause by a component validation
// -> just rerender, but clear the flag for further async media requests
validatingCausedRerendering = false;
inline = true;
// no need to revalidate right now
validate = false;
checkNewWindow = false;
dispatch = false;
} else {
// set), then check for an old timestamp
if (latestTimestamp != null && !timestampID.equals(latestTimestamp)) {
// asynchronous media
if (asyncMediaResponsible == null) {
// "open in new window/tab" in the browser).
if ((componentID != null && componentID.equals("-1")) || (ureq.getParameter("o_winrndo") != null)) {
// just rerender
} else {
// fxdiff BAKS-7: resume controller
if (isDebugLog)
log.debug("Removed old timestamp event");
// fireEvent(ureq, OLDTIMESTAMPCALL);
}
// just rerender current window
inline = true;
// do not increment timestamp so that e.g. url in a iframe remain valid
incTimestamp = false;
} else {
// some component will take care of it for the moment, so be it
mr = asyncMediaResponsible.getAsyncMediaResource(ureq);
if (mr == null) {
// indicates inline rendering
inline = true;
// an inline rendered async link should be
checkNewWindow = true;
// able to produce a new window
validate = true;
} else {
// serve the resource.
// all flags remain at their default value
}
}
} else {
// latestTimestamp == null || timestampID.equals(latestTimestamp)
dispatch = true;
checkNewWindow = true;
validate = true;
}
}
// end of simple flagging.
long dstart = 0;
if (isDebugLog) {
dstart = System.currentTimeMillis();
long syncIntroDiff = dstart - debug_start;
debugMsg.append("sync_bdisp:").append(syncIntroDiff).append(LOG_SEPARATOR);
}
boolean forceReload = false;
if (dispatch) {
DispatchResult dispatchResult = doDispatchToComponent(ureq, debugMsg);
boolean didDispatch = dispatchResult.isDispatch();
forceReload = dispatchResult.isForceReload();
incTimestamp = dispatchResult.isIncTimestamp();
if (isDebugLog) {
long dstop = System.currentTimeMillis();
long diff = dstop - dstart;
debugMsg.append("disp_comp:").append(diff).append(LOG_SEPARATOR);
}
if (didDispatch) {
// the component with the given id was found
mr = ureq.getDispatchResult().getResultingMediaResource();
if (mr == null) {
inline = true;
} else {
inline = false;
}
} else {
// component with id was not found -> probably asynchronous thread changed flow ->
// just rerender
inline = true;
dispatch = false;
checkNewWindow = false;
validate = true;
}
}
if (checkNewWindow) {
Window resWindow = ureq.getDispatchResult().getResultingWindow();
if (resWindow != null) {
// register it first, if not done before
Windows ws = Windows.getWindows(ureq);
if (!ws.isRegistered(resWindow)) {
resWindow.setUriPrefix(uriPrefix);
ws.registerWindow(resWindow);
}
// render initial state of new window by redirecting (302) to the new
// window id. needed for asyncronous data like images loaded
// todo maybe better delegate window registry to the windowbackoffice?
URLBuilder ubu = new URLBuilder(uriPrefix, resWindow.getInstanceId(), String.valueOf(resWindow.timestamp));
StringOutput sout = new StringOutput(30);
ubu.buildURI(sout, null, null);
mr = new RedirectMediaResource(sout.toString());
ServletUtil.serveResource(request, response, mr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("rdirnw:").append(diff).append(LOG_SEPARATOR);
log.debug(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return from 2 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
if (forceReload) {
// force RELOAD with a redirect to itself (http redirect because we are in non-Ajax mode)
String reRenderUri = buildURIFor(this, timestampID, null);
String url = reRenderUri;
DispatcherModule.redirectTo(response, url);
} else if (inline) {
// do inline rendering.
ComponentCollection top = getContentPane();
// the component just got dispatched
if (validate) {
// do not validate if a previous validate lead to a
// redirect; validating makes no sense here
// long t1 = System.currentTimeMillis();
ValidatingVisitor vv = new ValidatingVisitor(gsettings, jsAndCssAdder);
ComponentTraverser ct = new ComponentTraverser(vv, top, false);
ct.visitAll(ureq);
wbackofficeImpl.fireCycleEvent(Window.AFTER_VALIDATING);
ValidationResult vr = vv.getValidationResult();
String newModUri = vr.getNewModuleURI();
// ignore the return value since we are just about rendering anyway
vr.getJsAndCSSAdder().finishAndCheckChange();
if (newModUri != null) {
// send 302 redirect without dispatching, but just rerender
// inline.
// set window id to cur id, timestamp to current timestamp,
// component id to -1 -> indicates rerender
String uri = buildURIForRedirect(newModUri);
MediaResource mrr = new RedirectMediaResource(uri);
// set this only for the first request (the .html request), but clear it afterwards for asyncmedia
validatingCausedRerendering = true;
ServletUtil.serveResource(request, response, mrr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("rdirva:").append(diff).append(LOG_SEPARATOR);
log.debug(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window return form 3 durationDispatchRequest=" + durationDispatchRequest);
}
return;
}
}
wbackofficeImpl.fireCycleEvent(BEFORE_INLINE_RENDERING);
StringOutput result;
synchronized (render_mutex) {
// 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
// session, can be used as a bookmark. that is, urls from our framework are bookmarkable, but require some little
// coding effort: setting an appropriate business path and launching for each controller.
// note: the businesspath may also be used as a easy (but of course not perfect) back-button-solution:
// if the timestamp of a request is outdated, simply jump to its bookmarked business control path.
URLBuilder ubu = new URLBuilder(uriPrefix, getInstanceId(), newTimestamp);
RenderResult renderResult = new RenderResult();
// if we have an around-component-interception
// set the handler for this render cycle
InterceptHandler interceptHandler = wbackofficeImpl.getInterceptHandler();
if (interceptHandler != null) {
InterceptHandlerInstance dhri = interceptHandler.createInterceptHandlerInstance();
renderResult.setInterceptHandlerRenderInstance(dhri);
}
Renderer fr = Renderer.getInstance(top, top.getTranslator(), ubu, renderResult, gsettings);
long rstart = 0;
if (isDebugLog) {
rstart = System.currentTimeMillis();
}
result = StringOutputPool.allocStringBuilder(100000);
fr.render(top, result, null);
if (isDebugLog) {
long rstop = System.currentTimeMillis();
long diff = rstop - rstart;
debugMsg.append("render:").append(diff).append(LOG_SEPARATOR);
}
if (renderResult.getRenderException() != null) {
throw new OLATRuntimeException(Window.class, renderResult.getLogMsg(), renderResult.getRenderException());
}
// to check HTML by reload
// System.out.println();
// System.out.println(result.toString());
// System.out.println();
// after rendering we know if some component awaits further async
// calls
// like images, so get a handler
AsyncMediaResponsible amr = renderResult.getAsyncMediaResponsible();
// if amr == null -> we are not
setAsyncMediaResponsible(amr);
// excepting
// any async calls in the near future...
latestTimestamp = newTimestamp;
}
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("inl_comp:").append(diff).append(LOG_SEPARATOR);
}
wbackofficeImpl.fireCycleEvent(AFTER_INLINE_RENDERING);
ServletUtil.serveStringResource(response, result);
StringOutputPool.free(result);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("inl_serve:").append(diff).append(LOG_SEPARATOR);
}
}
// else serve mediaresource, but postpone serving to when lock has been released,
// otherwise e.g. a large download blocks the window, so that the user cannot click until the download is finished
}
if (!inline) {
// it can be an async media resource, or a resulting mediaresource (image, an excel download, a 302 redirect, and so on.)
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("mr_comp:").append(diff).append(LOG_SEPARATOR);
}
ServletUtil.serveResource(request, response, mr);
if (isDebugLog) {
long diff = System.currentTimeMillis() - debug_start;
debugMsg.append("mr_serve:").append(diff).append(LOG_SEPARATOR);
}
}
if (isDebugLog) {
// log the collected data now
log.info(debugMsg.toString());
long durationDispatchRequest = System.currentTimeMillis() - debug_start;
log.debug("Perf-Test: Window durationDispatchRequest=" + durationDispatchRequest);
}
}
use of org.olat.core.gui.render.ValidationResult in project openolat by klemens.
the class GuiStackNiceImpl method pushModalDialog.
/**
* @param title the title of the modal dialog, can be null
* @param content the component to push as modal dialog
*/
@Override
public void pushModalDialog(Component content) {
wbo.sendCommandTo(new ScrollTopCommand());
// wrap the component into a modal foreground dialog with alpha-blended-background
final Panel guiMsgPlace = new Panel("guimsgplace_for_modaldialog");
VelocityContainer inset = new VelocityContainer("inset", VELOCITY_ROOT + "/modalDialog.html", null, null) {
@Override
public void validate(UserRequest ureq, ValidationResult vr) {
super.validate(ureq, vr);
// just before rendering, we need to tell the windowbackoffice that we are a favorite for accepting gui-messages.
// the windowbackoffice doesn't know about guimessages, it is only a container that keeps them for one render cycle
List<ZIndexWrapper> zindexed = wbo.getGuiMessages();
zindexed.add(new ZIndexWrapper(guiMsgPlace, 10));
}
};
inset.put("cont", content);
inset.put("guimsgplace", guiMsgPlace);
int zindex = 900 + (modalLayers * 100) + 5;
inset.contextPut("zindexoverlay", zindex + 1);
inset.contextPut("zindexshim", zindex);
inset.contextPut("zindexarea", zindex + 5);
inset.contextPut("zindexextwindows", zindex + 50);
modalPanel.pushContent(inset);
// the links in the panel cannot be clicked because of the alpha-blended background over it, but if user chooses own css style ->
// FIXME:fj:b panel.setEnabled(false) causes effects if there is an image component in the panel -> the component is not dispatched
// and thus renders inline and wastes the timestamp.
// Needed:solution (a) a flag (a bit of the mode indicator of the urlbuilder can be used) to indicate that a request always needs to be delivered even
// if the component or a parent is not enabled.
// alternative solution(b): wrap the imagecomponent into a controller and use a mapper
// alternative solution(c): introduce a flag to the component to say "dispatch always", even if a parent component is not enabled
//
// - solution a would be easy, but would allow for forced dispatching by manipulating the url's flag.
// for e.g. a Link button ("make me admin") that is disabled this is a security breach.
// - solution b needs some wrapping, the advantage (for images) would be that they are cached by the browser if requested more than once
// within a controller
// - solution c is a safe and easy way to allow dispatching (only in case a mediaresource is returned as a result of the dispatching) even
// if parent elements are not enabled
// proposal: fix for 5.1.0 with solution c; for 5.0.1 the uncommenting of the line below is okay.
// if (modalLayers == 0) panel.setEnabled(false);
modalLayers++;
}
Aggregations