001package org.jsoup.nodes;
002
003import org.jsoup.helper.Validate;
004
005import java.util.List;
006
007abstract class LeafNode extends Node {
008    Object value; // either a string value, or an attribute map (in the rare case multiple attributes are set)
009
010    protected final boolean hasAttributes() {
011        return value instanceof Attributes;
012    }
013
014    @Override
015    public final Attributes attributes() {
016        ensureAttributes();
017        return (Attributes) value;
018    }
019
020    private void ensureAttributes() {
021        if (!hasAttributes()) {
022            Object coreValue = value;
023            Attributes attributes = new Attributes();
024            value = attributes;
025            if (coreValue != null)
026                attributes.put(nodeName(), (String) coreValue);
027        }
028    }
029
030    String coreValue() {
031        return attr(nodeName());
032    }
033
034    void coreValue(String value) {
035        attr(nodeName(), value);
036    }
037
038    @Override
039    public String attr(String key) {
040        Validate.notNull(key);
041        if (!hasAttributes()) {
042            return key.equals(nodeName()) ? (String) value : EmptyString;
043        }
044        return super.attr(key);
045    }
046
047    @Override
048    public Node attr(String key, String value) {
049        if (!hasAttributes() && key.equals(nodeName())) {
050            this.value = value;
051        } else {
052            ensureAttributes();
053            super.attr(key, value);
054        }
055        return this;
056    }
057
058    @Override
059    public boolean hasAttr(String key) {
060        ensureAttributes();
061        return super.hasAttr(key);
062    }
063
064    @Override
065    public Node removeAttr(String key) {
066        ensureAttributes();
067        return super.removeAttr(key);
068    }
069
070    @Override
071    public String absUrl(String key) {
072        ensureAttributes();
073        return super.absUrl(key);
074    }
075
076    @Override
077    public String baseUri() {
078        return hasParent() ? parent().baseUri() : "";
079    }
080
081    @Override
082    protected void doSetBaseUri(String baseUri) {
083        // noop
084    }
085
086    @Override
087    public int childNodeSize() {
088        return 0;
089    }
090
091    @Override
092    protected List<Node> ensureChildNodes() {
093        throw new UnsupportedOperationException("Leaf Nodes do not have child nodes.");
094    }
095}