package org.yaml.snakeyaml.representer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
import org.yaml.snakeyaml.introspector.PropertyUtils;
import org.yaml.snakeyaml.nodes.AnchorNode;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.SequenceNode;
import org.yaml.snakeyaml.nodes.Tag;
public abstract class BaseRepresenter {
protected final Map<Class<?>, Represent> representers = new HashMap<Class<?>, Represent>();
protected Represent nullRepresenter;
protected final Map<Class<?>, Represent> multiRepresenters = new LinkedHashMap<Class<?>, Represent>();
protected DumperOptions.ScalarStyle defaultScalarStyle = null;
protected FlowStyle defaultFlowStyle = FlowStyle.AUTO;
protected final Map<Object, Node> representedObjects = new IdentityHashMap<Object, Node>() {
private static final long serialVersionUID = -5576159264232131854L;
public Node put(Object key, Node value) {
return super.put(key, new AnchorNode(value));
}
};
protected Object objectToRepresent;
private PropertyUtils propertyUtils;
private boolean explicitPropertyUtils = false;
public Node represent(Object data) {
Node node = representData(data);
representedObjects.clear();
objectToRepresent = null;
return node;
}
protected final Node representData(Object data) {
objectToRepresent = data;
if (representedObjects.containsKey(objectToRepresent)) {
Node node = representedObjects.get(objectToRepresent);
return node;
}
if (data == null) {
Node node = nullRepresenter.representData(null);
return node;
}
Node node;
Class<?> clazz = data.getClass();
if (representers.containsKey(clazz)) {
Represent representer = representers.get(clazz);
node = representer.representData(data);
} else {
for (Class<?> repr : multiRepresenters.keySet()) {
if (repr != null && repr.isInstance(data)) {
Represent representer = multiRepresenters.get(repr);
node = representer.representData(data);
return node;
}
}
if (multiRepresenters.containsKey(null)) {
Represent representer = multiRepresenters.get(null);
node = representer.representData(data);
} else {
Represent representer = representers.get(null);
node = representer.representData(data);
}
}
return node;
}
protected Node representScalar(Tag tag, String value, DumperOptions.ScalarStyle style) {
if (style == null) {
style = this.defaultScalarStyle;
}
Node node = new ScalarNode(tag, value, null, null, style);
return node;
}
protected Node representScalar(Tag tag, String value) {
return representScalar(tag, value, null);
}
protected Node representSequence(Tag tag, Iterable<?> sequence, DumperOptions.FlowStyle flowStyle) {
int size = 10;
if (sequence instanceof List<?>) {
size = ((List<?>) sequence).size();
}
List<Node> value = new ArrayList<Node>(size);
SequenceNode node = new SequenceNode(tag, value, flowStyle);
representedObjects.put(objectToRepresent, node);
DumperOptions.FlowStyle bestStyle = FlowStyle.FLOW;
for (Object item : sequence) {
Node nodeItem = representData(item);
if (!(nodeItem instanceof ScalarNode && ((ScalarNode) nodeItem).isPlain())) {
bestStyle = FlowStyle.BLOCK;
}
value.add(nodeItem);
}
if (flowStyle == FlowStyle.AUTO) {
if (defaultFlowStyle != FlowStyle.AUTO) {
node.setFlowStyle(defaultFlowStyle);
} else {
node.setFlowStyle(bestStyle);
}
}
return node;
}
protected Node representMapping(Tag tag, Map<?, ?> mapping, DumperOptions.FlowStyle flowStyle) {
List<NodeTuple> value = new ArrayList<NodeTuple>(mapping.size());
MappingNode node = new MappingNode(tag, value, flowStyle);
representedObjects.put(objectToRepresent, node);
DumperOptions.FlowStyle bestStyle = FlowStyle.FLOW;
for (Map.Entry<?, ?> entry : mapping.entrySet()) {
Node nodeKey = representData(entry.getKey());
Node nodeValue = representData(entry.getValue());
if (!(nodeKey instanceof ScalarNode && ((ScalarNode) nodeKey).isPlain())) {
bestStyle = FlowStyle.BLOCK;
}
if (!(nodeValue instanceof ScalarNode && ((ScalarNode) nodeValue).isPlain())) {
bestStyle = FlowStyle.BLOCK;
}
value.add(new NodeTuple(nodeKey, nodeValue));
}
if (flowStyle == FlowStyle.AUTO) {
if (defaultFlowStyle != FlowStyle.AUTO) {
node.setFlowStyle(defaultFlowStyle);
} else {
node.setFlowStyle(bestStyle);
}
}
return node;
}
public void setDefaultScalarStyle(ScalarStyle defaultStyle) {
this.defaultScalarStyle = defaultStyle;
}
public ScalarStyle getDefaultScalarStyle() {
if (defaultScalarStyle == null) {
return ScalarStyle.PLAIN;
}
return defaultScalarStyle;
}
public void setDefaultFlowStyle(FlowStyle defaultFlowStyle) {
this.defaultFlowStyle = defaultFlowStyle;
}
public FlowStyle getDefaultFlowStyle() {
return this.defaultFlowStyle;
}
public void setPropertyUtils(PropertyUtils propertyUtils) {
this.propertyUtils = propertyUtils;
this.explicitPropertyUtils = true;
}
public final PropertyUtils getPropertyUtils() {
if (propertyUtils == null) {
propertyUtils = new PropertyUtils();
}
return propertyUtils;
}
public final boolean isExplicitPropertyUtils() {
return explicitPropertyUtils;
}
}