📄 parser.java
字号:
toAbsoluteURI(moldURI, true)); for (Iterator e = params.entrySet().iterator(); e.hasNext();) { final Map.Entry me = (Map.Entry)e.next(); compdef.addProperty( (String)me.getKey(), (String)me.getValue(), null); } } else if ("link".equals(target) || "meta".equals(target)) { //declare a header element pgdef.addHeader(new Header(target, params)); } else if ("page".equals(target)) { log.warning("Ignored page directive at "+pi.getLocator()); } else if ("import".equals(target)) { //import throw new UiException("The import directive can be used only at the top level, "+pi); } else { log.warning("Unknown processing instruction: "+target); } } private static void noEL(String nm, String val, Item item) throws UiException { if (val != null && val.indexOf("${") >= 0) throw new UiException(nm+" does not support EL expressions, "+item.getLocator()); } private String toAbsoluteURI(String uri, boolean allowEL) { if (uri != null && uri.length() > 0) { final char cc = uri.charAt(0); if (cc != '/' && cc != '~' && (!allowEL || uri.indexOf("${") < 0) && !Servlets.isUniversalURL(uri)) { final String dir = getLocator().getDirectory(); if (dir != null && dir.length() > 0) return dir.charAt(dir.length() - 1) == '/' ? dir + uri: dir + '/' + uri; } } return uri; } /** Parses the specified elements. */ private void parse(PageDefinition pgdef, InstanceDefinition parent, Collection items, AnnotInfo annotInfo) throws Exception { for (Iterator it = items.iterator(); it.hasNext();) { final Object o = it.next(); if (o instanceof Element) { parse(pgdef, parent, (Element)o, annotInfo); } else if (o instanceof ProcessingInstruction) { parse(pgdef, (ProcessingInstruction)o); } else if ((o instanceof Text) || (o instanceof CData)) { String label = ((Item)o).getText(); final LanguageDefinition parentlang = getLanguageDefinition(pgdef, parent); if (!parentlang.isRawLabel()) label = label.trim(); if (label.trim().length() > 0) //consider as a label parentlang.newLabelDefinition(parent, label); } } } private static final LanguageDefinition getLanguageDefinition(PageDefinition pgdef, InstanceDefinition instdef) { for (; instdef != null; instdef = instdef.getParent()) { LanguageDefinition langdef = instdef.getLanguageDefinition(); if (langdef != null) return langdef; } return pgdef.getLanguageDefinition(); } /** Parse an component definition specified in the given element. */ private void parse(PageDefinition pgdef, InstanceDefinition parent, Element el, AnnotInfo annotInfo) throws Exception { final String nm = el.getLocalName(); final Namespace ns = el.getNamespace(); final String pref = ns != null ? ns.getPrefix(): ""; final String uri = ns != null ? ns.getURI(): ""; final LanguageDefinition langdef = pgdef.getLanguageDefinition(); if ("zscript".equals(nm) && isZkElement(langdef, nm, pref, uri)) { parseZScript(parent, el, annotInfo); } else if ("attribute".equals(nm) && isZkElement(langdef, nm, pref, uri)) { parseAttribute(parent, el, annotInfo); } else if ("custom-attributes".equals(nm) && isZkElement(langdef, nm, pref, uri)) { parseCustomAttribute(parent, el, annotInfo); } else if (LanguageDefinition.ANNO_NAMESPACE.equals(uri)) { parseAnnotation(el, annotInfo); } else { //if (D.ON && log.debugable()) log.debug("component: "+nm+", ns:"+ns); final InstanceDefinition instdef; if ("zk".equals(nm) && isZkElement(langdef, nm, pref, uri)) { if (annotInfo.clear()) log.warning("Annotations are ignored since <zk> doesn't support them, "+el.getLocator()); instdef = new InstanceDefinition( parent, ComponentDefinition.ZK, "zk"); } else { if (LanguageDefinition.ZK_NAMESPACE.equals(uri)) throw new UiException("Unknown ZK component: "+el); final LanguageDefinition complangdef; if (isDefault(langdef, pref, uri)) { complangdef = langdef; } else { complangdef = LanguageDefinition.lookup(uri); } ComponentDefinition compdef = pgdef.getComponentDefinitionMap().get(nm); if (compdef != null) { instdef = new InstanceDefinition(parent, compdef); } else if (complangdef.hasComponentDefinition(nm)) { compdef = complangdef.getComponentDefinition(nm); instdef = new InstanceDefinition(parent, compdef); } else { compdef = complangdef.getDynamicTagDefinition(); if (compdef == null) throw new DefinitionNotFoundException("Component definition not found: "+nm+" in "+complangdef); instdef = new InstanceDefinition(parent, compdef, nm); } //process use first because addProperty needs it final String use = el.getAttribute("use"); if (!isEmpty(use)) { noEL("use", use, el); instdef.setImplementationClass(use); //Resolve later since might defined in zscript } } String ifc = null, unless = null, forEach = null, forEachBegin = null, forEachEnd = null; AnnotInfo attrAnnotInfo = null; for (Iterator it = el.getAttributeItems().iterator(); it.hasNext();) { final Attribute attr = (Attribute)it.next(); final Namespace attrns = attr.getNamespace(); final String attnm = attr.getLocalName(); final String attval = attr.getValue(); if (attrns != null && LanguageDefinition.ANNO_NAMESPACE.equals(attrns.getURI())) { if (attrAnnotInfo == null) attrAnnotInfo = new AnnotInfo(); attrAnnotInfo.addRaw(attnm, attval); } else if ("if".equals(attnm)) { ifc = attval; } else if ("unless".equals(attnm)) { unless = attval; } else if ("forEach".equals(attnm)) { forEach = attval; } else if ("forEachBegin".equals(attnm)) { forEachBegin = attval; } else if ("forEachEnd".equals(attnm)) { forEachEnd = attval; } else if (!"use".equals(attnm)) { 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)) { addAttribute(instdef, attns, attnm, attval, null); if (attrAnnotInfo != null) attrAnnotInfo.updateAnnotations(instdef, attnm); } } } instdef.setCondition(ConditionImpl.getInstance(ifc, unless)); instdef.setForEach(forEach, forEachBegin, forEachEnd); annotInfo.updateAnnotations(instdef, null); parse(pgdef, instdef, el.getChildren(), annotInfo); //recursive } } private void parseZScript(InstanceDefinition parent, Element el, AnnotInfo annotInfo) throws Exception { //if (!el.getElements().isEmpty()) // throw new UiException("Child elements are not allowed for the zscript element, "+el.getLocator()); if (el.getAttributeItem("forEach") != null) throw new UiException("forEach not applicable to zscript, "+el.getLocator()); if (annotInfo.clear()) log.warning("Annotations are ignored since <zscript> doesn't support them, "+el.getLocator()); final String ifc = el.getAttribute("if"), unless = el.getAttribute("unless"), zsrc = el.getAttribute("src"); final Condition cond = ConditionImpl.getInstance(ifc, unless); if (!isEmpty(zsrc)) { final ZScript zs; if (zsrc.indexOf("${") >= 0) { zs = new ZScript(zsrc, cond, getLocator()); } else { final URL url = getLocator().getResource(zsrc); if (url == null) throw new FileNotFoundException("File not found: "+zsrc+", at "+el.getLocator()); zs = new ZScript(url, cond); } parent.appendChild(zs); } final String script = el.getText(true); if (!isEmpty(script)) parent.appendChild(new ZScript(script, cond)); } private void parseAttribute(InstanceDefinition parent, Element el, AnnotInfo annotInfo) 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 attval = el.getText(false); //don't trim!! if (!isEmpty(attval)) { addAttribute(parent, null, attnm, attval, ConditionImpl.getInstance( el.getAttribute("if"), el.getAttribute("unless"))); } annotInfo.updateAnnotations(parent, attnm); } private void parseCustomAttribute(InstanceDefinition parent, Element el, AnnotInfo annotInfo) throws Exception { //if (!el.getElements().isEmpty()) // throw new UiException("Child elements are not allowed for the custom-attributes element, "+el.getLocator()); if (parent instanceof PageDefinition) throw new UiException("custom-attributes must be used under a component, "+el.getLocator()); if (annotInfo.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.addCustomAttributes( new CustomAttributes(attrs, scope, ConditionImpl.getInstance(ifc, unless))); } private void parseAnnotation(Element el, AnnotInfo annotInfo) 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()); } annotInfo.add(el.getLocalName(), attrs); } /** Whether the name space belongs to the default language. */ private static final boolean isDefault(LanguageDefinition langdef, String pref, String uri) { return ("".equals(pref) && "".equals(uri)) || langdef.getNamespace().equals(uri); } /** Whether a string is null or empty. */ private static boolean isEmpty(String s) { return s == null || s.length() == 0; } /** Returns whether the element is conflict with the language definition. * @param pref namespace's prefix * @param uri namespace's URI */ private static final boolean isZkElement(LanguageDefinition langdef, String nm, String pref, String uri) { if (isDefault(langdef, pref, uri)) return !langdef.hasComponentDefinition(nm); return LanguageDefinition.ZK_NAMESPACE.equals(uri); } /** Parse an attribute and adds it to the definition. */ private void addAttribute(InstanceDefinition instdef, Namespace attrns, String name, String value, Condition cond) throws Exception { if (Events.isValid(name)) { boolean bZkAttr = attrns == null; if (!bZkAttr) { final String pref = attrns.getPrefix(), uri = attrns.getURI(); final LanguageDefinition langdef = instdef.getLanguageDefinition(); if (langdef == null) bZkAttr = true; else if (isDefault(langdef, pref, uri)) bZkAttr = !langdef.isDynamicReservedAttributes("[event]"); else bZkAttr = LanguageDefinition.ZK_NAMESPACE.equals(uri); } if (bZkAttr) { instdef.addEventHandler(name, value, cond); return; //done } } instdef.addProperty(name, value, cond); } /** Information of annotations. */ private static class AnnotInfo { /** A list of Object[] = {String annotName, Map annotAttrs}; */ final List _annots = new LinkedList(); /** Adds an annotation definition. */ private void add(String annotName, Map annotAttrs) { if (annotName == null || annotName.length() == 0) throw new IllegalArgumentException("empty"); _annots.add(new Object[] {annotName, annotAttrs}); } private void addRaw(String annotName, String rawValue) { final Map attrs = Maps.parse(null, rawValue, ',', '\''); add(annotName, attrs); } /** Updates the annotations to the specified instance definition. * Note: it clears all annotation definitions before returning. * * @param instdef the instance definition to update * @param propName the property name */ private void updateAnnotations(InstanceDefinition instdef, String propName) { for (Iterator it = _annots.iterator(); it.hasNext();) { final Object[] info = (Object[])it.next(); final String annotName = (String)info[0]; final Map annotAttrs = (Map)info[1]; if (propName != null) instdef.addAnnotation(propName, annotName, annotAttrs); else instdef.addAnnotation(annotName, annotAttrs); } _annots.clear(); } /** Clears all annotation definitions. * @return true if one or more annotation definitions are defined * (thru {@link #add}). */ private boolean clear() { if (!_annots.isEmpty()) { _annots.clear(); return true; } return false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -