📄 uiengineimpl.java
字号:
} } private static final Event nextEvent(UiVisualizer uv) { final Event evt = ((ExecutionCtrl)uv.getExecution()).getNextEvent(); return evt != null && !uv.isAborting() ? evt: null; } /** Cycle 1: * Creates all child components defined in the specified definition. * @return the first component being created. */ private static final Component[] execCreate( CreateInfo ci, NodeInfo parentInfo, Component parent) throws IOException { if (parentInfo instanceof ComponentInfo) { final ComponentInfo pi = (ComponentInfo)parentInfo; final String fulfill = pi.getFulfill(); if (fulfill != null) { //defer the creation of children new FulfillListener(fulfill, pi, parent); return new Component[0]; } } return execCreate0(ci, parentInfo, parent); } private static final Component[] execCreate0( CreateInfo ci, NodeInfo parentInfo, Component parent) throws IOException { final List created = new LinkedList(); final Page page = ci.page; final PageDefinition pagedef = parentInfo.getPageDefinition(); //note: don't use page.getDefinition because createComponents //might be called from a page other than instance's for (Iterator it = parentInfo.getChildren().iterator(); it.hasNext();) { final Object meta = it.next(); if (meta instanceof ComponentInfo) { final ComponentInfo childInfo = (ComponentInfo)meta; final ForEach forEach = childInfo.getForEach(page, parent); if (forEach == null) { if (isEffective(childInfo, page, parent)) { final Component[] children = execCreateChild(ci, parent, childInfo); for (int j = 0; j < children.length; ++j) created.add(children[j]); } } else { while (forEach.next()) { if (isEffective(childInfo, page, parent)) { final Component[] children = execCreateChild(ci, parent, childInfo); for (int j = 0; j < children.length; ++j) created.add(children[j]); } } } } else if (meta instanceof TextInfo) { //parent must be a native component final String s = ((TextInfo)meta).getValue(parent); if (s != null && s.length() > 0) parent.appendChild( ((Native)parent).getHelper().newNative(s)); } else { execNonComponent(ci, parent, meta); } } return (Component[])created.toArray(new Component[created.size()]); } private static Component[] execCreateChild( CreateInfo ci, Component parent, ComponentInfo childInfo) throws IOException { final ComponentDefinition childdef = childInfo.getComponentDefinition(); if (ComponentDefinition.ZK == childdef) { return execCreate(ci, childInfo, parent); } else if (childdef.isInlineMacro()) { final Map props = new HashMap(); props.put("includer", parent); childInfo.evalProperties(props, ci.page, parent, true); return new Component[] { ci.exec.createComponents(childdef.getMacroURI(), parent, props)}; } else { final Component child = execCreateChild0(ci, parent, childInfo); return child != null ? new Component[] {child}: new Component[0]; } } private static Component execCreateChild0( CreateInfo ci, Component parent, ComponentInfo childInfo) throws IOException { final Composer composer = childInfo.getComposer(ci.page); final ComposerExt composerExt = composer instanceof ComposerExt ? (ComposerExt)composer: null; Component child = null; try { if (composerExt != null) { childInfo = composerExt.doBeforeCompose(ci.page, parent, childInfo); if (childInfo == null) return null; } child = ci.uf.newComponent(ci.page, parent, childInfo); final boolean bNative = childInfo instanceof NativeInfo; if (bNative) setProlog(ci, child, (NativeInfo)childInfo); if (composerExt != null) composerExt.doBeforeComposeChildren(child); execCreate(ci, childInfo, child); //recursive if (bNative) setEpilog(ci, child, (NativeInfo)childInfo); if (child instanceof AfterCompose) ((AfterCompose)child).afterCompose(); if (composer != null) composer.doAfterCompose(child); ComponentsCtrl.applyForward(child, childInfo.getForward()); //applies the forward condition //1) we did it after all child created, so it may reference //to it child (thought rarely happens) //2) we did it after afterCompose, so what specified //here has higher priority than class defined by app dev if (Events.isListened(child, Events.ON_CREATE, false)) Events.postEvent( new CreateEvent(Events.ON_CREATE, child, ci.exec.getArg())); return child; } catch (Throwable ex) { boolean ignore = false; if (composerExt != null) { try { ignore = composerExt.doCatch(ex); } catch (Throwable t) { log.error("Failed to invoke doCatch for "+childInfo, t); } } if (!ignore) throw UiException.Aide.wrap(ex); return child != null && child.getPage() != null ? child: null; //return child only if attached successfully } finally { if (composerExt != null) { try { composerExt.doFinally(); } catch (Throwable ex) { throw UiException.Aide.wrap(ex); } } } } /** Executes a non-component object, such as ZScript, AttributesInfo... */ private static final void execNonComponent( CreateInfo ci, Component comp, Object meta) { final Page page = ci.page; if (meta instanceof ZScript) { final ZScript zscript = (ZScript)meta; if (zscript.isDeferred()) { ((PageCtrl)page).addDeferredZScript(comp, zscript); //isEffective is handled later } else if (isEffective(zscript, page, comp)) { final Map backup = new HashMap(); final Namespace ns = comp != null ? Namespaces.beforeInterpret(backup, comp, false): Namespaces.beforeInterpret(backup, page, false); try { page.interpret(zscript.getLanguage(), zscript.getContent(page, comp), ns); } finally { Namespaces.afterInterpret(backup, ns, false); } } } else if (meta instanceof AttributesInfo) { final AttributesInfo attrs = (AttributesInfo)meta; if (comp != null) attrs.apply(comp); //it handles isEffective else attrs.apply(page); } else if (meta instanceof VariablesInfo) { final VariablesInfo vars = (VariablesInfo)meta; if (comp != null) vars.apply(comp); //it handles isEffective else vars.apply(page); } else { throw new IllegalStateException("Unknown metainfo: "+meta); } } private static final boolean isEffective(Condition cond, Page page, Component comp) { return comp != null ? cond.isEffective(comp): cond.isEffective(page); } public Component[] createComponents(Execution exec, PageDefinition pagedef, Page page, Component parent, Map arg) { if (pagedef == null) throw new IllegalArgumentException("pagedef"); if (parent != null) { if (parent.getPage() != null) page = parent.getPage(); } else if (page != null) { parent = ((PageCtrl)page).getDefaultParent(); } if (page == null) page = getCurrentPage(exec); final ExecutionCtrl execCtrl = (ExecutionCtrl)exec; if (!execCtrl.isActivated()) throw new IllegalStateException("Not activated yet"); final Page old = execCtrl.getCurrentPage(); final PageDefinition olddef = execCtrl.getCurrentPageDefinition(); if (page != null && page != old) execCtrl.setCurrentPage(page); execCtrl.setCurrentPageDefinition(pagedef); exec.pushArg(arg != null ? arg: Collections.EMPTY_MAP); //Note: we add taglib, stylesheets and var-resolvers to the page //it might cause name pollution but we got no choice since they //are used as long as components created by this method are alive if (page != null) pagedef.initXelContext(page); final Initiators inits = Initiators.doInit(pagedef, page); try { final Component[] comps = execCreate( new CreateInfo( ((WebAppCtrl)exec.getDesktop().getWebApp()).getUiFactory(), exec, page), pagedef, parent); inits.doAfterCompose(page, comps); return comps; } catch (Throwable ex) { inits.doCatch(ex); throw UiException.Aide.wrap(ex); } finally { exec.popArg(); execCtrl.setCurrentPage(old); //restore it execCtrl.setCurrentPageDefinition(olddef); //restore it inits.doFinally(); } } public void sendRedirect(String uri, String target) { if (uri != null && uri.length() == 0) uri = null; final UiVisualizer uv = getCurrentVisualizer(); uv.setAbortingReason( new AbortBySendRedirect( uri != null ? uv.getExecution().encodeURL(uri): "", target)); } public void setAbortingReason(AbortingReason aborting) { final UiVisualizer uv = getCurrentVisualizer(); uv.setAbortingReason(aborting); } //-- Recovering desktop --// public void execRecover(Execution exec, FailoverManager failover) { final Desktop desktop = exec.getDesktop(); final Session sess = desktop.getSession(); doActivate(exec, null, true); //it must not return null try { failover.recover(sess, exec, desktop); } finally { doDeactivate(exec); } } //-- Asynchronous updates --// public void execUpdate(Execution exec, List requests, Writer out) throws IOException { execUpdate(exec, requests, null, out); } public Collection execUpdate(Execution exec, List requests, String reqId, Writer out) throws IOException { if (requests == null) throw new IllegalArgumentException("null requests"); assert D.OFF || ExecutionsCtrl.getCurrentCtrl() == null: "Impossible to re-activate for update: old="+ExecutionsCtrl.getCurrentCtrl()+", new="+exec+", reqs="+requests; final UiVisualizer uv = doActivate(exec, requests, false); if (uv == null) return null; //done (request is added to the exec currently activated) final Desktop desktop = exec.getDesktop(); final Configuration config = desktop.getWebApp().getConfiguration(); final Monitor monitor = config.getMonitor(); if (monitor != null) { try { monitor.beforeUpdate(desktop, requests); } catch (Throwable ex) { log.error(ex); } } Collection doneReqIds = null; //request IDs that have been processed boolean cleaned = false; try { config.invokeExecutionInits(exec, null); final RequestQueue rque = ((DesktopCtrl)desktop).getRequestQueue(); if (reqId != null) rque.addRequestId(reqId); final List errs = new LinkedList(); final long tmexpired = System.currentTimeMillis() + config.getMaxProcessTime(); //Tom Yeh: 20060120 //Don't process all requests if this thread has processed //a while. Thus, user could see the response sooner. for (AuRequest request; System.currentTimeMillis() < tmexpired && (request = rque.nextRequest()) != null;) { //Cycle 1: Process one request //Don't process more such that requests will be queued //adn we have the chance to optimize them try { process(exec, request, !errs.isEmpty()); } catch (ComponentNotFoundException ex) { //possible because the previous might remove some comp //so ignore it// if (log.finable()) log.fine("Component not found: "+request); } catch (Throwable ex) { handleError(ex, uv, errs); //we don't skip request to avoid mis-match between c/s } //Cycle 2: Process any pending events posted by components Event event = nextEvent(uv); do { for (; event != null; event = nextEvent(uv)) { try { process(desktop, event); } catch (Throwable ex) { handleError(ex, uv, errs); break; //skip the rest of events! } } resumeAll(desktop, uv, errs); } while ((event = nextEvent(uv)) != null); } //Cycle 2a: Handle aborting reason final AbortingReason abrn = uv.getAbortingReason(); if (abrn != null) abrn.execute(); //always execute even if !isAborting //Cycle 3: Generate output List responses; try { //Note: we have to call visualizeErrors before uv.getResponses, //since it might create/update components if (!errs.isEmpty()) visualizeErrors(exec, uv, errs); responses = uv.getResponses(); } catch (Throwable ex) { responses = new LinkedList(); responses.add(new AuAlert(Exceptions.getMessage(ex))); log.error(ex); } if (rque.endWithRequest()) responses.add(new AuEcho(desktop)); else doneReqIds = rque.clearRequestIds(); responseSequenceId(desktop, out); response(responses, out);// if (log.debugable())// if (responses.size() < 5 || log.finerable()) log.finer("Responses: "+responses);// else log.debug("Responses: "+responses.subList(0, 5)+"..."); cleaned = true; config.invokeExecutionCleanups(exec, null, errs); out.flush(); //flush before deactivating to make sure it has been sent } catch (Throwable ex) { if (!cleaned) { cleaned = true; final List errs = new LinkedList(); errs.add(ex); config.invokeExecutionCleanups(exec, null, errs); ex = errs.isEmpty() ? null: (Throwable)errs.get(0); } if (ex != null) { if (ex instanceof IOException) throw (IOException)ex; throw UiException.Aide.wrap(ex); } } finally { if (!cleaned) config.invokeExecutionCleanups(exec, null, null);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -