org.zkoss.zk.ui.metainfo.HeaderInfo Maven / Gradle / Ivy
/* HeaderInfo.java
{{IS_NOTE
Purpose:
Description:
History:
Thu Sep 14 22:02:29 2006, Created by tomyeh
}}IS_NOTE
Copyright (C) 2006 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
}}IS_RIGHT
*/
package org.zkoss.zk.ui.metainfo;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.zkoss.html.HTMLs;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.ConditionImpl;
import org.zkoss.zk.xel.Evaluator;
import org.zkoss.zk.xel.ExValue;
/**
* Represents a header element, such as <?link> and <?meta>
* directives on the ZUML page.
* They are usually represented as directives in ZUML.
* For example, the link and meta directives represent <link>
* and <meta> HTML tags, respectively.
*
* Notice
*
* - Directives are evaluated before all other tags. Thus, it is not
* possible to set a value in zscript and then reference it in an attribute
* of the directive.
* - If a page is included by another page with the instant mode
* ({@link org.zkoss.zul.Include#getMode}), the directives will be ignored.
* - EL is allowed for every attribute.
* - Since 5.0.0, the if and unless attributes are supported.
*
*
* It is not serializable.
*
* @author tomyeh
* @see ResponseHeaderInfo
*/
public class HeaderInfo { //directive
private final String _name;
/** A list of AttrInfo. */
private final List _attrs;
private final ConditionImpl _cond;
/** Constructor.
*
* Note: it detects the href attribute (from the attrs argument), and
* encodes it with {@link Executions#encodeURL}.
*
* @param name the tag name, such as link (never null or empty).
* @param attrs a map of (String, String) attributes.
*/
public HeaderInfo(String name, Map attrs, ConditionImpl cond) {
if (name == null || name.length() == 0)
throw new IllegalArgumentException("empty");
_name = name;
_cond = cond;
if (attrs == null || attrs.isEmpty()) {
_attrs = Collections.emptyList();
} else {
_attrs = new LinkedList();
for (Map.Entry me: attrs.entrySet()) {
final String nm = me.getKey(), val = me.getValue();
_attrs.add(new AttrInfo(nm, new ExValue(val, String.class)));
}
}
}
/** Returns the tag name of this header element.
*/
public String getName() {
return _name;
}
/** Returns as HTML tag(s) representing this header element.
*
* @param page the page containing this header element.
* It is used to evaluate EL expression, if any, contained in the value.
* @since 6.0.0
*/
public String toHTML(PageDefinition pgdef, Page page) {
final Evaluator eval = pgdef.getEvaluator();
if (_cond != null && !_cond.isEffective(eval, page))
return "";
final boolean bScript = "script".equals(_name),
bStyle = !bScript && "style".equals(_name);
//1. scan content
final StringBuffer sb = new StringBuffer(128);
if (bScript || bStyle) {
String content = null;
boolean srcFound = false;
for (AttrInfo attr: _attrs) {
final String nm = attr.name;
if ("content".equals(nm)) {
content = (String)attr.value.getValue(eval, page);
} else {
srcFound = srcFound || "src".equals(nm) || "href".equals(nm);
}
}
if (content != null) {
sb.append('<').append(_name).append(" type=\"text/")
.append(bScript ? "javascript": "css").append("\">\n")
.append(content)
.append("\n").append(_name).append('>');
if (srcFound) sb.append('\n');
}
if (!srcFound)
return sb.toString(); //no more to generate
}
sb.append('<').append(bStyle ? "link": _name);
boolean relFound = false, typeFound = false;
for (AttrInfo attr: _attrs) {
final String nm = attr.name;
if ((bScript || bStyle) && "content".equals(nm))
continue; //skip
relFound = bStyle && (relFound || "rel".equals(nm));
typeFound = (bScript || bStyle) && (typeFound || "type".equals(nm));
String val = (String)attr.value.getValue(eval, page);
if (val == null || val.length() == 0)
val = "";
else if ("href".equals(nm) || ((bScript || bStyle) && "src".equals(nm)))
val = Executions.encodeURL(val);
HTMLs.appendAttribute(sb,
bStyle && "src".equals(nm) ? "href":
bScript && "href".equals(nm) ? "src": nm, val);
}
if (bStyle && !relFound)
sb.append(" rel=\"stylesheet\"");
if ((bScript || bStyle) && !typeFound)
sb.append(" type=\"text/")
.append(bScript ? "javascript": "css").append('"');
return sb.append(bScript ? ">\n": "/>").toString();
}
private static class AttrInfo {
private final String name;
private final ExValue value;
private AttrInfo(String name, ExValue value) {
this.name = name;
this.value = value;
}
}
}