/** * Process the event. Note: it doesn't invoke EventThreadInit and EventThreadCleanup. * * <p>This method is to implement {@link org.zkoss.zk.ui.sys.EventProcessingThread}. See also * {@link org.zkoss.zk.ui.util.Configuration#isEventThreadEnabled}. */ public void process() throws Exception { final ExecutionMonitor execmon = _desktop.getWebApp().getConfiguration().getExecutionMonitor(); // Bug 1506712: event listeners might be zscript, so we have to // keep built-in variables as long as possible final Scope scope = Scopes.beforeInterpret(_comp); // we have to push since process0 might invoke methods from zscript class try { Scopes.setImplicit("event", _event); _event = ((DesktopCtrl) _desktop).beforeProcessEvent(_event); if (_event != null) { if (execmon != null) execmon.eventStart(_event); Scopes.setImplicit("event", _event); // _event might change ((ComponentCtrl) _comp).service(_event, scope); ((DesktopCtrl) _desktop).afterProcessEvent(_event); } } finally { final Execution exec = _desktop.getExecution(); if (exec != null) // just in case ((ExecutionCtrl) exec).setExecutionInfo(null); if (execmon != null && _event != null) execmon.eventComplete(_event); Scopes.afterInterpret(); } }
/** * Generates the special JavaScript code, such as the application's name. It shall be called, * before generating "zkmx(" and "zkx(". * * @since 5.0.6 */ public static final String outSpecialJS(Desktop desktop) { final StringBuffer sb = new StringBuffer(); // output application name String oldnm = (String) desktop.getAttribute(ATTR_APPNM); if (oldnm == null) oldnm = "ZK"; final String appnm = desktop.getWebApp().getAppName(); if (!oldnm.equals(appnm)) { sb.append("zk.appName='"); Strings.escape(sb, appnm, Strings.ESCAPE_JAVASCRIPT).append("';"); desktop.setAttribute(ATTR_APPNM, appnm); } // output zktheme cookie String oldthemenm = (String) desktop.getAttribute(ATTR_THEMENM); if (oldthemenm == null) oldthemenm = ""; final Object request = desktop.getExecution().getNativeRequest(); String themenm = ""; if (request instanceof HttpServletRequest) { themenm = ThemeFns.getThemeResolver().getTheme((HttpServletRequest) request); } if (!oldthemenm.equals(themenm)) { sb.append("zk.themeName='"); Strings.escape(sb, themenm, Strings.ESCAPE_JAVASCRIPT).append("';"); desktop.setAttribute(ATTR_THEMENM, themenm); } // output ZK ICON final Session sess = Sessions.getCurrent(); if (sess != null) { WebApp wapp = desktop.getWebApp(); if (wapp == null || "CE".equals(WebApps.getEdition()) || wapp.getAttribute("org.zkoss.zk.ui.notice") != null) { final PI pi = (PI) sess.getAttribute(ATTR_PI); boolean show = pi == null; if (show) sess.setAttribute(ATTR_PI, new PI()); else show = pi.show(); if (show) sb.append("zk.pi=1;"); } } return sb.toString(); }
private boolean isEventThreadEnabled(boolean attachedRequired) { Desktop desktop = getDesktop(); if (desktop == null) { if (attachedRequired) throw new SuspendNotAllowedException("Not attached, " + this); final Execution exec = Executions.getCurrent(); if (exec == null || (desktop = exec.getDesktop()) == null) return true; // assume enabled (safer) } return desktop.getWebApp().getConfiguration().isEventThreadEnabled(); }
/** * Returns the HTML content representing a page. * * @param au whether it is caused by asynchronous update * @param exec the execution (never null) */ public static final void outPageContent(Execution exec, Page page, Writer out, boolean au) throws IOException { final Desktop desktop = page.getDesktop(); final PageCtrl pageCtrl = (PageCtrl) page; final Component owner = pageCtrl.getOwner(); boolean contained = owner == null && exec.isIncluded(); // a standalone page (i.e., no owner), and being included by // non-ZK page (e.g., JSP). // // Revisit Bug 2001707: OK to use exec.isIncluded() since // we use PageRenderer now (rather than Servlet's include) // TODO: test again // prepare style String style = page.getStyle(); if (style == null || style.length() == 0) { style = null; String wd = null, hgh = null; if (owner instanceof HtmlBasedComponent) { final HtmlBasedComponent hbc = (HtmlBasedComponent) owner; wd = hbc.getWidth(); // null if not set hgh = hbc.getHeight(); // null if not set } if (wd != null || hgh != null || contained) { final StringBuffer sb = new StringBuffer(32); HTMLs.appendStyle(sb, "width", wd != null ? wd : "100%"); HTMLs.appendStyle(sb, "height", hgh != null ? hgh : contained ? null : "100%"); style = sb.toString(); } } RenderContext rc = null, old = null; final boolean aupg = exec.isAsyncUpdate(page); // AU this page final boolean includedAndPart = owner != null && !aupg; // this page is included and rendered with its owner final boolean divRequired = !au || includedAndPart; final boolean standalone = !au && owner == null; if (standalone) { rc = new RenderContext( out, new StringWriter(), desktop.getWebApp().getConfiguration().isCrawlable(), false); setRenderContext(exec, rc); } else if (owner != null) { old = getRenderContext(exec); // store final boolean crawlable = old != null && old.temp != null && desktop.getWebApp().getConfiguration().isCrawlable(); setRenderContext(exec, crawlable ? new RenderContext(old.temp, null, true, true) : null); } // generate div first if (divRequired) { outDivTemplateBegin(out, page.getUuid()); } if (standalone) { // switch out // don't call outDivTemplateEnd yet since rc.temp will be generated before it out = new StringWriter(); } else if (divRequired) { outDivTemplateEnd(page, out); // close it now since no rc.temp } if (includedAndPart) { out = new StringWriter(); } else if (divRequired) { // generate JS second out.write("\n<script class=\"z-runonce\" type=\"text/javascript\">\n"); } exec.setAttribute(ATTR_DESKTOP_JS_GENED, Boolean.TRUE); final int order = ComponentRedraws.beforeRedraw(false); final String extra; try { if (order < 0) { if (aupg) out.write('['); else { out.write(outSpecialJS(desktop)); out.write(divRequired ? "zkmx(" : "zkx("); } } else if (order > 0) // not first child out.write(','); out.write("\n[0,'"); // 0: page out.write(page.getUuid()); out.write("',{"); final StringBuffer props = new StringBuffer(128); final String pgid = page.getId(); if (pgid.length() > 0) appendProp(props, "id", pgid); if (owner != null) { appendProp(props, "ow", owner.getUuid()); } else { appendProp(props, "dt", desktop.getId()); appendProp(props, "cu", getContextURI(exec)); appendProp(props, "uu", desktop.getUpdateURI(null)); appendProp(props, "ru", desktop.getRequestPath()); } final String pageWgtCls = pageCtrl.getWidgetClass(); if (pageWgtCls != null) appendProp(props, "wc", pageWgtCls); if (style != null) appendProp(props, "style", style); if (!isClientROD(page)) appendProp(props, "z$rod", Boolean.FALSE); if (contained) appendProp(props, "ct", Boolean.TRUE); out.write(props.toString()); out.write("},["); for (Component root = page.getFirstRoot(); root != null; root = root.getNextSibling()) ((ComponentCtrl) root).redraw(out); out.write("]]"); } finally { extra = ComponentRedraws.afterRedraw(); } if (order < 0) { outEndJavaScriptFunc(exec, out, extra, aupg); } if (standalone) { setRenderContext(exec, null); StringBuffer sw = ((StringWriter) out).getBuffer(); out = rc.temp; if (divRequired) outDivTemplateEnd(page, out); // close tag after temp, but before perm (so perm won't be destroyed) Files.write(out, ((StringWriter) rc.perm).getBuffer()); // perm // B65-ZK-1836 Files.write( out, new StringBuffer(sw.toString().replaceAll("</(?i)(?=script>)", "<\\\\/"))); // js } else if (owner != null) { // restore setRenderContext(exec, old); } if (includedAndPart) { ((Includer) owner).setRenderingResult(((StringWriter) out).toString()); } else if (divRequired) { out.write("\n</script>\n"); } }
/** * Returns HTML tags to include all JavaScript files and codes that are required when loading a * ZUML page (never null). * * <p>FUTURE CONSIDERATION: we might generate the inclusion on demand instead of all at once. * * @param exec the execution (never null) * @param wapp the Web application. If null, exec.getDesktop().getWebApp() is used. So you have to * specify it if the execution is not associated with desktop (a fake execution, such as * JSP/DSP). * @param deviceType the device type, such as ajax. If null, exec.getDesktop().getDeviceType() is * used. So you have to specify it if the execution is not associated with desktop (a fake * execution). */ public static final String outLangJavaScripts(Execution exec, WebApp wapp, String deviceType) { if (exec.isAsyncUpdate(null) || exec.getAttribute(ATTR_LANG_JS_GENED) != null) return ""; // nothing to generate exec.setAttribute(ATTR_LANG_JS_GENED, Boolean.TRUE); final Desktop desktop = exec.getDesktop(); if (wapp == null) wapp = desktop.getWebApp(); if (deviceType == null) deviceType = desktop != null ? desktop.getDeviceType() : "ajax"; final StringBuffer sb = new StringBuffer(1536); final Set<JavaScript> jses = new LinkedHashSet<JavaScript>(32); for (LanguageDefinition langdef : LanguageDefinition.getByDeviceType(deviceType)) jses.addAll(langdef.getJavaScripts()); for (JavaScript js : jses) append(sb, js); sb.append("\n<!-- ZK ").append(wapp.getVersion()); if (WebApps.getFeature("ee")) sb.append(" EE"); else if (WebApps.getFeature("pe")) sb.append(" PE"); sb.append(' ').append(wapp.getBuild()); Object o = wapp.getAttribute("org.zkoss.zk.ui.notice"); if (o != null) sb.append(o); sb.append(" -->\n"); int tmout = 0; final Boolean autoTimeout = getAutomaticTimeout(desktop); if (autoTimeout != null ? autoTimeout.booleanValue() : wapp.getConfiguration().isAutomaticTimeout(deviceType)) { if (desktop != null) { tmout = desktop.getSession().getMaxInactiveInterval(); } else { Object req = exec.getNativeRequest(); if (req instanceof HttpServletRequest) { final HttpSession hsess = ((HttpServletRequest) req).getSession(false); if (hsess != null) { final Session sess = SessionsCtrl.getSession(wapp, hsess); if (sess != null) { tmout = sess.getMaxInactiveInterval(); } else { // try configuration first since HttpSession's timeout is set // when ZK Session is created (so it is not set yet) // Note: no need to setMaxInactiveInternval here since it will // be set later or not useful at the end tmout = wapp.getConfiguration().getSessionMaxInactiveInterval(); if (tmout <= 0) // system default tmout = hsess.getMaxInactiveInterval(); } } else tmout = wapp.getConfiguration().getSessionMaxInactiveInterval(); } } if (tmout > 0) { // unit: seconds int extra = tmout / 8; tmout += extra > 60 ? 60 : extra < 5 ? 5 : extra; // Add extra seconds to ensure it is really timeout } } final boolean keepDesktop = exec.getAttribute(Attributes.NO_CACHE) == null && !"page".equals(ExecutionsCtrl.getPageRedrawControl(exec)), groupingAllowed = isGroupingAllowed(desktop); final String progressboxPos = org.zkoss.lang.Library.getProperty("org.zkoss.zul.progressbox.position", ""); if (tmout > 0 || keepDesktop || progressboxPos.length() > 0 || !groupingAllowed) { sb.append("<script class=\"z-runonce\" type=\"text/javascript\">\nzkopt({"); if (keepDesktop) sb.append("kd:1,"); if (!groupingAllowed) sb.append("gd:1,"); if (tmout > 0) sb.append("to:").append(tmout).append(','); if (progressboxPos.length() > 0) sb.append("ppos:'").append(progressboxPos).append('\''); if (sb.charAt(sb.length() - 1) == ',') sb.setLength(sb.length() - 1); sb.append("});\n</script>"); } final Device device = Devices.getDevice(deviceType); String s = device.getEmbedded(); if (s != null) sb.append(s).append('\n'); return sb.toString(); }
/** * Open a download dialog to save the specified content at the client with the suggested file * name. * * @param media the media to download * @param flnm the suggested file name, e.g., myfile.pdf. If null, {@link Media#getName} is * assumed. */ public static void save(Media media, String flnm) { final Desktop desktop = Executions.getCurrent().getDesktop(); ((WebAppCtrl) desktop.getWebApp()) .getUiEngine() .addResponse(new AuDownload(new DownloadURL(media, flnm))); // Bug 2114380 }