📄 parser.java
字号:
} else if ("forEachEnd".equals(attnm) && isZkAttr(langdef, attrns)) { forEachEnd = attval; } else if ("fulfill".equals(attnm) && isZkAttr(langdef, attrns)) { compInfo.setFulfill(attval); } else if (!("use".equals(attnm) && isZkAttr(langdef, attrns))) { final Namespace attns = attr.getNamespace(); final String attpref = attns != null ? attns.getPrefix(): ""; final String attruri = attns != null ? attns.getURI(): ""; if (!"xmlns".equals(attpref) && !("xmlns".equals(attnm) && "".equals(attpref)) && !"http://www.w3.org/2001/XMLSchema-instance".equals(attruri)) { final int len = attval.length(); if (len >= 3 && attval.charAt(0) == '@' && attval.charAt(1) == '{' && attval.charAt(len-1) == '}') { //annotation if (attrAnnHelper == null) attrAnnHelper = new AnnotationHelper(); attrAnnHelper.addByCompoundValue( attval.substring(2, len -1)); attrAnnHelper.applyAnnotations(compInfo, "self".equals(attnm) ? null: attnm, true); } else { addAttribute(compInfo, attns, attnm, attval, null); if (attrAnnHelper != null) attrAnnHelper.applyAnnotations(compInfo, attnm, true); } } } } compInfo.setCondition(ConditionImpl.getInstance(ifc, unless)); compInfo.setForEach(forEach, forEachBegin, forEachEnd); annHelper.applyAnnotations(compInfo, null, true); parse(pgdef, compInfo, el.getChildren(), annHelper); //recursive //optimize native components if (compInfo instanceof NativeInfo && !compInfo.getChildren().isEmpty()) optimizeNativeInfos((NativeInfo)compInfo); } } private void parseZScript(NodeInfo parent, Element el, AnnotationHelper annHelper) { if (el.getAttributeItem("forEach") != null) throw new UiException("forEach not applicable to <zscript>, "+el.getLocator()); if (annHelper.clear()) log.warning("Annotations are ignored since <zscript> doesn't support them, "+el.getLocator()); final String ifc = el.getAttributeValue("if"), unless = el.getAttributeValue("unless"), zsrc = el.getAttributeValue("src"); final boolean deferred = "true".equals(el.getAttributeValue("deferred")); String zslang = el.getAttributeValue("language"); if (zslang == null) { zslang = parent.getPageDefinition().getZScriptLanguage(); //we have to resolve it in parser since a page might be //created by use of createComponents } else { noEmpty("language", zslang, el); noEL("language", zslang, el); } final ConditionImpl cond = ConditionImpl.getInstance(ifc, unless); if (!isEmpty(zsrc)) { //ignore empty (not error) final ZScript zs; if (zsrc.indexOf("${") >= 0) { zs = new ZScript(parent.getEvaluatorRef(), zslang, zsrc, cond, getLocator()); } else { final URL url = getLocator().getResource(zsrc); if (url == null) throw new UiException("File not found: "+zsrc+", at "+el.getLocator()); //don't throw FileNotFoundException since Tomcat 'eats' it zs = new ZScript(parent.getEvaluatorRef(), zslang, url, cond); } if (deferred) zs.setDeferred(true); parent.appendChild(zs); } final String script = el.getText(true); if (!isEmpty(script)) { final ZScript zs = new ZScript(parent.getEvaluatorRef(), zslang, script, cond); if (deferred) zs.setDeferred(true); parent.appendChild(zs); } } private static void parseAttribute(ComponentInfo parent, Element el, AnnotationHelper annHelper) throws Exception { //if (!el.getElements().isEmpty()) // throw new UiException("Child elements are not allowed for the attribute element, "+el.getLocator()); if (el.getAttributeItem("forEach") != null) throw new UiException("forEach not applicable to attribute, "+el.getLocator()); //FUTURE: handling the namespace of if and unless final String attnm = IDOMs.getRequiredAttributeValue(el, "name"); final String trim = el.getAttributeValue("trim"); noEL("trim", trim, el); final String attval = el.getText(trim != null && "true".equals(trim)); addAttribute(parent, null, attnm, attval, ConditionImpl.getInstance( el.getAttributeValue("if"), el.getAttributeValue("unless"))); annHelper.applyAnnotations(parent, attnm, true); } private static void parseCustomAttributes(NodeInfo parent, Element el, AnnotationHelper annHelper) throws Exception { //if (!el.getElements().isEmpty()) // throw new UiException("Child elements are not allowed for <custom-attributes>, "+el.getLocator()); if (parent instanceof PageDefinition) throw new UiException("custom-attributes must be used under a component, "+el.getLocator()); if (annHelper.clear()) log.warning("Annotations are ignored since <custom-attribute> doesn't support them, "+el.getLocator()); String ifc = null, unless = null, scope = null; final Map attrs = new HashMap(); for (Iterator it = el.getAttributeItems().iterator(); it.hasNext();) { final Attribute attr = (Attribute)it.next(); final String attnm = attr.getLocalName(); final String attval = attr.getValue(); if ("if".equals(attnm)) { ifc = attval; } else if ("unless".equals(attnm)) { unless = attval; } else if ("scope".equals(attnm)) { scope = attval; } else if ("forEach".equals(attnm)) { throw new UiException("forEach not applicable to <custom-attributes>, "+el.getLocator()); } else { attrs.put(attnm, attval); } } if (!attrs.isEmpty()) parent.appendChild(new AttributesInfo( parent.getEvaluatorRef(), attrs, scope, ConditionImpl.getInstance(ifc, unless))); } private static void parseVariables(NodeInfo parent, Element el, AnnotationHelper annHelper) throws Exception { //if (!el.getElements().isEmpty()) // throw new UiException("Child elements are not allowed for <variables> element, "+el.getLocator()); if (el.getAttributeItem("forEach") != null) throw new UiException("forEach not applicable to <variables>, "+el.getLocator()); if (annHelper.clear()) log.warning("Annotations are ignored since <variables> doesn't support them, "+el.getLocator()); String ifc = null, unless = null; boolean local = false; final Map vars = new HashMap(); for (Iterator it = el.getAttributeItems().iterator(); it.hasNext();) { final Attribute attr = (Attribute)it.next(); final String attnm = attr.getLocalName(); final String attval = attr.getValue(); if ("if".equals(attnm)) { ifc = attval; } else if ("unless".equals(attnm)) { unless = attval; } else if ("local".equals(attnm)) { local = "true".equals(attval); } else if ("forEach".equals(attnm)) { throw new UiException("forEach not applicable to <variables>, "+el.getLocator()); } else { vars.put(attnm, attval); } } if (!vars.isEmpty()) parent.appendChild(new VariablesInfo( parent.getEvaluatorRef(), vars, local, ConditionImpl.getInstance(ifc, unless))); } private static void parseAnnotation(Element el, AnnotationHelper annHelper) throws Exception { if (!el.getElements().isEmpty()) throw new UiException("Child elements are not allowed for the annotations, "+el.getLocator()); final Map attrs = new HashMap(); for (Iterator it = el.getAttributeItems().iterator(); it.hasNext();) { final Attribute attr = (Attribute)it.next(); attrs.put(attr.getLocalName(), attr.getValue()); } annHelper.add(el.getLocalName(), attrs); } /** Whether a string is null or empty. */ private static boolean isEmpty(String s) { return s == null || s.length() == 0; } /** Whether the name space belongs to the default language. */ private static final boolean isDefaultNS(LanguageDefinition langdef, String pref, String uri) { return (!langdef.isNative() && "".equals(pref) && "".equals(uri)) || langdef.getNamespace().equals(uri); } /** Returns whether it is a ZK element. * @param pref namespace's prefix * @param uri namespace's URI */ private static final boolean isZkElement(LanguageDefinition langdef, String nm, String pref, String uri) { if (isDefaultNS(langdef, pref, uri)) return !langdef.hasComponentDefinition(nm); return LanguageDefinition.ZK_NAMESPACE.equals(uri); } /** Returns whether it is a ZK attribute. */ private static final boolean isZkAttr(LanguageDefinition langdef, Namespace attrns) { //if native we will make sure URI is ZK or lang's namespace if (langdef.isNative()) { final String uri = attrns.getURI(); return LanguageDefinition.ZK_NAMESPACE.equals(uri) || langdef.getNamespace().equals(uri); } return true; } /** Parse an attribute and adds it to the definition. */ private static void addAttribute(ComponentInfo compInfo, Namespace attrns, String name, String value, ConditionImpl cond) throws Exception { if (Events.isValid(name)) { boolean bZkAttr = attrns == null; if (!bZkAttr) { String pref = attrns.getPrefix(), uri = attrns.getURI(); LanguageDefinition langdef = compInfo.getLanguageDefinition(); if (langdef == null) bZkAttr = true; else if (isDefaultNS(langdef, pref, uri)) bZkAttr = !langdef.isDynamicReservedAttributes("[event]"); else bZkAttr = LanguageDefinition.ZK_NAMESPACE.equals(uri); } if (bZkAttr) { final ZScript zscript = ZScript.parseContent(value); if (zscript.getLanguage() == null) zscript.setLanguage( compInfo.getPageDefinition().getZScriptLanguage()); //resolve it here instead of runtime since createComponents compInfo.addEventHandler(name, zscript, cond); return; //done } } compInfo.addProperty(name, value, cond); } /** Adds the declared namespaces to the native info, if necessary. */ private static void addDeclaredNamespace( NativeInfo nativeInfo, Collection namespaces, LanguageDefinition langdef) { for (Iterator it = namespaces.iterator(); it.hasNext();) { final Namespace ns = (Namespace)it.next(); final String uri = ns.getURI(); boolean bNatPrefix = uri.startsWith(LanguageDefinition.NATIVE_NAMESPACE_PREFIX); if (bNatPrefix || (langdef.isNative() && !LanguageDefinition.ZK_NAMESPACE.equals(uri) && !LanguageDefinition.ANNO_NAMESPACE.equals(uri) && !LanguageDefinition.NATIVE_NAMESPACE.equals(uri) && !langdef.getNamespace().equals(uri))) nativeInfo.addDeclaredNamespace( new Namespace(ns.getPrefix(), bNatPrefix ? uri.substring(LanguageDefinition.NATIVE_NAMESPACE_PREFIX.length()): uri)); } } /** Minimizes the native infos such that UiEngine creates * the minimal number of components. */ private static void optimizeNativeInfos(NativeInfo compInfo) { //Optimize 1: merge to prolog, if the first children are //native and have no child for (Iterator it = compInfo.getChildren().iterator(); it.hasNext();) { final Object o = it.next(); if (o instanceof NativeInfo) { final NativeInfo childInfo = (NativeInfo)o; if (!childInfo.getChildren().isEmpty()) break; childInfo.setParentDirectly(null); } else if (o instanceof ComponentInfo) { break; } compInfo.addPrologChildDirectly(o); it.remove(); //detach it from the children list } //Optimize 2: merge to epilog if the last children, are //native and have no child int sz = compInfo.getChildren().size(); if (sz >= 0) { final ListIterator it = compInfo.getChildren().listIterator(sz); while (it.hasPrevious()) { final Object o = it.previous(); if (o instanceof NativeInfo) { final NativeInfo childInfo = (NativeInfo)o; if (!childInfo.getChildren().isEmpty()) { it.next(); break; } childInfo.setParentDirectly(null); } else if (o instanceof ComponentInfo) { it.next(); break; } } while (it.hasNext()) { final Object o = it.next(); compInfo.addEpilogChildDirectly(o); it.remove(); } } //Optimize 3: merge to split child //If there is only one native child, we make it a split child and //make all its children (grand-chidren) up one level if (compInfo.getChildren().size() == 1 && !compInfo.withForEach() && compInfo.getSplitChild() == null /*just in case*/) { Iterator it = compInfo.getChildren().iterator(); final Object o = it.next(); if (o instanceof NativeInfo) { final NativeInfo childInfo = (NativeInfo)o; childInfo.setParentDirectly(null); compInfo.setSplitChild(childInfo); it.remove(); for (it = childInfo.getChildren().iterator(); it.hasNext();) { final Object gc = it.next(); it.remove(); compInfo.appendChildDirectly(gc); if (gc instanceof ComponentInfo) ((ComponentInfo)gc).setParentDirectly(compInfo); } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -