package serializers.json; import static argo.jdom.JsonNodeFactories.aJsonArray; import static argo.jdom.JsonNodeFactories.aJsonNull; import static argo.jdom.JsonNodeFactories.aJsonNumber; import static argo.jdom.JsonNodeFactories.aJsonObject; import static argo.jdom.JsonNodeFactories.aJsonString; import static argo.jdom.JsonNodeType.NULL; import static java.lang.Integer.parseInt; import static java.lang.Long.parseLong; import static java.util.Arrays.asList; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import serializers.*; import argo.format.CompactJsonFormatter; import argo.format.JsonFormatter; import argo.jdom.JdomParser; import argo.jdom.JsonField; import argo.jdom.JsonNode; import argo.jdom.JsonStringNode; import data.media.Image; import data.media.Media; import data.media.MediaContent; /** * Driver that uses Argo [http://argo.sourceforge.net], with manual tree processing. * * Implementation provided by Mark Slater, admin and committer on the Argo project. */ public class JsonArgoTree { public static void register(TestGroups groups) { groups.media.add(JavaBuiltIn.mediaTransformer, new ManualTreeSerializer("json/argo/manual-tree"), new SerFeatures( SerFormat.JSON, SerGraph.FLAT_TREE, SerClass.MANUAL_OPT, "" ) ); } static class ManualTreeSerializer extends Serializer<MediaContent> { private final String name; public ManualTreeSerializer(String name) { this.name = name; } public String getName() { return name; } public MediaContent deserialize(byte[] array) throws Exception { String mediaContentJsonInput = new String(array, "UTF-8"); return readMediaContent(mediaContentJsonInput); } public byte[] serialize(MediaContent mediaContent) throws IOException { return writeMediaContent(mediaContent).getBytes("UTF-8"); } private static final JsonFormatter JSON_FORMATTER = new CompactJsonFormatter(); private static final JdomParser JDOM_PARSER = new JdomParser(); private static final JsonStringNode MEDIA_KEY = aJsonString("media"); private static final JsonStringNode IMAGES_KEY = aJsonString("images"); private static final JsonStringNode URI_KEY = aJsonString("uri"); private static final JsonStringNode WIDTH_KEY = aJsonString("width"); private static final JsonStringNode HEIGHT_KEY = aJsonString("height"); private static final JsonStringNode SIZE_KEY = aJsonString("size"); private static final JsonStringNode COPYRIGHT_KEY = aJsonString("copyright"); private static final JsonStringNode DURATION_KEY = aJsonString("duration"); private static final JsonStringNode TITLE_KEY = aJsonString("title"); private static final JsonStringNode PLAYER_KEY = aJsonString("player"); private static final JsonStringNode FORMAT_KEY = aJsonString("format"); private static final JsonStringNode PERSONS_KEY = aJsonString("persons"); private static final JsonStringNode BIT_RATE_KEY = aJsonString("bitrate"); private String writeMediaContent(MediaContent mediaContent) { return JSON_FORMATTER.format( aJsonObject( new JsonField(MEDIA_KEY, createMediaObject(mediaContent.media)), new JsonField(IMAGES_KEY, createImagesArray(mediaContent.images)) )); } private JsonNode createImagesArray(List<Image> images) { List<JsonNode> jsonNodes = new ArrayList<JsonNode>(images.size() * 2); for (Image image : images) { jsonNodes.add(aJsonObject( new JsonField(HEIGHT_KEY, aJsonNumber(String.valueOf(image.height))), new JsonField(SIZE_KEY, aJsonString(image.size.name())), new JsonField(TITLE_KEY, aJsonString(image.title)), new JsonField(URI_KEY, aJsonString(image.uri)), new JsonField(WIDTH_KEY, aJsonNumber(String.valueOf(image.width))) )); } return aJsonArray(jsonNodes); } private JsonNode createMediaObject(Media media) { List<JsonNode> persons = new ArrayList<JsonNode>(media.persons.size() * 2); for (String person : media.persons) { persons.add(aJsonString(person)); } JsonNode value = media.copyright == null ? aJsonNull() : aJsonString(media.copyright); List<JsonField> jsonFields = new ArrayList<JsonField>(asList( new JsonField(URI_KEY, aJsonString(media.uri)), new JsonField(TITLE_KEY, aJsonString(media.title)), new JsonField(WIDTH_KEY, aJsonNumber(String.valueOf(media.width))), new JsonField(HEIGHT_KEY, aJsonNumber(String.valueOf(media.height))), new JsonField(FORMAT_KEY, aJsonString(media.format)), new JsonField(DURATION_KEY, aJsonNumber(String.valueOf(media.duration))), new JsonField(SIZE_KEY, aJsonNumber(String.valueOf(media.size))), new JsonField(PLAYER_KEY, aJsonString(media.player.name())), new JsonField(COPYRIGHT_KEY, value), new JsonField(PERSONS_KEY, aJsonArray(persons)) )); if (media.hasBitrate) { jsonFields.add(new JsonField(BIT_RATE_KEY, aJsonNumber(String.valueOf(media.bitrate)))); } return aJsonObject(jsonFields); } MediaContent readMediaContent(String mediaContentJsonInput) throws Exception { MediaContent mediaContent = new MediaContent(); Map<JsonStringNode, JsonNode> fields = JDOM_PARSER.parse(mediaContentJsonInput).getFields(); mediaContent.media = readMedia(fields.get(MEDIA_KEY)); mediaContent.images = readImages(fields.get(IMAGES_KEY)); return mediaContent; } private Media readMedia(JsonNode jsonNode) { Media media = new Media(); Map<JsonStringNode, JsonNode> fields = jsonNode.getFields(); media.copyright = getValueOrNull(fields.get(COPYRIGHT_KEY)); media.duration = parseLong(fields.get(DURATION_KEY).getText()); media.format = getValueOrNull(fields.get(FORMAT_KEY)); media.player = Media.Player.valueOf(fields.get(PLAYER_KEY).getText()); media.title = getValueOrNull(fields.get(TITLE_KEY)); media.uri = getValueOrNull(fields.get(URI_KEY)); media.size = parseLong(fields.get(SIZE_KEY).getText()); media.height = parseInt(fields.get(HEIGHT_KEY).getText()); media.width = parseInt(fields.get(WIDTH_KEY).getText()); List<JsonNode> personNodesElements = fields.get(PERSONS_KEY).getElements(); List<String> persons = new ArrayList<String>(personNodesElements.size() * 2); for (JsonNode personNode : personNodesElements) { persons.add(personNode.getText()); } media.persons = persons; JsonNode bitRate = fields.get(BIT_RATE_KEY); if (bitRate != null && bitRate.getType() != NULL) { media.bitrate = parseInt(bitRate.getText()); media.hasBitrate = true; } return media; } private static String getValueOrNull(JsonNode textNode) { return textNode.getType() == NULL ? null : textNode.getText(); } private List<Image> readImages(JsonNode node) { List<JsonNode> elements = node.getElements(); List<Image> images = new ArrayList<Image>(elements.size() * 2); for (JsonNode jsonNode : elements) { Map<JsonStringNode, JsonNode> fields = jsonNode.getFields(); images.add(new Image( fields.get(URI_KEY).getText(), fields.get(TITLE_KEY).getText(), parseInt(fields.get(WIDTH_KEY).getText()), parseInt(fields.get(HEIGHT_KEY).getText()), Image.Size.valueOf(fields.get(SIZE_KEY).getText()) )); } return images; } } }