package core.framework.impl.template.node;
import core.framework.api.util.Exceptions;
import core.framework.api.util.Maps;
import core.framework.impl.template.TemplateMetaContext;
import core.framework.impl.template.fragment.ContainerFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author neo
*/
public class Attributes {
public final Map<String, Attribute> attributes = Maps.newLinkedHashMap();
public void add(Attribute attribute) {
attributes.put(attribute.name, attribute);
}
public void buildTemplate(ContainerFragment parent, TemplateMetaContext context) {
validate();
for (Attribute attribute : attributes.values()) {
if (skip(attribute)) continue;
if (attribute.isCDNAttribute()) {
attribute.addCDNAttribute(parent, context);
} else if (attribute.isDynamic()) {
if (attribute.isDynamicBooleanAttribute()) attribute.addBooleanAttribute(parent, context);
else attribute.addValueAttribute(parent, context);
} else if (attribute.isMessage()) {
attribute.addMessageAttribute(parent, context);
} else {
attribute.addStaticContent(parent);
}
}
}
private boolean skip(Attribute attribute) {
String name = attribute.name;
if ("xmlns:c".equals(name) || "xmlns:m".equals(name)
|| "c:text".equals(name)
|| "c:html".equals(name)
|| "m:text".equals(name)
|| "c:include".equals(name)
|| "c:for".equals(name)
|| "c:if".equals(name))
return true;
return !attribute.isDynamic() && (attributes.containsKey("c:" + name) || attributes.containsKey("m:" + name)); // there is dynamic attribute to overwrite
}
public boolean containDynamicContent() {
return attributes.containsKey("c:text")
|| attributes.containsKey("m:text")
|| attributes.containsKey("c:html")
|| attributes.containsKey("c:include");
}
public Attribute dynamicContentAttribute() {
Attribute attribute = attributes.get("c:text");
if (attribute != null) return attribute;
attribute = attributes.get("m:text");
if (attribute != null) return attribute;
attribute = attributes.get("c:html");
if (attribute != null) return attribute;
return attributes.get("c:include");
}
public List<Attribute> flowAttributes() {
List<Attribute> attributes = new ArrayList<>();
this.attributes.forEach((name, attr) -> {
if ("c:if".equals(name) || "c:for".equals(name)) attributes.add(attr);
});
return attributes;
}
private void validate() {
int count = 0;
Attribute attribute = attributes.get("c:text");
if (attribute != null) count++;
attribute = attributes.get("m:text");
if (attribute != null) count++;
attribute = attributes.get("c:html");
if (attribute != null) count++;
attribute = attributes.get("c:include");
if (attribute != null) count++;
if (count > 1 && attribute != null)
throw Exceptions.error("element must not have more than one dynamic content attribute, attribute={}, location={}", attribute.name, attribute.location);
}
}