package org.gbif.occurrence.common.json;
import org.gbif.api.model.common.MediaObject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;
import com.google.common.base.Throwables;
import com.google.common.collect.Sets;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.type.CollectionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility class to serialize and deserialize MediaObject instances from/to JSON.
*/
public class MediaSerDeserUtils {
private static final Logger LOG = LoggerFactory.getLogger(MediaSerDeserUtils.class);
private static final String SER_ERROR_MSG = "Unable to serialize media objects to JSON";
private static final String DESER_ERROR_MSG = "Unable to deserialize String into media objects";
private static final ObjectMapper MAPPER = new ObjectMapper();
static {
// Don't change this section, methods used here guarantee backwards compatibility with Jackson 1.8.8
MAPPER.configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
MAPPER.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
MAPPER.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);
}
private static final CollectionType LIST_MEDIA_TYPE = MAPPER.getTypeFactory().constructCollectionType(List.class,
MediaObject.class);
private MediaSerDeserUtils() {
// private constructor
}
/**
* Converts the list of media objects into a JSON string.
*/
public static String toJson(List<MediaObject> media) {
try {
if (media != null && !media.isEmpty()) {
return MAPPER.writeValueAsString(media);
}
} catch (IOException e) {
logAndRethrow(SER_ERROR_MSG, e);
}
return null;
}
/**
* Converts a Json string into a list of media objects.
*/
public static List<MediaObject> fromJson(String mediaJson) {
try {
return MAPPER.readValue(mediaJson, LIST_MEDIA_TYPE);
} catch (IOException e) {
logAndRethrow(DESER_ERROR_MSG, e);
}
return null;
}
/**
* Converts a byte[] into String and extracts the media types from JSON representation of it.
*/
public static Set<String> extractMediaTypes(byte[] input) {
return extractMediaTypes(new String(input, StandardCharsets.UTF_8));
}
/**
* Extracts the media types of JSON String.
*/
public static Set<String> extractMediaTypes(String jsonMedias) {
List<MediaObject> medias = MediaSerDeserUtils.fromJson(jsonMedias);
Set<String> mediaTypes = Sets.newHashSet();
if (medias != null && !medias.isEmpty()) {
for (MediaObject mediaObject : medias) {
if (mediaObject.getType() != null) {
mediaTypes.add(mediaObject.getType().name().toUpperCase());
}
}
}
return mediaTypes;
}
/**
* Logs an error and re-throws the exception.
*/
private static void logAndRethrow(String message, Throwable throwable) {
LOG.error(message, throwable);
Throwables.propagate(throwable);
}
}