/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.jaxrs.provider.atom;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.lang.annotation.Annotation;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AtomPojoProviderTest extends Assert {
private ClassPathXmlApplicationContext ctx;
@Before
public void setUp() {
ctx =
new ClassPathXmlApplicationContext(
new String[] {"/org/apache/cxf/jaxrs/provider/atom/servers.xml"});
}
@Test
public void testWriteFeedWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom");
assertNotNull(provider);
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Books books = new Books();
List<Book> bs = new ArrayList<>();
bs.add(new Book("a"));
bs.add(new Book("b"));
books.setBooks(bs);
provider.writeTo(books, Books.class, Books.class, new Annotation[]{},
MediaType.valueOf("application/atom+xml"), null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Feed feed = new AtomFeedProvider().readFrom(Feed.class, null, null, null, null, bis);
assertEquals("Books", feed.getTitle());
List<Entry> entries = feed.getEntries();
assertEquals(2, entries.size());
verifyEntry(getEntry(entries, "a"), "a");
verifyEntry(getEntry(entries, "b"), "b");
}
@Test
public void testWriteFeedWithBuildersNoJaxb() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atomNoJaxb");
assertNotNull(provider);
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Books books = new Books();
List<Book> bs = new ArrayList<>();
bs.add(new Book("a"));
bs.add(new Book("b"));
books.setBooks(bs);
provider.writeTo(books, Books.class, Books.class, new Annotation[]{},
MediaType.valueOf("application/atom+xml"), null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Feed feed = new AtomFeedProvider().readFrom(Feed.class, null, null, null, null, bis);
assertEquals("Books", feed.getTitle());
List<Entry> entries = feed.getEntries();
assertEquals(2, entries.size());
Entry entryA = getEntry(entries, "a");
verifyEntry(entryA, "a");
String entryAContent = entryA.getContent();
assertTrue("<a/>".equals(entryAContent) || "<a><a/>".equals(entryAContent)
|| "<a xmlns=\"\"/>".equals(entryAContent));
Entry entryB = getEntry(entries, "b");
verifyEntry(entryB, "b");
String entryBContent = entryB.getContent();
assertTrue("<b/>".equals(entryBContent) || "<b><b/>".equals(entryBContent)
|| "<b xmlns=\"\"/>".equals(entryBContent));
}
@Test
public void testWriteEntryWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom2");
assertNotNull(provider);
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
provider.writeTo(new Book("a"), Book.class, Book.class, new Annotation[]{},
MediaType.valueOf("application/atom+xml;type=entry"), null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Entry entry = new AtomEntryProvider().readFrom(Entry.class, null, null, null, null, bis);
verifyEntry(entry, "a");
}
@Test
public void testReadEntryWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom3");
assertNotNull(provider);
doTestReadEntry(provider);
}
@Test
public void testReadEntryWithoutBuilders() throws Exception {
doTestReadEntry(new AtomPojoProvider());
}
private void doTestReadEntry(AtomPojoProvider provider) throws Exception {
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
MediaType mt = MediaType.valueOf("application/atom+xml;type=entry");
provider.writeTo(new Book("a"), Book.class, Book.class, new Annotation[]{}, mt, null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
@SuppressWarnings({"unchecked", "rawtypes" })
Book book = (Book)provider.readFrom((Class)Book.class, Book.class,
new Annotation[]{}, mt, null, bis);
assertEquals("a", book.getName());
}
@Test
public void testReadEntryNoBuilders2() throws Exception {
final String entry =
"<!DOCTYPE entry SYSTEM \"entry://entry\"><entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<title type=\"text\">a</title>"
+ "<content type=\"application/xml\">"
+ "<book xmlns=\"\">"
+ "<name>a</name>"
+ "</book>"
+ "</content>"
+ "</entry>";
AtomPojoProvider provider = new AtomPojoProvider();
ByteArrayInputStream bis = new ByteArrayInputStream(entry.getBytes());
MediaType mt = MediaType.valueOf("application/atom+xml;type=entry");
@SuppressWarnings({"unchecked", "rawtypes" })
Book book = (Book)provider.readFrom((Class)Book.class, Book.class,
new Annotation[]{}, mt, null, bis);
assertEquals("a", book.getName());
}
@Test
public void testReadFeedWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom4");
assertNotNull(provider);
doTestReadFeed(provider);
}
@Test
public void testReadFeedWithoutBuilders() throws Exception {
AtomPojoProvider provider = new AtomPojoProvider();
doTestReadFeed(provider);
}
private void doTestReadFeed(AtomPojoProvider provider) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
MediaType mt = MediaType.valueOf("application/atom+xml;type=feed");
Books books = new Books();
List<Book> bs = new ArrayList<>();
bs.add(new Book("a"));
bs.add(new Book("b"));
books.setBooks(bs);
provider.writeTo(books, Books.class, Books.class, new Annotation[]{}, mt, null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
@SuppressWarnings({"unchecked", "rawtypes" })
Books books2 = (Books)provider.readFrom((Class)Books.class, Books.class,
new Annotation[]{}, mt, null, bis);
List<Book> list = books2.getBooks();
assertEquals(2, list.size());
assertTrue("a".equals(list.get(0).getName()) || "a".equals(list.get(1).getName()));
assertTrue("b".equals(list.get(0).getName()) || "b".equals(list.get(1).getName()));
}
@Test
public void testReadFeedWithoutBuilders2() throws Exception {
AtomPojoProvider provider = new AtomPojoProvider();
final String feed =
"<!DOCTYPE feed SYSTEM \"feed://feed\"><feed xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<entry><content type=\"application/xml\"><book xmlns=\"\"><name>a</name></book></content></entry>"
+ "<entry><content type=\"application/xml\"><book xmlns=\"\"><name>b</name></book></content></entry>"
+ "</feed>";
MediaType mt = MediaType.valueOf("application/atom+xml;type=feed");
ByteArrayInputStream bis = new ByteArrayInputStream(feed.getBytes());
@SuppressWarnings({"unchecked", "rawtypes" })
Books books2 = (Books)provider.readFrom((Class)Books.class, Books.class,
new Annotation[]{}, mt, null, bis);
List<Book> list = books2.getBooks();
assertEquals(2, list.size());
assertTrue("a".equals(list.get(0).getName()) || "a".equals(list.get(1).getName()));
assertTrue("b".equals(list.get(0).getName()) || "b".equals(list.get(1).getName()));
}
@Test
public void testReadEntryNoContent() throws Exception {
/** A sample entry without content. */
final String entryNoContent =
"<?xml version='1.0' encoding='UTF-8'?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <id>84297856</id>\n"
+ "</entry>";
AtomPojoProvider atomPojoProvider = new AtomPojoProvider();
@SuppressWarnings({
"rawtypes", "unchecked"
})
JaxbDataType type = (JaxbDataType)atomPojoProvider.readFrom((Class)JaxbDataType.class,
JaxbDataType.class,
new Annotation[0],
MediaType.valueOf("application/atom+xml;type=entry"),
new MetadataMap<String, String>(),
new ByteArrayInputStream(entryNoContent.getBytes(StandardCharsets.UTF_8)));
assertNull(type);
}
@Test
public void testReadEntryWithUpperCaseTypeParam() throws Exception {
doReadEntryWithContent("application/atom+xml;type=ENTRY");
}
@Test
public void testReadEntryNoTypeParam() throws Exception {
doReadEntryWithContent("application/atom+xml");
}
private void doReadEntryWithContent(String mediaType) throws Exception {
final String entryWithContent =
"<?xml version='1.0' encoding='UTF-8'?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <id>84297856</id>\n"
+ " <content type=\"application/xml\">\n"
+ " <jaxbDataType xmlns=\"\">\n"
+ " </jaxbDataType>\n"
+ " </content>\n"
+ "</entry>";
AtomPojoProvider atomPojoProvider = new AtomPojoProvider();
@SuppressWarnings({
"rawtypes", "unchecked"
})
JaxbDataType type = (JaxbDataType)atomPojoProvider.readFrom((Class)JaxbDataType.class,
JaxbDataType.class,
new Annotation[0],
MediaType.valueOf(mediaType),
new MetadataMap<String, String>(),
new ByteArrayInputStream(entryWithContent.getBytes(StandardCharsets.UTF_8)));
assertNotNull(type);
}
/**
* A sample JAXB data-type to read data into.
*/
@XmlRootElement
public static class JaxbDataType {
// no data
}
private Entry getEntry(List<Entry> entries, String title) {
for (Entry e : entries) {
if (title.equals(e.getTitle())) {
return e;
}
}
return null;
}
private void verifyEntry(Entry e, String title) {
assertNotNull(e);
assertEquals(title, e.getTitle());
}
public static class CustomFeedWriter implements AtomElementWriter<Feed, Books> {
public void writeTo(Feed feed, Books pojoFeed) {
feed.setTitle("Books");
}
}
public static class CustomEntryWriter implements AtomElementWriter<Entry, Book> {
public void writeTo(Entry entry, Book pojoEntry) {
entry.setTitle(pojoEntry.getName());
}
}
public static class CustomEntryReader implements AtomElementReader<Entry, Book> {
public Book readFrom(Entry element) {
try {
String s = element.getContent();
Unmarshaller um =
new JAXBElementProvider<Book>().getJAXBContext(Book.class, Book.class)
.createUnmarshaller();
return (Book)um.unmarshal(new StringReader(s));
} catch (Exception ex) {
// ignore
}
return null;
}
}
public static class CustomFeedReader implements AtomElementReader<Feed, Books> {
public Books readFrom(Feed element) {
Books books = new Books();
List<Book> list = new ArrayList<>();
CustomEntryReader entryReader = new CustomEntryReader();
for (Entry e : element.getEntries()) {
list.add(entryReader.readFrom(e));
}
books.setBooks(list);
return books;
}
}
public static class CustomFeedBuilder extends AbstractFeedBuilder<Books> {
@Override
public String getBaseUri(Books books) {
return "http://books";
}
}
public static class CustomEntryBuilder extends AbstractEntryBuilder<Book> {
@Override
public String getBaseUri(Book books) {
return "http://book";
}
}
@XmlRootElement
public static class Book {
private String name = "Book";
public Book() {
}
public Book(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getXMLContent() {
return "<" + name + "/>";
}
}
@XmlRootElement
public static class Books {
private List<Book> books;
public Books() {
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> list) {
books = list;
}
}
}