📄 languagedefinition.java
字号:
/* LanguageDefinition.java{{IS_NOTE Purpose: Description: History: Tue May 31 18:01:38 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.metainfo;import java.util.Collection;import java.util.Map;import java.util.HashMap;import java.util.Set;import java.util.HashSet;import java.util.List;import java.util.LinkedList;import java.util.Collections;import java.util.Iterator;import org.zkoss.util.resource.Locator;import org.zkoss.util.logging.Log;import org.zkoss.xel.taglib.Taglibs;import org.zkoss.xel.taglib.Taglib;import org.zkoss.web.servlet.JavaScript;import org.zkoss.web.servlet.StyleSheet;import org.zkoss.zk.mesg.MZk;import org.zkoss.zk.ui.Page;import org.zkoss.zk.ui.Component;import org.zkoss.zk.ui.ext.Macro;import org.zkoss.zk.ui.ext.Native;import org.zkoss.zk.ui.UiException;import org.zkoss.zk.xel.Evaluator;import org.zkoss.zk.xel.impl.SimpleEvaluator;import org.zkoss.zk.xel.impl.EvaluatorRef;import org.zkoss.zk.device.Devices;import org.zkoss.zk.device.DeviceNotFoundException;import org.zkoss.zk.ui.metainfo.impl.ComponentDefinitionImpl;/** * A definition of a language, such as xul. * * @author tomyeh */public class LanguageDefinition { private static final Log log = Log.lookup(LanguageDefinition.class); //static// /** A map of (String name or namespace, LanguageDefinition). */ private static final Map _ldefByName = new HashMap(); /** A map of (String ext, LanguageDefinition). */ private static final Map _ldefsByExt = new HashMap(); /** A map of (String deviceType, List(LanguageDefinition). */ private static final Map _ldefsByClient = new HashMap(); /** The namespace for ZK. It is mainly used to resolve special components * and attributes, such as zscript and use. */ public static final String ZK_NAMESPACE = "http://www.zkoss.org/2005/zk"; /** The namespace for ZK annotations. */ public static final String ANNO_NAMESPACE = "http://www.zkoss.org/2005/zk/annotation"; /** The namespace for ZK native namespace. * @since 3.0.0 */ public static final String NATIVE_NAMESPACE = "http://www.zkoss.org/2005/zk/native"; /** The namespace for ZK native namespace prefix. * If a namespace starts with {@link #NATIVE_NAMESPACE_PREFIX} ("native:"), * it means it is also a native space ({@link #NATIVE_NAMESPACE} * but the namespace prefix and uri will be generated. * * <p>For example, * <pre><code><s:svg xmlns:s="native:http://www.w3.org/2000/svg"/></code></pre> * * <p>generates the following output: * * <pre><code><s:svg xmlns:s="http://www.w3.org/2000/svg"/></code></pre> * * where the prefix <code>s</code> and URI <code>http://www.w3.org/2000/svg</code> * are both generated. * * @since 3.0.0 */ public static final String NATIVE_NAMESPACE_PREFIX = "native:"; /** the device type that this definition belongs to. */ private final String _deviceType; /** name */ private final String _name; /** The name space. */ private final String _ns; /** The extensions supported by this language definition. */ private List _exts; /** The component map. */ private final ComponentDefinitionMap _compdefs; /** The component name for dynamic tags. */ private String _dyntagnm; /** The component definition for dynamic tags. */ private ComponentDefinition _dyntagDefn; /** The set of reserved attributes used by _dyntagDefn. */ private Set _dyntagRvAttrs; /** Map(String lang, String script). */ private final Map _initscripts = new HashMap(); /** Map(String lang, String script). */ private final Map _eachscripts = new HashMap(); /** The URI to render a page. */ private final String _desktopURI, _pageURI; /** A list of Taglib. */ private final List _taglibs = new LinkedList(); /** A list of JavaScript. */ private final List _js = new LinkedList(), _rojs = Collections.unmodifiableList(_js); private final Map _jsmods = new HashMap(5), _rojsmods = Collections.unmodifiableMap(_jsmods); /** A list of StyleSheet. */ private final List _ss = new LinkedList(), _ross = Collections.unmodifiableList(_ss); private final Locator _locator; /** The label template. */ private LabelTemplate _labeltmpl; /** The macro template. */ private MacroTemplate _macrotmpl; /** The native component definition. */ private ComponentDefinition _nativedef; /** The evaluator. */ private Evaluator _eval; /** The evaluator reference. */ private EvaluatorRef _evalr; /** Whether it is a native language. */ private final boolean _native; /** Returns whether the specified language exists. */ public static boolean exists(String name) { init(); synchronized (_ldefByName) { return _ldefByName.containsKey(name); } } /** Returns the language definition of the specified name or namespace. * * <p>Note: the name and namespace of any language cannot be the same. * * @param name the name or the namespace; If null or empty, "xul/html" is assumed. * @exception DefinitionNotFoundException is thrown if the definition * is not found */ public static final LanguageDefinition lookup(String name) { init(); if (name == null || name.length() == 0) name = "xul/html"; final LanguageDefinition langdef; synchronized (_ldefByName) { langdef = (LanguageDefinition)_ldefByName.get(name); } if (langdef == null) if (ZK_NAMESPACE.equals(name)) throw new DefinitionNotFoundException(ZK_NAMESPACE+" is reserved. Use it only with reserved elements and attributes, such as zscript and attribute"); else throw new DefinitionNotFoundException("Language not found: "+name); return langdef; } /** Returns the language definition by specifying an extension. * * @param ext the extension, e.g., "zul". * If null, "zul" is assumed. * @exception DefinitionNotFoundException is thrown if the definition * is not found */ public static final LanguageDefinition getByExtension(String ext) { init(); if (ext == null) ext = "zul"; final LanguageDefinition langdef; synchronized (_ldefsByExt) { langdef = (LanguageDefinition)_ldefsByExt.get(ext); } if (langdef == null) throw new DefinitionNotFoundException("Language not found for extension "+ext); return langdef; } /** Associates an extension to a language. * * @param lang the language name. It cannot be null. * @param ext the extension, e.g., "svg". It cannot be null. * @since 3.0.0 */ public static final void addExtension(String ext, String lang) { if (lang == null || ext == null) throw new IllegalArgumentException(); init(); final LanguageDefinition langdef = lookup(lang); //ensure it exists synchronized (_ldefsByExt) { _ldefsByExt.put(ext, langdef); } } /** Returns a readonly list of language definitions belong to * the specified device type. * * <p>A device type identifies the type of a client. For example, "ajax" * represents all Web browsers with Ajax support, * while "mil" represents clients that supports * <i>Mobile User interface markup Language</i> (on Limited Connected Device, * such as mobile phones). * * @param deviceType the device type, e.g., "ajax". * @see #getDeviceType * @see #getAll */ public static final List getByDeviceType(String deviceType) { init(); final List ldefs; synchronized (_ldefsByClient) { ldefs = (List)_ldefsByClient.get(deviceType); } return ldefs != null ? ldefs: Collections.EMPTY_LIST; } /** Returns a readonly list of all language definitions * regardless of the device type. * * @see #getByDeviceType * @since 2.4.1 */ public static final List getAll() { init(); final List list = new LinkedList(); synchronized (_ldefsByClient) { for (Iterator it = _ldefsByClient.values().iterator(); it.hasNext();) { list.addAll((List)it.next()); } } return list; } /** Returns a readonly collection of all device types. * @see #getByDeviceType */ public static final Collection getDeviceTypes() { init(); return _ldefsByClient.keySet(); } private static final void init() { DefinitionLoaders.load(); } /** Constructs a language defintion. * * <p>Note: the name and namespace of any language cannot be the same. * In other words, each language has two names, name and namespace. * You can find the language back by either of them via * {@link #lookup}. * * @param deviceType the device type; never null or empty * @param desktopURI the URI used to render a desktop; never null. * @param pageURI the URI used to render a page; never null. * @param ignoreCase whether the component name is case-insensitive * @param bNative whether it is native (i.e., all tags are * {@link org.zkoss.zk.ui.ext.Native}). * If native, the namespaces found in a ZUML page is no longer * used to specified a language. Rather, it is output to the client * directly. */ public LanguageDefinition(String deviceType, String name, String namespace, List extensions, String desktopURI, String pageURI, boolean ignoreCase, boolean bNative, Locator locator) { if (deviceType == null || deviceType.length() == 0) throw new UiException("deviceType cannot be empty"); if (!Devices.exists(deviceType)) throw new DeviceNotFoundException(deviceType, MZk.NOT_FOUND, deviceType); if (name == null || name.length() == 0) throw new UiException("name cannot be empty"); if (namespace == null || namespace.length() == 0) throw new UiException("namespace cannot be empty"); if (ZK_NAMESPACE.equals(namespace)) throw new UiException(ZK_NAMESPACE+" is reserved."); if (desktopURI == null || desktopURI.length() == 0) throw new UiException("The URI for desktop cannot be empty"); if (pageURI == null || pageURI.length() == 0) throw new UiException("The URI for page cannot be empty"); if (locator == null) throw new UiException("locator cannot be null"); _deviceType = deviceType; _name = name; _ns = namespace; _desktopURI = desktopURI; _pageURI = pageURI; _locator = locator; _native = bNative; _compdefs = new ComponentDefinitionMap(ignoreCase); boolean replWarned = false; synchronized (_ldefByName) { if (!_ldefByName.containsKey(name) && _ldefByName.containsKey(namespace)) throw new UiException("Different language, "+name+", with the same namespace, "+namespace); _ldefByName.put(namespace, this); final Object old = _ldefByName.put(name, this); if (old != null) { final List ldefs = (List)_ldefsByClient.get(deviceType); if (ldefs != null) ldefs.remove(old); replWarned = true; log.warning("Replicated language: "+name+", overriden by "+this); //it is possible if zcommon.jar is placed in both //WEB-INF/lib and shared/lib, i.e., appear twice in the class path //We overwrite because shared/lib apears first due to //getResources is used (parent first) } } if (extensions != null) { synchronized (_ldefsByExt) { for (Iterator it = extensions.iterator(); it.hasNext();) { final String ext = (String)it.next(); final Object old = _ldefsByExt.put(ext, this); if (!replWarned && old != null) log.warning("Extension "+ext+", overriden by "+this); } } _exts = Collections.unmodifiableList(extensions); } else { _exts = Collections.EMPTY_LIST; } synchronized (_ldefsByClient) { List ldefs = (List)_ldefsByClient.get(deviceType); if (ldefs == null) _ldefsByClient.put(deviceType, ldefs = new LinkedList()); ldefs.add(this); } } /** Returns the device type that this definition belongs to. * * <p>A device type identifies the type of a client. For example, "ajax" * represents all HTML compatible clients (aka., browsers), * while "mil" represents clients that supports * <i>Mobile Interactive markup Language</i> (on Limited Connected Device, * such as mobile phones). */ public String getDeviceType() { return _deviceType; } /** Returns whether this is a native language. * If true, it means all tags in a ZUML page is considered as * native and all namespaces (except ZK namespace) are output * the client directly. * * @since 3.0.0 */ public boolean isNative() { return _native; } /** Returns name of this language. * Each language definition has a unique name and namespace. */ public String getName() { return _name; } /** Returns the name space. * Each language definition has a unique name and namespace. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -