public <V extends Object> ValueWriter<V> getValueWriter(V value)
{
Class<? extends Object> clazz = value == null ? Void.TYPE : value.getClass();
ValueWriter writer = null; // TODO _cachedWriters.get(clazz);
if(writer == null || !writer.isComplete())
{
ValueWriter.Factory<V> factory = (ValueWriter.Factory<V>) (_writerMap.get(clazz));
if(factory == null)
{
if(value instanceof List)
{
factory = _writerMap.get(List.class);
_writerMap.put(value.getClass(), factory);
writer = factory.newInstance(this);
if(writer.isCacheable())
{
_cachedWriters.put(clazz, writer);
}
writer.setValue(value);
}
else if(value instanceof Map)
{
factory = _writerMap.get(Map.class);
_writerMap.put(value.getClass(), factory);
writer = factory.newInstance(this);
if(writer.isCacheable())
{
_cachedWriters.put(clazz, writer);
}
writer.setValue(value);
}
else if(value.getClass().isArray())
{
if(RestrictedType.class.isAssignableFrom(value.getClass().getComponentType()))
{
RestrictedType[] restrictedTypes = (RestrictedType[]) value;
Object[] newVals = (Object[]) Array.newInstance(restrictedTypes[0].getValue().getClass(),
restrictedTypes.length);
for(int i = 0; i < restrictedTypes.length; i++)
{
newVals[i] = restrictedTypes[i].getValue();
}
return (ValueWriter<V>) getValueWriter(newVals);
}
// TODO primitive array types
factory = _writerMap.get(List.class);
writer = factory.newInstance(this);
writer.setValue(Arrays.asList((Object[])value));
}
else
{
return null;
}
}
else
{
writer = factory.newInstance(this);
if(writer.isCacheable())
{
_cachedWriters.put(clazz, writer);
}
writer.setValue(value);
}
}
else
{
writer.setValue(value);
}
return writer;
}