org.joda.beans.ser.map.JodaBeanSimpleMapWriter Maven / Gradle / Ivy
/*
* Copyright 2001-present Stephen Colebourne
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.joda.beans.ser.map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.joda.beans.Bean;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaProperty;
import org.joda.beans.ser.JodaBeanSer;
import org.joda.beans.ser.SerCategory;
import org.joda.beans.ser.SerIterator;
import org.joda.beans.ser.SerOptional;
import org.joda.convert.StringConverter;
/**
* Provides the ability for a Joda-Bean to be written to a JSON-like in memory {@code Map}.
*
* This class contains mutable state and cannot be used from multiple threads.
* A new instance must be created for each message.
*
* The format used here is natural, with no meta-data.
* As such, it may not be possible to write some objects or read the JSON data back in.
*
* Beans are output as maps where the key is the property name.
* Most simple types, defined by Joda-Convert, are output as JSON strings.
* Null values are generally omitted, booleans and numbers are left as is.
* Maps must have a key that can be converted to a string by Joda-Convert.
* The property type needs to be known when writing/reading - properties, or
* list/map entries, that are defined as {@code Object} are unlikely to work well.
*
* Collections are output using lists, Maps as maps, with other collection types
* having a complex list-based format.
*/
public class JodaBeanSimpleMapWriter {
/**
* The settings to use.
*/
private final JodaBeanSer settings;
/**
* Creates an instance.
*
* @param settings the settings to use, not null
*/
public JodaBeanSimpleMapWriter(JodaBeanSer settings) {
JodaBeanUtils.notNull(settings, "settings");
this.settings = settings;
}
//-----------------------------------------------------------------------
/**
* Writes the bean to a string.
*
* @param bean the bean to output, not null
* @return the JSON, not null
*/
public Map write(Bean bean) {
JodaBeanUtils.notNull(bean, "bean");
return writeBean(bean, bean.getClass());
}
//-----------------------------------------------------------------------
// write a bean as a JSON object
private Map writeBean(Bean bean, Class> declaredType) {
Map result = new LinkedHashMap<>();
// property information
for (MetaProperty> prop : bean.metaBean().metaPropertyIterable()) {
if (prop.style().isSerializable() || (prop.style().isDerived() && settings.isIncludeDerived())) {
Object value = SerOptional.extractValue(prop, bean);
if (value != null) {
Object outputValue = null;
Class> propType = SerOptional.extractType(prop, bean.getClass());
if (value instanceof Bean) {
if (settings.getConverter().isConvertible(value.getClass())) {
outputValue = writeSimple(propType, value);
} else {
outputValue = writeBean((Bean) value, propType);
}
} else {
SerIterator itemIterator = settings.getIteratorFactory().create(value, prop, bean.getClass(), true);
if (itemIterator != null) {
outputValue = writeElements(itemIterator);
} else {
outputValue = writeSimple(propType, value);
}
}
result.put(prop.name(), outputValue);
}
}
}
return result;
}
//-----------------------------------------------------------------------
// write a collection
private Object writeElements(SerIterator itemIterator) {
if (itemIterator.category() == SerCategory.MAP) {
return writeMap(itemIterator);
} else if (itemIterator.category() == SerCategory.COUNTED) {
return writeCounted(itemIterator);
} else if (itemIterator.category() == SerCategory.TABLE) {
return writeTable(itemIterator);
} else if (itemIterator.category() == SerCategory.GRID) {
return writeGrid(itemIterator);
} else {
return writeArray(itemIterator);
}
}
// write list/set/array
private Object writeArray(SerIterator itemIterator) {
List