package serializers.xml;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import serializers.*;
import javolution.text.CharArray;
import javolution.xml.XMLBinding;
import javolution.xml.XMLFormat;
import javolution.xml.XMLObjectReader;
import javolution.xml.XMLObjectWriter;
import javolution.xml.stream.XMLStreamException;
import data.media.*;
import static data.media.FieldMapping.*;
public class XmlJavolution
{
public final static String ROOT_ELEMENT = "mc";
public static void register(TestGroups groups)
{
groups.media.add(JavaBuiltIn.mediaTransformer, new JavolutionSerializer<MediaContent>(MediaBinding, MediaContent.class),
new SerFeatures(
SerFormat.XML,
SerGraph.FLAT_TREE,
SerClass.MANUAL_OPT,
""
)
);
// commented-out by dyu: use the non-abbreviated version
//groups.media.add(JavaBuiltIn.MediaTransformer, new JavolutionSerializer<MediaContent>("-abbrev", MediaBindingAbbreviated, MediaContent.class));
}
private static final class JavolutionSerializer<T> extends Serializer<T>
{
private final XMLBinding binding;
private final Class<T> clazz;
public JavolutionSerializer(XMLBinding binding, Class<T> clazz)
{
this.binding = binding;
this.clazz = clazz;
}
@Override
public String getName() { return "xml/javolution/manual"; }
@Override
public T deserialize(byte[] array) throws Exception
{
XMLObjectReader reader = XMLObjectReader.newInstance(new ByteArrayInputStream(array)).setBinding(binding);
try {
return reader.read(ROOT_ELEMENT, clazz);
} finally {
reader.close();
}
}
@Override
public byte[] serialize(T content) throws Exception
{
ByteArrayOutputStream baos = outputStream(content);
XMLObjectWriter writer = XMLObjectWriter.newInstance(baos).setBinding(binding);
writer.write(content, ROOT_ELEMENT, clazz);
writer.close();
baos.close();
return baos.toByteArray();
}
}
@SuppressWarnings("serial")
private static final XMLBinding MediaBinding = new XMLBinding()
{
{
setAlias(MediaContent.class, ROOT_ELEMENT);
setAlias(Image.class, FULL_FIELD_NAME_IMAGES);
setAlias(Media.class, FULL_FIELD_NAME_MEDIA);
setAlias(String.class, "str");
}
private <G,S> XMLFormat<G> toGeneric(XMLFormat<S> specific)
{
@SuppressWarnings("unchecked")
XMLFormat<G> generic = (XMLFormat<G>) specific;
return generic;
}
// silly javolution does not use generics properly....
@SuppressWarnings("unchecked")
@Override
public XMLFormat getFormat(Class cls) throws XMLStreamException
{
if (MediaContent.class.equals(cls))
return toGeneric(MediaContentConverter);
if (Media.class.equals(cls))
return toGeneric(MediaConverter);
if (Image.class.equals(cls))
return toGeneric(ImageConverter);
return super.getFormat(cls);
}
private final XMLFormat<Image> ImageConverter = new XMLFormat<Image>(null)
{
@Override
public void write(Image image, XMLFormat.OutputElement xml) throws XMLStreamException
{
xml.setAttribute(FULL_FIELD_NAME_URI, image.uri);
xml.setAttribute(FULL_FIELD_NAME_TITLE, image.title);
xml.setAttribute(FULL_FIELD_NAME_WIDTH, image.width);
xml.setAttribute(FULL_FIELD_NAME_HEIGHT, image.height);
xml.setAttribute(FULL_FIELD_NAME_SIZE, image.size.ordinal());
}
@Override
public void read(XMLFormat.InputElement xml, Image image) throws XMLStreamException
{
image.uri = xml.getAttribute(FULL_FIELD_NAME_URI).toString();
image.title = xml.getAttribute(FULL_FIELD_NAME_TITLE, (String) null);
image.width = xml.getAttribute(FULL_FIELD_NAME_WIDTH).toInt();
image.height = xml.getAttribute(FULL_FIELD_NAME_HEIGHT).toInt();
image.size = Image.Size.values()[xml.getAttribute(FULL_FIELD_NAME_SIZE, 0)];
}
};
private final XMLFormat<Media> MediaConverter = new XMLFormat<Media>(null)
{
@Override
public void write(Media media, XMLFormat.OutputElement xml) throws XMLStreamException
{
xml.setAttribute(FULL_FIELD_NAME_URI, media.uri);
xml.setAttribute(FULL_FIELD_NAME_TITLE, media.title);
xml.setAttribute(FULL_FIELD_NAME_WIDTH, media.width);
xml.setAttribute(FULL_FIELD_NAME_HEIGHT, media.height);
xml.setAttribute(FULL_FIELD_NAME_FORMAT, media.format);
xml.setAttribute(FULL_FIELD_NAME_DURATION, media.duration);
xml.setAttribute(FULL_FIELD_NAME_SIZE, media.size);
if (media.hasBitrate) xml.setAttribute(FULL_FIELD_NAME_BITRATE, media.bitrate);
xml.setAttribute(FULL_FIELD_NAME_PLAYER, media.player.ordinal());
xml.setAttribute(FULL_FIELD_NAME_COPYRIGHT, media.copyright);
for (String p : media.persons) {
xml.add(p);
}
}
@Override
public void read(XMLFormat.InputElement xml, Media media) throws XMLStreamException
{
media.uri = xml.getAttribute(FULL_FIELD_NAME_URI).toString();
media.title = xml.getAttribute(FULL_FIELD_NAME_TITLE, (String) null);
media.width = xml.getAttribute(FULL_FIELD_NAME_WIDTH).toInt();
media.height = xml.getAttribute(FULL_FIELD_NAME_HEIGHT).toInt();
media.format = xml.getAttribute(FULL_FIELD_NAME_FORMAT).toString();
media.duration = xml.getAttribute(FULL_FIELD_NAME_DURATION).toLong();
media.size = xml.getAttribute(FULL_FIELD_NAME_SIZE).toLong();
CharArray caBitrate = xml.getAttribute(FULL_FIELD_NAME_BITRATE);
media.hasBitrate = (caBitrate != null);
if (caBitrate != null) media.bitrate = caBitrate.toInt();
media.player = Media.Player.values()[xml.getAttribute(FULL_FIELD_NAME_PLAYER, 0)];
media.copyright = xml.getAttribute(FULL_FIELD_NAME_COPYRIGHT, (String) null);
List<String> persons = new ArrayList<String>();
while (xml.hasNext()) {
persons.add((String)xml.getNext());
}
media.persons = persons;
}
};
private final XMLFormat<MediaContent> MediaContentConverter = new XMLFormat<MediaContent>(null)
{
@Override
public void write(MediaContent content, XMLFormat.OutputElement xml) throws XMLStreamException
{
xml.add(content.media);
for (Image image : content.images) {
xml.add(image);
}
}
@Override
public MediaContent newInstance(java.lang.Class<MediaContent> cls, XMLFormat.InputElement xml) throws XMLStreamException
{
Media media = (Media) xml.getNext();
List<Image> images = new ArrayList<Image>();
while (xml.hasNext()) {
images.add((Image) xml.getNext());
}
return new MediaContent(media, images);
}
@Override
public void read(javolution.xml.XMLFormat.InputElement arg0, MediaContent arg1)
{
// Do nothing; Object loaded by newInstance;
}
};
};
}