📄 pageimpl.java
字号:
/* PageImpl.java{{IS_NOTE Purpose: Description: History: Fri Jun 3 18:17:32 2005, Created by tomyeh}}IS_NOTECopyright (C) 2005 Potix Corporation. All Rights Reserved.{{IS_RIGHT This program is distributed under GPL Version 2.0 in the hope that it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.zk.ui.impl;import java.util.Iterator;import java.util.ListIterator;import java.util.List;import java.util.LinkedList;import java.util.ArrayList;import java.util.Map;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.AbstractMap;import java.util.Set;import java.util.HashSet;import java.util.Collection;import java.util.Collections;import java.io.Writer;import java.io.IOException;import org.zkoss.lang.D;import org.zkoss.lang.Classes;import org.zkoss.lang.Objects;import org.zkoss.lang.Strings;import org.zkoss.lang.Exceptions;import org.zkoss.lang.Expectable;import org.zkoss.util.CollectionsX;import org.zkoss.util.logging.Log;import org.zkoss.io.Serializables;import org.zkoss.xel.VariableResolver;import org.zkoss.xel.Function;import org.zkoss.xel.FunctionMapper;import org.zkoss.xel.util.DualFunctionMapper;import org.zkoss.zk.mesg.MZk;import org.zkoss.zk.ui.WebApp;import org.zkoss.zk.ui.Desktop;import org.zkoss.zk.ui.Richlet;import org.zkoss.zk.ui.Page;import org.zkoss.zk.ui.Session;import org.zkoss.zk.ui.IdSpace;import org.zkoss.zk.ui.Component;import org.zkoss.zk.ui.Executions;import org.zkoss.zk.ui.Execution;import org.zkoss.zk.ui.UiException;import org.zkoss.zk.ui.ComponentNotFoundException;import org.zkoss.zk.ui.event.EventListener;import org.zkoss.zk.ui.event.Events;import org.zkoss.zk.ui.metainfo.PageDefinition;import org.zkoss.zk.ui.metainfo.LanguageDefinition;import org.zkoss.zk.ui.metainfo.ComponentDefinition;import org.zkoss.zk.ui.metainfo.ComponentDefinitionMap;import org.zkoss.zk.ui.metainfo.DefinitionNotFoundException;import org.zkoss.zk.ui.metainfo.ZScript;import org.zkoss.zk.ui.util.Condition;import org.zkoss.zk.ui.util.PageSerializationListener;import org.zkoss.zk.ui.sys.ExecutionCtrl;import org.zkoss.zk.ui.sys.WebAppCtrl;import org.zkoss.zk.ui.sys.DesktopCtrl;import org.zkoss.zk.ui.sys.PageCtrl;import org.zkoss.zk.ui.sys.PageConfig;import org.zkoss.zk.ui.sys.ComponentCtrl;import org.zkoss.zk.ui.sys.ComponentsCtrl;import org.zkoss.zk.ui.sys.Names;import org.zkoss.zk.ui.sys.UiEngine;import org.zkoss.zk.ui.sys.IdGenerator;import org.zkoss.zk.xel.ExValue;import org.zkoss.zk.au.out.AuSetTitle;import org.zkoss.zk.scripting.Interpreter;import org.zkoss.zk.scripting.Interpreters;import org.zkoss.zk.scripting.HierachicalAware;import org.zkoss.zk.scripting.SerializableAware;import org.zkoss.zk.scripting.Namespace;import org.zkoss.zk.scripting.InterpreterNotFoundException;import org.zkoss.zk.scripting.util.AbstractNamespace;/** * An implmentation of {@link Page} and {@link PageCtrl}. * Refer to them for more details. * * <p>Note: though {@link PageImpl} is serializable, it is designed * to work with Web container to enable the serialization of sessions. * It is not suggested to serialize and desrialize it directly since * many fields might be lost. * * <p>On the other hand, it is OK to serialize and deserialize * {@link Component}. * * <p>Implementation Notes:<br> * It is not thread-safe because it is protected by the spec: * at most one thread can access a page and all its components at the same time. * * @author tomyeh */public class PageImpl implements Page, PageCtrl, java.io.Serializable { private static final Log log = Log.lookup(PageImpl.class); private static final Log _zklog = Log.lookup("org.zkoss.zk.log"); private static final long serialVersionUID = 20070413L; /** URI for redrawing as a desktop or part of another desktop. */ private final ExValue _dkURI, _pgURI; /** The component that includes this page, or null if not included. */ private transient Component _owner; /** Used to retore _owner. */ private transient String _ownerUuid; private transient Desktop _desktop; private String _id, _uuid; private String _title = "", _style = ""; private final String _path; private String _zslang; /** A list of deferred zscript [Component parent, {@link ZScript}]. */ private List _zsDeferred; /** A list of root components. */ private final List _roots = new LinkedList(); private transient List _roRoots; /** A map of fellows. */ private transient Map _fellows; /** A map of attributes. */ private transient Map _attrs; /** A map of event listener: Map(evtnm, List(EventListener)). */ private transient Map _listeners; /** The default parent. */ private transient Component _defparent; /** The reason to store it is PageDefinition is not serializable. */ private FunctionMapper _mapper; /** The reason to store it is PageDefinition is not serializable. */ private ComponentDefinitionMap _compdefs; /** The reason to store it is PageDefinition is not serializable. */ private transient LanguageDefinition _langdef; /** The header tags. */ private String _headers = ""; /** The root attributes. */ private String _rootAttrs = ""; private String _contentType, _docType, _firstLine; private Boolean _cacheable; /** A map of interpreters Map(String zslang, Interpreter ip). */ private transient Map _ips; private transient NS _ns; /** A list of {@link VariableResolver}. */ private transient List _resolvers; /** Constructs a page by giving the page definition. * * <p>Note: when a page is constructed, it doesn't belong to a desktop * yet. Caller has to invoke {@link #init} to complete * the creation of a page. * Why two phase? Contructor could be called before execution * is activated, but {@link #init} must be called in an execution. * * <p>Also note that {@link #getId} and {@link #getTitle} * are not ready until {@link #init} is called. * * @param pgdef the page definition (never null). */ public PageImpl(PageDefinition pgdef) { this(pgdef.getLanguageDefinition(), pgdef.getComponentDefinitionMap(), pgdef.getRequestPath(), pgdef.getZScriptLanguage()); } /** Constructs a page without page definition and richlet. * * @param langdef the language definition (never null) * @param compdefs the component definition map. * If null, an empty map is assumed. * @param path the request path. If null, empty is assumed. * @param zslang the zscript language. If null, "Java" is assumed. */ public PageImpl(LanguageDefinition langdef, ComponentDefinitionMap compdefs, String path, String zslang) { init(); _langdef = langdef; _dkURI = new ExValue(_langdef.getDesktopURI(), String.class); _pgURI = new ExValue(_langdef.getPageURI(), String.class); _compdefs = compdefs != null ? compdefs: new ComponentDefinitionMap( _langdef.getComponentDefinitionMap().isCaseInsensitive()); _path = path != null ? path: ""; _zslang = zslang != null ? zslang: "Java"; } /** Constructs a page by specifying a richlet. * * <p>Note: when a page is constructed, it doesn't belong to a desktop * yet. Caller has to invoke {@link #init} to complete * the creation of a page. * * <p>Also note that {@link #getId} and {@link #getTitle} * are not ready until {@link #init} is called. * * @param richlet the richlet to serve this page. * @param path the request path, or null if not available */ public PageImpl(Richlet richlet, String path) { init(); _langdef = richlet.getLanguageDefinition(); _dkURI = new ExValue(_langdef.getDesktopURI(), String.class); _pgURI = new ExValue(_langdef.getPageURI(), String.class); _compdefs = new ComponentDefinitionMap( _langdef.getComponentDefinitionMap().isCaseInsensitive()); _path = path != null ? path: ""; _zslang = "Java"; } /** Initialized the page when contructed or deserialized. */ protected void init() { _ips = new LinkedHashMap(3); _ns = new NS(); _roRoots = Collections.unmodifiableList(_roots); _attrs = new HashMap(); _fellows = new HashMap(); } /** Returns the UI engine. */ private final UiEngine getUiEngine() { return ((WebAppCtrl)_desktop.getWebApp()).getUiEngine(); } //-- Page --// private final Execution getExecution() { return _desktop != null ? _desktop.getExecution(): Executions.getCurrent(); } public final FunctionMapper getFunctionMapper() { return _mapper; } public void addFunctionMapper(FunctionMapper mapper) { _mapper = DualFunctionMapper.combine(mapper, _mapper); } public String getRequestPath() { return _path; } public final String getId() { return _id; } public final String getUuid() { return _uuid; } public void setId(String id) { if (_desktop != null) throw new UiException("Unable to change the identifier after the page is initialized"); if (id != null && id.length() > 0) _id = id; //No need to update client since it is allowed only before init(...) } public String getTitle() { return _title; } public void setTitle(String title) { if (title == null) title = ""; if (!_title.equals(title)) { _title = title; if (_desktop != null) { final Execution exec = getExecution(); if (_title.length() > 0) { _title = (String)exec.evaluate(this, _title, String.class); if (_title == null) _title = ""; } if (exec.isAsyncUpdate(this)) getUiEngine().addResponse("setTitle", new AuSetTitle(_title)); } } } public String getStyle() { return _style; } public void setStyle(String style) { if (style == null) style = ""; if (!_style.equals(style)) { _style = style; if (_desktop != null) { final Execution exec = getExecution(); if (_style.length() > 0) { _style = (String)exec.evaluate(this, _style, String.class); if (_style == null) _style = ""; } //FUTURE: might support the change of style dynamically } } } public Collection getRoots() { return _roRoots; } public Map getAttributes(int scope) { switch (scope) { case DESKTOP_SCOPE: return _desktop != null ? _desktop.getAttributes(): Collections.EMPTY_MAP; case SESSION_SCOPE: return _desktop != null ? _desktop.getSession().getAttributes(): Collections.EMPTY_MAP; case APPLICATION_SCOPE: return _desktop != null ? _desktop.getWebApp().getAttributes(): Collections.EMPTY_MAP; case PAGE_SCOPE: return _attrs; case REQUEST_SCOPE: final Execution exec = getExecution(); if (exec != null) return exec.getAttributes(); //fall thru default: return Collections.EMPTY_MAP; } } 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 doesn't belong to any ID space: "+this); 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 Map getAttributes() { return _attrs; } public Object getAttribute(String name) { return _attrs.get(name); } public Object setAttribute(String name, Object value) { return value != null ? _attrs.put(name, value): removeAttribute(name); } public Object removeAttribute(String name) { return _attrs.remove(name); } public void invalidate() { getUiEngine().addInvalidate(this); } public void removeComponents() { for (Iterator it = new ArrayList(getRoots()).iterator(); it.hasNext();) ((Component)it.next()).detach(); } public void setVariable(String name, Object val) { _ns.setVariable(name, val, true); } public boolean containsVariable(String name) { return _ns.containsVariable(name, true); } public Object getVariable(String name) { return _ns.getVariable(name, true); } public void unsetVariable(String name) { _ns.unsetVariable(name, true); } public Class getZScriptClass(String clsnm) { for (Iterator it = getLoadedInterpreters().iterator(); it.hasNext();) { Class cls = ((Interpreter)it.next()).getClass(clsnm); if (cls != null) return cls; } try { return Classes.forNameByThread(clsnm); } catch (ClassNotFoundException ex) { return null; } } public Function getZScriptFunction(String name, Class[] argTypes) { for (Iterator it = getLoadedInterpreters().iterator(); it.hasNext();) { Function mtd = ((Interpreter)it.next()).getFunction(name, argTypes); if (mtd != null) return mtd; } return null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -