package com.owlike.genson.convert;
import java.lang.reflect.Type;
import java.util.List;
import com.owlike.genson.BeanView;
import com.owlike.genson.Context;
import com.owlike.genson.Converter;
import com.owlike.genson.Genson;
import com.owlike.genson.Wrapper;
import com.owlike.genson.annotation.HandleBeanView;
import com.owlike.genson.reflect.BeanDescriptor;
import com.owlike.genson.reflect.BeanViewDescriptorProvider;
import com.owlike.genson.reflect.TypeUtil;
import com.owlike.genson.stream.ObjectReader;
import com.owlike.genson.stream.ObjectWriter;
/**
* Converter responsible of applying the BeanView mechanism.
*
* @param <T> type of objects this BeanViewConverter can handle.
* @author eugen
* @see com.owlike.genson.reflect.BeanViewDescriptorProvider BeanViewDescriptorProvider
* @see com.owlike.genson.BeanView BeanView
*/
public class BeanViewConverter
<T
> extends Wrapper
<Converter
<T
>> implements Converter
<T
> {
public static class BeanViewConverterFactory
extends ChainedFactory
{
private final BeanViewDescriptorProvider provider
;
public BeanViewConverterFactory
(BeanViewDescriptorProvider provider
) {
this.
provider = provider
;
}
@
1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"rawtypes",
"unchecked"})
@
1.5.0/docs/api/java/lang/Override.html">Override
protected Converter
<?> create
(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, Genson genson, Converter
<?> nextConverter
) {
if (!Wrapper.
toAnnotatedElement(nextConverter
).
isAnnotationPresent(
HandleBeanView.
class))
// TODO as we link an instance to a type, we may optimize things, but for the moment it is okay
// lets see if this feature is used
return new BeanViewConverter
(type, provider, nextConverter
);
return nextConverter
;
}
}
private final BeanViewDescriptorProvider provider
;
private final 1.5.0/docs/api/java/lang/reflect/Type.html">Type type
;
public BeanViewConverter
(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, BeanViewDescriptorProvider provider, Converter
<T
> next
) {
super(next
);
this.
provider = provider
;
this.
type = type
;
}
@
1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
protected Class
<? extends BeanView
<T
>> findViewFor
(1.5.0/docs/api/java/lang/reflect/Type.html">Type type,
List
<Class
<? extends BeanView
<?>>> views
) {
for (Class
<? extends BeanView
<?>> v : views
) {
1.5.0/docs/api/java/lang/reflect/Type.html">Type searchedType = TypeUtil.
lookupGenericType(BeanView.
class, v
);
searchedType = TypeUtil.
expandType(searchedType, v
);
searchedType = TypeUtil.
typeOf(0, searchedType
);
if (TypeUtil.
match(type, searchedType,
false)) {
return (Class
<? extends BeanView
<T
>>) v
;
}
}
return null;
}
public void serialize
(T obj, ObjectWriter writer,
5+0%2Fdocs%2Fapi+Context">Context ctx
) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
boolean handled =
false;
List
<Class
<? extends BeanView
<?>>> views = ctx.
views();
if (views
!=
null && views.
size() > 0
) {
Class
<? extends BeanView
<T
>> viewClass = findViewFor
(type, views
);
if (viewClass
!=
null) {
1.5.0/docs/api/java/lang/reflect/Type.html">Type viewForType = TypeUtil.
expandType(BeanView.
class.
getTypeParameters()[0
],
viewClass
);
@
1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
Class
<T
> viewForClass =
(Class
<T
>) TypeUtil.
getRawClass(viewForType
);
BeanDescriptor
<T
> descriptor = provider
.
provide(viewForClass, viewClass, ctx.
genson);
descriptor.
serialize(obj, writer, ctx
);
handled =
true;
}
}
if (!handled
) wrapped.
serialize(obj, writer, ctx
);
}
public T deserialize
(ObjectReader reader,
5+0%2Fdocs%2Fapi+Context">Context ctx
) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
if (ctx.
hasViews()) {
Class
<? extends BeanView
<T
>> viewClass = findViewFor
(type, ctx.
views());
if (viewClass
!=
null) {
1.5.0/docs/api/java/lang/reflect/Type.html">Type viewForType = TypeUtil.
expandType(BeanView.
class.
getTypeParameters()[0
],
viewClass
);
@
1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
Class
<T
> viewForClass =
(Class
<T
>) TypeUtil.
getRawClass(viewForType
);
BeanDescriptor
<T
> descriptor = provider
.
provide(viewForClass, viewClass, ctx.
genson);
return descriptor.
deserialize(reader, ctx
);
}
}
return wrapped.
deserialize(reader, ctx
);
}
}