/** * Generates and returns the ZK specific HTML tags such as stylesheet and JavaScript. * * <p>For each desktop, we have to generate a set of HTML tags to load ZK Client engine, style * sheets and so on. For ZUL pages, it is generated automatically by page.dsp. However, for ZHTML * pages, we have to generate these tags with special component such as org.zkoss.zhtml.Head, such * that the result HTML page is legal. * * @param exec the execution (never null) * @return the string holding the HTML tags, or null if already generated. * @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). * @see #outHeaderZkTags */ public static String outZkTags(Execution exec, WebApp wapp, String deviceType) { if (exec.getAttribute(ATTR_ZK_TAGS_GENERATED) != null) return null; exec.setAttribute(ATTR_ZK_TAGS_GENERATED, Boolean.TRUE); final StringBuffer sb = new StringBuffer(512) .append('\n') .append(outLangStyleSheets(exec, wapp, deviceType)) .append(outLangJavaScripts(exec, wapp, deviceType)); final Desktop desktop = exec.getDesktop(); if (desktop != null && exec.getAttribute(ATTR_DESKTOP_JS_GENED) == null) { sb.append("<script class=\"z-runonce\" type=\"text/javascript\">\nzkdt('") .append(desktop.getId()) .append("','") .append(getContextURI(exec)) .append("','") .append(desktop.getUpdateURI(null)) .append("','") .append(desktop.getRequestPath()) .append("');") .append(outSpecialJS(desktop)) .append("\n</script>\n"); } return sb.toString(); }
public Set<? extends Component> getAvailableAtClient() { if (!isCropper()) return null; final Tree tree = getTree(); final Component parent = getParent(); final Execution exe = Executions.getCurrent(); final String attrnm = VISIBLE_ITEM + tree.getUuid(); Map<Treeitem, Boolean> map = cast((Map) exe.getAttribute(attrnm)); if (map == null) { // Test very simple case first since getVisibleItems costly if (parent instanceof Treeitem) { for (Treeitem ti = (Treeitem) parent; ; ) { if (!ti.isOpen()) return Collections.emptySet(); Component gp = ti.getParent().getParent(); if (!(gp instanceof Treeitem)) break; ti = (Treeitem) gp; } } map = tree.getVisibleItems(); Executions.getCurrent().setAttribute(attrnm, map); } return map.keySet(); // yes, we return all visible items, not just direct children // in other words, we consider the whole tree as a single scope // See also bug 2814504 }
/** Returns the first line to be generated to the output, or null if no special first line. */ public static final String outFirstLine(Execution exec, Page page) { if (exec.getAttribute(FIRST_LINE_GENED) == null && !exec.isAsyncUpdate(null)) { exec.setAttribute(FIRST_LINE_GENED, Boolean.TRUE); return trimAndLF(((PageCtrl) page).getFirstLine()); } return ""; }
/** Returns the doc type, or null if not available. It is null or <!DOCTYPE ...>. */ public static final String outDocType(Execution exec, Page page) { if (exec.getAttribute(DOCTYPE_GENED) == null && !exec.isAsyncUpdate(null)) { exec.setAttribute(DOCTYPE_GENED, Boolean.TRUE); final String docType = ((PageCtrl) page).getDocType(); return trimAndLF(docType != null ? docType : page.getDesktop().getDevice().getDocType()); } return ""; }
/** * Returns the content of the specified condition that will be placed inside the header element of * the specified page, or null if it was generated before. For HTML, the header element is the * HEAD element. * * <p>Notice that this method ignores the following invocations against the same page in the same * execution. In other words, it is safe to invoke this method multiple times. * * @param before whether to return the headers that shall be shown before ZK's CSS/JS headers. If * true, only the headers that shall be shown before (such as meta) are returned. If true, * only the headers that shall be shown after (such as link) are returned. */ public static final String outHeaders(Execution exec, Page page, boolean before) { if (page == null) return ""; String attr = "zkHeaderGened" + page.getUuid(); if (before) attr += "Bf"; if (exec.getAttribute(attr) != null) return null; exec.setAttribute(attr, Boolean.TRUE); // generated only once return before ? ((PageCtrl) page).getBeforeHeadTags() : ((PageCtrl) page).getAfterHeadTags(); }
/** * Generates the unavailable message in HTML tags, if any. * * @param exec the execution (never null) */ public static String outUnavailable(Execution exec) { if (exec.getAttribute(ATTR_UNAVAILABLE_GENED) == null && !exec.isAsyncUpdate(null)) { exec.setAttribute(ATTR_UNAVAILABLE_GENED, Boolean.TRUE); final Device device = exec.getDesktop().getDevice(); String s = device.getUnavailableMessage(); return s != null ? "<noscript>\n" + s + "\n</noscript>" : ""; } return ""; // nothing to generate }
/** * Returns HTML tags to include all style sheets that are defined in all languages of the * specified device (never null). * * <p>In addition to style sheets defined in lang.xml and lang-addon.xml, it also include: * * <ol> * <li>The style sheet specified in the theme-uri parameter. * </ol> * * <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 outLangStyleSheets(Execution exec, WebApp wapp, String deviceType) { if (exec.isAsyncUpdate(null) || exec.getAttribute(ATTR_LANG_CSS_GENED) != null) return ""; // nothing to generate exec.setAttribute(ATTR_LANG_CSS_GENED, Boolean.TRUE); final StringBuffer sb = new StringBuffer(512); for (StyleSheet ss : getStyleSheets(exec, wapp, deviceType)) append(sb, ss, exec, null); if (sb.length() > 0) sb.append('\n'); return sb.toString(); }
private static Map<Component, ShadowInfo> getShadowInfos(boolean autoCreate) { Execution exec = Executions.getCurrent(); if (exec == null) return null; Map<Component, ShadowInfo> result = cast((Map) exec.getAttribute(COMPONENT_INFO)); if (result == null && autoCreate) { result = new HashMap<Component, ShadowInfo>(); exec.setAttribute(COMPONENT_INFO, result); } return result; }
public BindingAnnotationInfoChecker getAnnotationInfoChecker() { Execution exec = Executions.getCurrent(); if (exec == null) return null; BindingAnnotationInfoChecker checker = (BindingAnnotationInfoChecker) exec.getAttribute(CHECKER_KEY); if (checker == null) { checker = createDefaultAnnotationInfoChecker(); exec.setAttribute(CHECKER_KEY, checker); } return checker; }
public BindingExecutionInfoCollector getExecutionInfoCollector() { Execution exec = Executions.getCurrent(); if (exec == null) return null; BindingExecutionInfoCollector collector = (BindingExecutionInfoCollector) exec.getAttribute(COLLECTOR_KEY); if (collector == null) { collector = createBindingExecutionInfoCollector(); exec.setAttribute(COLLECTOR_KEY, collector); } return collector; }
/** * Returns whether a component can directly generate HTML tags to the output. This flag is used by * components that can generate the content directly, such as {@link * org.zkoss.zk.ui.HtmlNativeComponent} * * @see #setDirectContent */ public static boolean isDirectContent(Execution exec) { if (exec == null) exec = Executions.getCurrent(); return exec != null && exec.getAttribute(ATTR_DIRECT_CONTENT) != null; }
/** * Returns if the ZK specific HTML tags are generated. * * @since 5.0.3 */ public static boolean isZkTagsGenerated(Execution exec) { return exec.getAttribute(ATTR_ZK_TAGS_GENERATED) != null; }
/** * Returns the render context, or null if not available. It is used to render the content that * will appear before the content generated by {@link ContentRenderer}, such as crawlable content. * * @param exec the execution. If null, {@link Executions#getCurrent} is assumed. */ public static final RenderContext getRenderContext(Execution exec) { if (exec == null) exec = Executions.getCurrent(); return exec != null ? (RenderContext) exec.getAttribute(ATTR_RENDER_CONTEXT) : null; }
/** * 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(); }