📄 abstractcomponent.java
字号:
private final UiEngine getThisUiEngine() { return ((WebAppCtrl)_page.getDesktop().getWebApp()).getUiEngine(); } //-- Component --// public final Page getPage() { return _page; } public final Desktop getDesktop() { return _page != null ? _page.getDesktop(): null; } public void setPage(Page page) { if (page != _page) setPageBefore(page, null); //append } public void setPageBefore(Page page, Component refRoot) { if (refRoot != null && (page == null || refRoot == this || refRoot.getParent() != null || refRoot.getPage() != page)) refRoot = null; if (_parent != null) throw new UiException("Only the parent of a root component can be changed: "+this); final boolean samepg = page == _page; if (!samepg) { if (page != null) { if (_page != null && _page.getDesktop() != page.getDesktop()) throw new UiException("The new page must be in the same desktop: "+page); //Not allow developers to access two desktops simutaneously checkIdSpacesDown(this, (PageCtrl)page); //No need to check UUID since checkIdSpacesDown covers it //-- a page is an ID space } else { //detach from a page checkDetach(_page); } if (_page != null) removeFromIdSpacesDown(this); } addMoved(_parent, _page, page); //Not depends on UUID if (!samepg) setPage0(page); //UUID might be changed here if (page != null && (samepg || refRoot != null)) ((PageCtrl)page).moveRoot(this, refRoot); if (!samepg && _page != null) addToIdSpacesDown(this); } /** Checks whether it is OK to detach the specified page. * @param page the page to detach (never null). */ private static void checkDetach(Page page) { final Execution exec = Executions.getCurrent(); if (exec == null) throw new UiException("You cannot access a desktop other than an event listener"); if (page.getDesktop() != exec.getDesktop()) throw new UiException("You cannot access components belong to other desktop"); } /** Called when this component is moved from the specified parent * and/or page to the new page. * * <p>Default: it notifies {@link UiEngine} to update the component * at the client (usually remove-and-add). * * <p>It is designed to let derived classes overriding this method * to disable this update. However, you rarely need to override it. * One possible but rare case: the component's * visual part at the client updates the visual representation * at the client and then notify the component at the server * to update its children accordingly. In this case, it is redudant * if we ask UI Engine to send the updates to client. * * @param oldparent the parent before moved. * The new parent can be found by calling {@link #getParent}. * @param oldpg the parent before moved. * @param newpg the new page. {@link #getPage} might return * the old page. */ protected void addMoved(Component oldparent, Page oldpg, Page newpg) { final Desktop dt; if (oldpg != null) dt = oldpg.getDesktop(); else if (newpg != null) dt = newpg.getDesktop(); else return; ((WebAppCtrl)dt.getWebApp()) .getUiEngine().addMoved(this, oldparent, oldpg, newpg); } /** Ses the page without fixing IdSpace */ private void setPage0(Page page) { if (page == _page) return; //nothing changed //assert D.OFF || _parent == null || _parent.getPage() == page; //detach final boolean bRoot = _parent == null; if (_page != null) { if (bRoot) ((PageCtrl)_page).removeRoot(this); if (page == null) { ((DesktopCtrl)_page.getDesktop()).removeComponent(this); } } final Page oldpage = _page; _page = page; if (_page != null) { if (bRoot) ((PageCtrl)_page).addRoot(this); //Not depends on uuid final Desktop desktop = _page.getDesktop(); if (oldpage == null) { if (_uuid == null || _uuid == ComponentsCtrl.ANONYMOUS_ID || desktop.getComponentByUuidIfAny(_uuid) != null) _uuid = nextUuid(desktop); if (_id == null || (this instanceof RawId)) _id = _uuid; //no need to handle ID space since it is either //anonymous or uuid is not changed ((DesktopCtrl)desktop).addComponent(this); //depends on uuid } onPageAttached(_page, oldpage); } else { onPageDetached(oldpage); } if (_spaceInfo != null && _parent == null) _spaceInfo.ns.setParent(page != null ? page.getNamespace(): null); //process all children recursively for (AbstractComponent p = _first; p != null; p = p._next) p.setPage0(page); //recursive } private String nextUuid(Desktop desktop) { final IdGenerator idgen = ((WebAppCtrl)desktop.getWebApp()).getIdGenerator(); String uuid; do { uuid = idgen != null ? idgen.nextComponentUuid(desktop, this): null; if (uuid == null) uuid = ((DesktopCtrl)desktop).getNextUuid(); } while (desktop.getComponentByUuidIfAny(uuid) != null); return uuid; } public String getId() { if (_id == null) _id = this instanceof RawId ? getUuid(): ComponentsCtrl.ANONYMOUS_ID; return _id; } public void setId(String id) { if (id == null || id.length() == 0) throw new UiException("ID cannot be empty"); if (!Objects.equals(_id, id)) { if (Names.isReserved(id) || (!(this instanceof NonFellow) && ComponentsCtrl.isAutoId(id))) throw new UiException("Invalid ID: "+id+". Cause: reserved words not allowed: "+Names.getReservedNames()); final boolean rawId = this instanceof RawId; if (rawId && _page != null && _page.getDesktop().getComponentByUuidIfAny(id) != null) throw new UiException("Replicated ID is not allowed for "+getClass()+": "+id+"\nNote: HTML/WML tags, ID must be unique"); checkIdSpaces(this, id); removeFromIdSpaces(this); if (rawId) { //we have to change UUID if (_page != null) { getThisUiEngine().addUuidChanged(this, false); //called before uuid is changed ((DesktopCtrl)_page.getDesktop()).removeComponent(this); } _uuid = _id = id; if (_page != null) { ((DesktopCtrl)_page.getDesktop()).addComponent(this); addMoved(_parent, _page, _page); } } else { _id = id; } addToIdSpaces(this); final Object xc = getExtraCtrl(); if ((xc instanceof ZidRequired) && ((ZidRequired)xc).isZidRequired()) smartUpdate("z.zid", _id); } } public final String getUuid() { if (_uuid == null) { final Execution exec = Executions.getCurrent(); _uuid = exec == null ? ComponentsCtrl.ANONYMOUS_ID: nextUuid(exec.getDesktop()); if (_id == null || (this instanceof RawId)) _id = _uuid; } return _uuid; } public final IdSpace getSpaceOwner() { Component p = this; do { if (p instanceof IdSpace) return (IdSpace)p; } while ((p = p.getParent()) != null); return _page; } public Component getFellow(String compId) { if (this instanceof IdSpace) { final Component comp = (Component)_spaceInfo.fellows.get(compId); if (comp == null) if (compId != null && ComponentsCtrl.isAutoId(compId)) throw new ComponentNotFoundException(MZk.AUTO_ID_NOT_LOCATABLE, compId); else throw new ComponentNotFoundException("Fellow component not found: "+compId); return comp; } final IdSpace idspace = getSpaceOwner(); if (idspace == null) throw new ComponentNotFoundException("This component doesn't belong to any ID space: "+this); return idspace.getFellow(compId); } public Component getFellowIfAny(String compId) { if (this instanceof IdSpace) return (Component)_spaceInfo.fellows.get(compId); final IdSpace idspace = getSpaceOwner(); return idspace == null ? null: idspace.getFellowIfAny(compId); } public Component getNextSibling() { return _next; } public Component getPreviousSibling() { return _prev; } public Component getFirstChild() { return _first; } public Component getLastChild() { return _last; } public Map getAttributes(int scope) { switch (scope) { case SPACE_SCOPE: if (this instanceof IdSpace) return _spaceInfo.attrs; final IdSpace idspace = getSpaceOwner(); return idspace instanceof Page ? ((Page)idspace).getAttributes(): idspace == null ? Collections.EMPTY_MAP: ((Component)idspace).getAttributes(SPACE_SCOPE); case PAGE_SCOPE: return _page != null ? _page.getAttributes(): Collections.EMPTY_MAP; case DESKTOP_SCOPE: return _page != null ? _page.getDesktop().getAttributes(): Collections.EMPTY_MAP; case SESSION_SCOPE: return _page != null ? _page.getDesktop().getSession().getAttributes(): Collections.EMPTY_MAP; case APPLICATION_SCOPE: return _page != null ? _page.getDesktop().getWebApp().getAttributes(): Collections.EMPTY_MAP; case COMPONENT_SCOPE: return _attrs; case REQUEST_SCOPE: final Execution exec = getExecution(); if (exec != null) return exec.getAttributes(); //fall thru default: return Collections.EMPTY_MAP; } } private final Execution getExecution() { return _page != null ? _page.getDesktop().getExecution(): Executions.getCurrent(); } public Object getAttribute(String name, int scope) { return getAttributes(scope).get(name); } public Object setAttribute(String name, Object value, int scope) { if (value != null) { final Map attrs = getAttributes(scope); if (attrs == Collections.EMPTY_MAP) throw new IllegalStateException("This component, "+this +", doesn't belong to the "+Components.scopeToString(scope)+" scope"); return attrs.put(name, value); } else { return removeAttribute(name, scope); } } public Object removeAttribute(String name, int scope) { final Map attrs = getAttributes(scope); if (attrs == Collections.EMPTY_MAP) throw new IllegalStateException("This component doesn't belong to any ID space: "+this); return attrs.remove(name); } public final Map getAttributes() { return _attrs; } public final Object getAttribute(String name) { return _attrs.get(name); } public final Object setAttribute(String name, Object value) { return value != null ? _attrs.put(name, value): _attrs.remove(name); } public final Object removeAttribute(String name) { return _attrs.remove(name); } public void setVariable(String name, Object val, boolean local) { getNamespace().setVariable(name, val, local); } public boolean containsVariable(String name, boolean local) { return getNamespace().containsVariable(name, local); } public Object getVariable(String name, boolean local) { return getNamespace().getVariable(name, local); } public void unsetVariable(String name, boolean local) { getNamespace().unsetVariable(name, local); } public Component getParent() { return _parent; } public void setParent(Component parent) { if (_parent == parent) return; //nothing changed checkParentChild(parent, this); final boolean idSpaceChanged = parent != null ? parent.getSpaceOwner() != (_parent != null ? _parent.getSpaceOwner(): _page): _page != null; if (idSpaceChanged) removeFromIdSpacesDown(this); //call removeChild and clear _parent final AbstractComponent op = _parent; if (op != null) { if (!op.inRemoving(this)) { op.markRemoving(this, true); try { op.removeChild(this); //spec: call back removeChild } finally { op.markRemoving(this, false); } } _parent = null; //op.removeChild assumes _parent not changed yet } else { if (_page != null) ((PageCtrl)_page).removeRoot(this); //Not depends on uuid } //call insertBefore and set _parent if (parent != null) { final AbstractComponent np = (AbstractComponent)parent; if (!np.inAdding(this)) { np.markAdding(this, true); try { np.insertBefore(this, null); //spec: call back inserBefore } finally { np.markAdding(this, false); } } _parent = np; //np.insertBefore assumes _parent not changed yet } //if parent == null, assume no page at all (so no addRoot) //correct _page final Page newpg = _parent != null ? _parent.getPage(): null; addMoved(op, _page, newpg); //Not depends on UUID setPage0(newpg); //UUID might be changed here if (_spaceInfo != null) //ID space owner _spaceInfo.ns.setParent( _parent != null ? _parent.getNamespace(): null); if (idSpaceChanged) addToIdSpacesDown(this); //called after setPage } /** Returns whether the child is being removed. */ private boolean inRemoving(Component child) { return _rming != null && _rming.contains(child); } /** Sets if the child is being removed. */ private void markRemoving(Component child, boolean set) { if (set) { if (_rming == null) _rming = new HashSet(2); _rming.add(child); } else { if (_rming != null && _rming.remove(child) && _rming.isEmpty()) _rming = null; } } /** Returns whether the child is being added. */ private boolean inAdding(Component child) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -