IOException, YamlException {
boolean isRoot = this.isRoot;
this.isRoot = false;
if (object == null) {
emitter.emit(new ScalarEvent(null, null, new boolean[] {true, true}, null, (char)0));
return;
}
Class valueClass = object.getClass();
boolean unknownType = fieldClass == null;
if (unknownType) fieldClass = valueClass;
if (object instanceof Enum) {
emitter.emit(new ScalarEvent(null, null, new boolean[] {true, true}, ((Enum)object).name(), (char)0));
return;
}
String anchor = null;
if (!Beans.isScalar(valueClass)) {
anchor = anchoredObjects.get(object);
if (config.writeConfig.autoAnchor) {
Integer count = referenceCount.get(object);
if (count == null) {
emitter.emit(new AliasEvent(anchoredObjects.get(object)));
return;
}
if (count > 1) {
referenceCount.remove(object);
if (anchor == null) {
anchor = String.valueOf(nextAnchor++);
anchoredObjects.put(object, anchor);
}
}
}
}
String tag = null;
boolean showTag = false;
if (unknownType || valueClass != fieldClass || config.writeConfig.alwaysWriteClassName) {
showTag = true;
if ((unknownType || fieldClass == List.class) && valueClass == ArrayList.class) showTag = false;
if ((unknownType || fieldClass == Map.class) && valueClass == HashMap.class) showTag = false;
if (fieldClass == Set.class && valueClass == HashSet.class) showTag = false;
if (valueClass == defaultType) showTag = false;
if (showTag) {
tag = config.classNameToTag.get(valueClass.getName());
if (tag == null) tag = valueClass.getName();
}
}
for (Entry<Class, ScalarSerializer> entry : config.scalarSerializers.entrySet()) {
if (entry.getKey().isAssignableFrom(valueClass)) {
ScalarSerializer serializer = entry.getValue();
emitter.emit(new ScalarEvent(null, tag, new boolean[] {tag == null, tag == null}, serializer.write(object), (char)0));
return;
}
}
if (Beans.isScalar(valueClass)) {
emitter.emit(new ScalarEvent(null, null, new boolean[] {true, true}, String.valueOf(object), (char)0));
return;
}
if (object instanceof Collection) {
emitter.emit(new SequenceStartEvent(anchor, tag, !showTag, false));
for (Object item : (Collection)object) {
if (isRoot && !config.writeConfig.writeRootElementTags) elementType = item.getClass();
writeValue(item, elementType, null, null);
}
emitter.emit(Event.SEQUENCE_END);
return;
}
if (object instanceof Map) {
emitter.emit(new MappingStartEvent(anchor, tag, !showTag, false));
for (Object item : ((Map)object).entrySet()) {
Entry entry = (Entry)item;
writeValue(entry.getKey(), null, null, null);
if (isRoot && !config.writeConfig.writeRootElementTags) elementType = entry.getValue().getClass();
writeValue(entry.getValue(), elementType, null, null);
}
emitter.emit(Event.MAPPING_END);
return;
}
if (fieldClass.isArray()) {
elementType = fieldClass.getComponentType();
emitter.emit(new SequenceStartEvent(anchor, null, true, false));
for (int i = 0, n = Array.getLength(object); i < n; i++)
writeValue(Array.get(object, i), elementType, null, null);
emitter.emit(Event.SEQUENCE_END);
return;
}
// Value must be a bean.
Object prototype = null;
if (!config.writeConfig.writeDefaultValues && valueClass != Class.class) {
prototype = defaultValuePrototypes.get(valueClass);
if (prototype == null && Beans.getDeferredConstruction(valueClass, config) == null) {
try {
prototype = Beans.createObject(valueClass, config.privateConstructors);
} catch (InvocationTargetException ex) {
throw new YamlException("Error creating object prototype to determine default values.", ex);
}
defaultValuePrototypes.put(valueClass, prototype);
}
}
Set<Property> properties;
try {
properties = Beans.getProperties(valueClass, config.beanProperties, config.privateFields, config);
} catch (IntrospectionException ex) {
throw new YamlException("Error inspecting class: " + valueClass.getName(), ex);
}
emitter.emit(new MappingStartEvent(anchor, tag, !showTag, false));
for (Property property : properties) {
try {
Object propertyValue = property.get(object);
if (prototype != null) {
// Don't output properties that have the default value for the prototype.
Object prototypeValue = property.get(prototype);
if (propertyValue == null && prototypeValue == null) continue;
if (propertyValue != null && prototypeValue != null && prototypeValue.equals(propertyValue)) continue;
}
emitter.emit(new ScalarEvent(null, null, new boolean[] {true, true}, property.getName(), (char)0));
Class propertyElementType = config.propertyToElementType.get(property);
Class propertyDefaultType = config.propertyToDefaultType.get(property);
writeValue(propertyValue, property.getType(), propertyElementType, propertyDefaultType);
} catch (Exception ex) {
throw new YamlException("Error getting property '" + property + "' on class: " + valueClass.getName(), ex);