/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.beans.reflect;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Reflection transcoder for an object that implements a {@link Collection}.
*
* @author Middleware Services
*/
public abstract class AbstractCollectionReflectionTranscoder implements ReflectionTranscoder
{
/** Type that is a collection. */
private final Class<?> type;
/** Used for collections that do not contain arrays. */
private final SingleValueReflectionTranscoder<?> singleValueTranscoder;
/** Used for collections that contain arrays. */
private final ArrayReflectionTranscoder arrayTranscoder;
/**
* Creates a new abstract collection reflection transcoder.
*
* @param c class that is a collection
* @param transcoder to operate on elements of the collection
*/
public AbstractCollectionReflectionTranscoder(final Class<?> c, final SingleValueReflectionTranscoder<?> transcoder)
{
type = c;
singleValueTranscoder = transcoder;
arrayTranscoder = null;
}
/**
* Creates a new abstract collection reflection transcoder.
*
* @param c class that is a collection
* @param transcoder to operate on elements of the collection
*/
public AbstractCollectionReflectionTranscoder(final Class<?> c, final ArrayReflectionTranscoder transcoder)
{
type = c;
singleValueTranscoder = null;
arrayTranscoder = transcoder;
}
@Override
public Object decodeStringValues(final Collection<String> values)
{
final Collection<Object> decoded = createCollection(Object.class);
if (arrayTranscoder != null) {
decoded.add(arrayTranscoder.decodeStringValues(values));
} else {
for (String value : values) {
final List<String> l = new ArrayList<>(1);
l.add(value);
decoded.add(singleValueTranscoder.decodeStringValues(l));
}
}
return decoded;
}
@Override
public Object decodeBinaryValues(final Collection<byte[]> values)
{
final Collection<Object> decoded = createCollection(Object.class);
if (arrayTranscoder != null) {
decoded.add(arrayTranscoder.decodeBinaryValues(values));
} else {
for (byte[] value : values) {
final List<byte[]> l = new ArrayList<>(1);
l.add(value);
decoded.add(singleValueTranscoder.decodeBinaryValues(l));
}
}
return decoded;
}
@Override
public Collection<String> encodeStringValues(final Object values)
{
final Collection<String> encoded = createCollection(String.class);
if (values != null) {
for (Object o : (Collection<?>) values) {
if (arrayTranscoder != null) {
encoded.addAll(arrayTranscoder.encodeStringValues(o));
} else {
encoded.addAll(singleValueTranscoder.encodeStringValues(o));
}
}
}
return encoded;
}
@Override
public Collection<byte[]> encodeBinaryValues(final Object values)
{
final Collection<byte[]> encoded = createCollection(byte[].class);
if (values != null) {
for (Object o : (Collection<?>) values) {
if (arrayTranscoder != null) {
encoded.addAll(arrayTranscoder.encodeBinaryValues(o));
} else {
encoded.addAll(singleValueTranscoder.encodeBinaryValues(o));
}
}
}
return encoded;
}
/**
* Returns a collection implementation of the correct type for this transcoder.
*
* @param <T> type of collection
* @param clazz type of collection
*
* @return collection implementation
*/
protected abstract <T> Collection<T> createCollection(Class<T> clazz);
@Override
public Class<?> getType()
{
return type;
}
@Override
public boolean supports(final Class<?> t)
{
return getType().isAssignableFrom(t);
}
@Override
public String toString()
{
return
String.format(
"[%s@%d::type=%s, singleValueTranscoder=%s, arrayTranscoder=%s]",
getClass().getName(),
hashCode(),
type,
singleValueTranscoder,
arrayTranscoder);
}
}