diff --git a/extensions/serializer/src/main/java/org/apache/abdera/ext/serializer/BaseSerializer.java b/extensions/serializer/src/main/java/org/apache/abdera/ext/serializer/BaseSerializer.java index 22503035..12188b2e 100644 --- a/extensions/serializer/src/main/java/org/apache/abdera/ext/serializer/BaseSerializer.java +++ b/extensions/serializer/src/main/java/org/apache/abdera/ext/serializer/BaseSerializer.java @@ -86,26 +86,27 @@ protected void writeExtensions(Object source, ObjectContext objectContext, SerializationContext context, Conventions conventions) { - AccessibleObject[] accessors = objectContext.getAccessors(Extension.class, conventions); + final AccessibleObject[] accessors = objectContext.getAccessors(Extension.class, conventions); for (AccessibleObject accessor : accessors) { - Object value = eval(accessor, source); - ObjectContext valueContext = new ObjectContext(value, source, accessor); - Extension extension = valueContext.getAnnotation(Extension.class); - boolean simple = extension != null ? extension.simple() : false; - Serializer ser = context.getSerializer(valueContext); - if (ser == null) { + final Object value = eval(accessor, source); + final Object[] values = toArray(value); + for (Object val : values) { + final ObjectContext valueContext = new ObjectContext(val, source, accessor); + final Extension extension = valueContext.getAnnotation(Extension.class); + final boolean simple = extension != null ? extension.simple() : false; + Serializer ser; if (simple) { - QName qname = getQName(accessor); + final QName qname = getQName(accessor); ser = new SimpleElementSerializer(qname); } else { ser = context.getSerializer(valueContext); - if (ser == null) { - QName qname = getQName(accessor); - ser = new ExtensionSerializer(qname); - } } + if (ser == null) { + final QName qname = getQName(accessor); + ser = new ExtensionSerializer(qname); + } + ser.serialize(val, valueContext, context); } - ser.serialize(value, valueContext, context); } } @@ -249,7 +250,7 @@ protected static QName getQName(AccessibleObject accessor) { protected static QName getQName(Extension extension) { QName qname = null; if (extension != null) { - if (isUndefined(extension.prefix()) && isUndefined(extension.ns()) && isUndefined(extension.name())) { + if (!isUndefined(extension.prefix()) && !isUndefined(extension.ns()) && !isUndefined(extension.name())) { qname = new QName(extension.ns(), extension.name(), extension.prefix()); } else if (isUndefined(extension.prefix()) && !isUndefined(extension.ns()) && !isUndefined(extension.name())) { diff --git a/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/AbderaTestHelper.java b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/AbderaTestHelper.java new file mode 100644 index 00000000..6ca67ab3 --- /dev/null +++ b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/AbderaTestHelper.java @@ -0,0 +1,18 @@ +package org.apache.abdera.test.ext.serializer; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +import org.apache.abdera.Abdera; +import org.apache.abdera.model.Document; +import org.apache.abdera.model.Element; + +public final class AbderaTestHelper { + + public static final T deserialize(final ByteArrayOutputStream serialized) { + final ByteArrayInputStream in = new ByteArrayInputStream(serialized.toByteArray()); + final Document doc = Abdera.getInstance().getParser().parse(in); + return doc.getRoot(); + } + +} diff --git a/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/ExtensionAnnotationTest.java b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/ExtensionAnnotationTest.java new file mode 100644 index 00000000..575faf85 --- /dev/null +++ b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/ExtensionAnnotationTest.java @@ -0,0 +1,312 @@ +package org.apache.abdera.test.ext.serializer; + +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.List; +import javax.xml.namespace.QName; + +import org.apache.abdera.Abdera; +import org.apache.abdera.ext.serializer.ConventionSerializationContext; +import org.apache.abdera.ext.serializer.annotation.Entry; +import org.apache.abdera.ext.serializer.annotation.Extension; +import org.apache.abdera.model.Element; +import org.apache.abdera.model.ExtensibleElement; +import org.apache.abdera.writer.StreamWriter; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public final class ExtensionAnnotationTest { + + private static final String PREFIX = "foo"; + + private static final String NS = "http://example.org/foo"; + + private static final String EXT_NAME = "ext"; + + private static final QName EXT_QNAME = new QName(NS, EXT_NAME, PREFIX); + + /** + * Expected serialized result: + * + * + * + * foo + * + * + */ + @Entry + public static final class EntryWithSimpleExtension { + + private final String value; + + public EntryWithSimpleExtension(final String value) { + this.value = value; + } + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME, simple = true) + public String getSimpleExtension() { + return value; + } + + } + + /** + * Expected serialized result: + * + * + * + * + * foo + * + * + * + */ + @Entry + public static final class EntryWithExtensionNestingSimpleExtension { + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME) + public ExtensionNestingSimpleExtension getExtension() { + return new ExtensionNestingSimpleExtension("foo"); + } + + } + + public static final class ExtensionNestingSimpleExtension { + + private final String value; + + public ExtensionNestingSimpleExtension(final String value) { + this.value = value; + } + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME, simple = true) + public String getNestedExtension() { + return value; + } + + } + + /** + * Expected serialized result: + * + * + * + * + * + * foo + * + * + * + * + */ + @Entry + public static final class EntryWithExtensionNestingExtensionNestingSimpleExtension { + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME) + public ExtensionNestingExtensionNestingSimpleExtension getExtension() { + return new ExtensionNestingExtensionNestingSimpleExtension("foo"); + } + + } + + public static final class ExtensionNestingExtensionNestingSimpleExtension { + + private final String value; + + public ExtensionNestingExtensionNestingSimpleExtension(final String value) { + this.value = value; + } + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME) + public ExtensionNestingSimpleExtension getExtensionNestingSimpleExtension() { + return new ExtensionNestingSimpleExtension(value); + } + + } + + /** + * Expected serialized result: + * + * + * + * foo + * + * + * bar + * + * + * baz + * + * + */ + @Entry + public static final class EntryWithListOfSimpleExtensions { + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME, simple = true) + public List getSimpleExtensions() { + return Arrays.asList("foo", "bar", "baz"); + } + + } + + /** + * Expected serialized result: + * + * + * + * + * foo + * + * + * + * + * bar + * + * + * + * + * baz + * + * + * + */ + @Entry + public static final class EntryWithListOfExtensionsNestingSimpleExtension { + + @Extension(prefix = PREFIX, ns = NS, name = EXT_NAME) + public List getComplexExtensionExtensions() { + return Arrays.asList(new ExtensionNestingSimpleExtension("foo"), + new ExtensionNestingSimpleExtension("bar"), + new ExtensionNestingSimpleExtension("baz")); + } + + } + + private final Abdera abdera = Abdera.getInstance(); + + @Test + public void shouldGenerateSimpleExtension() { + // given + final EntryWithSimpleExtension source = new EntryWithSimpleExtension("foo"); + + // when + final StreamWriter streamWriter = abdera.newStreamWriter(); + final ByteArrayOutputStream serialized = new ByteArrayOutputStream(); + streamWriter.setOutputStream(serialized).setAutoIndent(true); + final ConventionSerializationContext context = new ConventionSerializationContext(streamWriter); + streamWriter.startDocument(); + context.serialize(source); + streamWriter.endDocument(); + + // then + final org.apache.abdera.model.Entry entry = AbderaTestHelper.deserialize(serialized); + final ExtensibleElement extension = entry.getExtension(EXT_QNAME); + assertNotNull(extension); + assertEquals("foo", extension.getText().trim()); + } + + @Test + public void shouldGenerateExtensionNestingSimpleExtension() { + // given + final EntryWithExtensionNestingSimpleExtension source = new EntryWithExtensionNestingSimpleExtension(); + + // when + final StreamWriter streamWriter = abdera.newStreamWriter(); + final ByteArrayOutputStream serialized = new ByteArrayOutputStream(); + streamWriter.setOutputStream(serialized).setAutoIndent(true); + final ConventionSerializationContext context = new ConventionSerializationContext(streamWriter); + streamWriter.startDocument(); + context.serialize(source); + streamWriter.endDocument(); + + // then + final org.apache.abdera.model.Entry entry = AbderaTestHelper.deserialize(serialized); + final ExtensibleElement extension = entry.getExtension(EXT_QNAME); + assertNotNull(extension); + final Element simple = extension.getExtension(EXT_QNAME); + assertNotNull(simple); + assertEquals("foo", simple.getText().trim()); + } + + @Test + public void shouldGenerateExtensionNestingExtensionNestingSimpleExtension() { + // given + final EntryWithExtensionNestingExtensionNestingSimpleExtension source = + new EntryWithExtensionNestingExtensionNestingSimpleExtension(); + + // when + final StreamWriter streamWriter = abdera.newStreamWriter(); + final ByteArrayOutputStream serialized = new ByteArrayOutputStream(); + streamWriter.setOutputStream(serialized).setAutoIndent(true); + final ConventionSerializationContext context = new ConventionSerializationContext(streamWriter); + streamWriter.startDocument(); + context.serialize(source); + streamWriter.endDocument(); + + // then + final org.apache.abdera.model.Entry entry = AbderaTestHelper.deserialize(serialized); + final ExtensibleElement extension = entry.getExtension(EXT_QNAME); + assertNotNull(extension); + final ExtensibleElement nested = extension.getExtension(EXT_QNAME); + assertNotNull(nested); + final Element simple = nested.getExtension(EXT_QNAME); + assertNotNull(simple); + assertEquals("foo", simple.getText().trim()); + } + + @Test + public void shouldGenerateSeveralSimpleExtensions() { + // given + final EntryWithListOfSimpleExtensions source = new EntryWithListOfSimpleExtensions(); + + // when + final StreamWriter streamWriter = abdera.newStreamWriter(); + final ByteArrayOutputStream serialized = new ByteArrayOutputStream(); + streamWriter.setOutputStream(serialized).setAutoIndent(true); + final ConventionSerializationContext context = new ConventionSerializationContext(streamWriter); + streamWriter.startDocument(); + context.serialize(source); + streamWriter.endDocument(); + + // then + final org.apache.abdera.model.Entry entry = AbderaTestHelper.deserialize(serialized); + final List extensions = entry.getExtensions(EXT_QNAME); + assertNotNull(extensions); + assertEquals(3, extensions.size()); + assertEquals("foo", extensions.get(0).getText().trim()); + assertEquals("bar", extensions.get(1).getText().trim()); + assertEquals("baz", extensions.get(2).getText().trim()); + } + + @Test + public void shouldGenerateSeveralExtensionsNestingSimpleExtension() { + // given + final EntryWithListOfExtensionsNestingSimpleExtension source = new EntryWithListOfExtensionsNestingSimpleExtension(); + + // when + final StreamWriter streamWriter = abdera.newStreamWriter(); + final ByteArrayOutputStream serialized = new ByteArrayOutputStream(); + streamWriter.setOutputStream(serialized).setAutoIndent(true); + final ConventionSerializationContext context = new ConventionSerializationContext(streamWriter); + streamWriter.startDocument(); + context.serialize(source); + streamWriter.endDocument(); + + // then + final org.apache.abdera.model.Entry entry = AbderaTestHelper.deserialize(serialized); + final List extensions = entry.getExtensions(EXT_QNAME); + assertNotNull(extensions); + assertEquals(3, extensions.size()); + final Element first = extensions.get(0).getExtension(EXT_QNAME); + assertNotNull(first); + assertEquals("foo", first.getText().trim()); + final Element second = extensions.get(1).getExtension(EXT_QNAME); + assertNotNull(second); + assertEquals("bar", second.getText().trim()); + final Element third = extensions.get(2).getExtension(EXT_QNAME); + assertNotNull(third); + assertEquals("baz", third.getText().trim()); + } +} diff --git a/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/TestSuite.java b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/TestSuite.java index c6e221b6..3d1e902c 100644 --- a/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/TestSuite.java +++ b/extensions/serializer/src/test/java/org/apache/abdera/test/ext/serializer/TestSuite.java @@ -25,5 +25,6 @@ public static void main(String[] args) { JUnitCore runner = new JUnitCore(); runner.addListener(new TextListener(System.out)); runner.run(SerializerTest.class); + runner.run(ExtensionAnnotationTest.class); } }