/*
* Created by Andrey Cherkashin (acherkashin)
* http://acherkashin.me
*
* License
* Copyright (c) 2015 Andrey Cherkashin
* The project released under the MIT license: http://opensource.org/licenses/MIT
*/
package com.juniform;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @author acherkashin
*/
public class JUniformObject implements Iterable<JUniformObject>
{
public final static JUniformObject OBJECT_NIL = new JUniformObject();
protected final Object _value;
protected final List<Object> _array;
protected List<Object> _getArray() {
return _array;
}
protected final Map<Object,Object> _map;
protected Map<Object,Object> _getMap() {
return _map;
}
/**
* Private constructor for a NIL object
*/
private JUniformObject() {
_value = null;
_array = null;
_map = null;
}
/**
* Returns a statement whether this object is a map
* @return
*/
public boolean isMapValue() {
return _getMap() != null;
}
/**
* Returns a statement whether this object is an array
* @return
*/
public boolean isArrayValue() {
return _getArray() != null;
}
/**
* Returns whether the stored value is null
* @return
*/
public boolean isNull() {
return getValue() == null;
}
/**
* Returns whether the stored value is null
* @return
*/
public boolean isNotNull() {
return getValue() != null;
}
/**
* Constructor for creating a Uniform object from a custom value
* @param value Storing value
*/
@SuppressWarnings("unchecked")
public JUniformObject(Object value) {
_value = value;
if (_value instanceof List) {
_array = (List<Object>)_value;
} else {
_array = null;
}
if (_value instanceof Map) {
_map = (Map<Object,Object>)_value;
} else {
_map = null;
}
}
/**
* Returns property of a stored map or a NULL uniform object
* @param key Key to search
* @return JUniformObject
*/
public JUniformObject getProperty(Object key) {
Map<Object,Object> map = _getMap();
if (map == null) {
return OBJECT_NIL;
}
if (false == map.containsKey(key)) {
return OBJECT_NIL;
}
Object value = map.get(key);
if (value instanceof JUniformObject) {
return (JUniformObject)value;
} else {
return new JUniformObject(map.get(key));
}
}
/**
* Returns amount of properties in a stored map
* @return
*/
public int getPropertiesCount() {
Map<Object,Object> map = _getMap();
if (map == null) {
return 0;
}
return map.size();
}
/**
* Returns a value stored in the object
* @return
*/
public Object getValue() {
return _value;
}
// ---------------------------------------------------------------------- //
// DEFAULT OUTPUTS
// ---------------------------------------------------------------------- //
public boolean toBooleanDefault(boolean defaultValue) {
Boolean value = toBoolean();
return value == null ? defaultValue : value;
}
public int toIntegerDefault(int defaultValue) {
Integer value = toInteger();
return value == null ? defaultValue : value;
}
public long toLongDefault(long defaultValue) {
Long value = toLong();
return value == null ? defaultValue : value;
}
public float toFloatDefault(float defaultValue) {
Float value = toFloat();
return value == null ? defaultValue : value;
}
public double toDoubleDefault(double defaultValue) {
Double value = toDouble();
return value == null ? defaultValue : value;
}
public String toStringDefault(String defaultValue) {
String value = toString();
return value == null ? defaultValue : value;
}
// ---------------------------------------------------------------------- //
// OUTPUTS
// ---------------------------------------------------------------------- //
/**
* Returns a stored value as a boolean
* @return
*/
public Boolean toBoolean() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof Boolean) {
return (Boolean)value;
}
if (null != value.toString()) switch (value.toString()) {
case "true":
return true;
case "false":
return false;
default:
return null;
}
return null;
}
/**
* Returns a stored value as a string
* @return
*/
@Override
public String toString() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof String) {
return (String)value;
}
return value.toString();
}
/**
* Returns a stored value as an Integer
* @return
*/
public Integer toInteger() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof Float) {
return (int)Math.round((float)value);
}
else if (value instanceof Double) {
Long longValue = (long)Math.round((double)value);
return (int)Math.max(Math.min(Integer.MAX_VALUE, longValue), Integer.MIN_VALUE);
}
else if (value instanceof Integer) {
return (int)value;
}
else if (value instanceof Long) {
// safe long to int
return (int)Math.max(Math.min(Integer.MAX_VALUE, (Long)value), Integer.MIN_VALUE);
}
try {
return Integer.parseInt(value.toString());
} catch (NumberFormatException ex) {
try {
return (int)Math.round(Float.parseFloat(value.toString()));
} catch(NumberFormatException ex2) {
return null;
}
}
}
/**
* Returns a stored value as a Long
* @return
*/
public Long toLong() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof Float) {
return (long)Math.round((float)value);
}
else if (value instanceof Double) {
return (long)Math.round((double)value);
}
else if (value instanceof Integer) {
return (long)(int)value;
}
else if (value instanceof Long) {
return (long)value;
}
try {
return Long.parseLong(value.toString());
} catch (NumberFormatException ex) {
try {
return (long)Math.round(Double.parseDouble(value.toString()));
} catch(NumberFormatException ex2) {
return null;
}
}
}
/**
* Returns a stored value as a Double
* @return
*/
public Double toDouble() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof Double) {
return (double)value;
}
try {
return Double.parseDouble(value.toString());
} catch (NumberFormatException ex) {
return null;
}
}
/**
* Returns a stored value as a Float
* @return
*/
public Float toFloat() {
Object value = getValue();
if (value == null) {
return null;
}
if (value instanceof Float) {
return (float)value;
}
try {
return Float.parseFloat(value.toString());
} catch (NumberFormatException ex) {
return null;
}
}
/**
* Returns an element from an array
* @param index Array index
* @return
*/
public JUniformObject getElementByIndex(int index) {
List<Object> array = _getArray();
if (array == null) {
return JUniformObject.OBJECT_NIL;
}
if (index < 0 || index > _array.size() - 1) {
return JUniformObject.OBJECT_NIL;
}
Object object = array.get(index);
if (object instanceof JUniformObject) {
return (JUniformObject)object;
} else {
return new JUniformObject(object);
}
}
/**
* Returns a size of an array
* @return
*/
public int getElementsCount() {
List<Object> array = _getArray();
if (array == null) {
return 0;
}
return array.size();
}
/**
* Returns an iterator if that's an array. Returns a NULL object iterator instead
* @return
*/
@Override
public Iterator<JUniformObject> iterator() {
Iterator<JUniformObject> it = new Iterator<JUniformObject>() {
private int _index = 0;
@Override
public boolean hasNext() {
if (_array == null) {
return false;
}
return _index < _array.size();
}
@Override
public JUniformObject next() {
Object object = _array.get(_index++);
if (false == (object instanceof JUniformObject)) {
object = new JUniformObject(object);
}
return (JUniformObject)object;
}
@Override
public void remove() {}
};
return it;
}
/**
* Map entry set iteration iteration
* @return
*/
public Set<Map.Entry<Object,JUniformObject>> entrySet() {
Set<Map.Entry<Object,JUniformObject>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
}
private Set<Map.Entry<Object,JUniformObject>> entrySet = null;
private final class EntrySet extends AbstractSet<Map.Entry<Object,JUniformObject>> {
Map<Object,Object> _map;
private EntrySet() {
_map = _getMap();
}
@Override
public Iterator<Map.Entry<Object,JUniformObject>> iterator() {
return new EntryIterator(_map.entrySet().iterator());
}
@Override
public boolean contains(Object o) {
return _map.entrySet().contains(o);
}
@Override
public boolean remove(Object o) {
return _map.entrySet().remove(o);
}
@Override
public int size() {
return _map.entrySet().size();
}
@Override
public void clear() {
_map.entrySet().clear();
}
}
private final class EntryIterator implements Iterator<Map.Entry<Object,JUniformObject>> {
private final Iterator<Map.Entry<Object,Object>> _iterator;
private EntryIterator(Iterator<Map.Entry<Object,Object>> iterator) {
_iterator = iterator;
}
@Override
public boolean hasNext() {
return _iterator.hasNext();
}
@Override
public Map.Entry<Object,JUniformObject> next() {
Map.Entry<Object,Object> entry = _iterator.next();
Object object = entry.getValue();
if (false == (object instanceof JUniformObject)) {
object = new JUniformObject(object);
}
return new Entry(entry.getKey(), (JUniformObject)object);
}
@Override
public void remove() {}
}
private final class Entry implements Map.Entry<Object,JUniformObject> {
private final Object _key;
private final JUniformObject _value;
private Entry(Object key, JUniformObject value) {
_key = key;
_value = value;
}
@Override
public Object getKey() {
return _key;
}
@Override
public JUniformObject getValue() {
return _value;
}
@Override
public JUniformObject setValue(JUniformObject value) { return null; }
}
}