View Javadoc
1   package com.atlassian.activeobjects.test.model;
2   
3   import com.atlassian.activeobjects.external.ActiveObjects;
4   import com.atlassian.activeobjects.test.TestActiveObjects;
5   import com.google.common.base.Function;
6   import com.google.common.base.Joiner;
7   import com.google.common.base.Predicate;
8   import com.google.common.base.Supplier;
9   import com.google.common.base.Suppliers;
10  import com.google.common.collect.ImmutableList;
11  import com.google.common.collect.ImmutableMap;
12  import com.google.common.collect.Iterables;
13  import net.java.ao.EntityManager;
14  import net.java.ao.RawEntity;
15  import org.apache.commons.io.IOUtils;
16  import org.slf4j.Logger;
17  import org.slf4j.LoggerFactory;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.text.ParseException;
22  import java.text.SimpleDateFormat;
23  import java.util.Date;
24  import java.util.Locale;
25  import java.util.TimeZone;
26  
27  import static com.google.common.base.Preconditions.checkNotNull;
28  import static com.google.common.collect.Collections2.transform;
29  import static com.google.common.collect.Lists.newArrayList;
30  import static org.junit.Assert.assertEquals;
31  
32  public final class Model {
33      private static final String DATE_FORMAT = "MMM d, yyyy";
34  
35      private static final String BRIAN_GOETZ = "Brian Goetz";
36      private static final String TIM_PEIERLS = "Tim Peierls";
37      private static final String JOSHUA_BLOCH = "Joshua Bloch";
38      private static final String JOSEPH_BOWBEER = "Joseph Bowbeer";
39      private static final String DOUG_LEA = "Doug Lea";
40      private static final String DAVID_HOLMES = "David Holmes";
41      private static final String MARTIN_ODERSKY = "Martin Odersky";
42      private static final String LEX_SPOON = "Lex Spoon";
43  
44      private static final String BILL_VENNERS = "Bill Venners";
45      private static final String JCIP = "Java Concurrency In Practice";
46      private static final double JCIP_PRICE = 37.79;
47      private static final Date JCIP_PUBLISHED = toDate("May 19, 2006");
48      private static final long JCIP_ISBN = 9780321349606L;
49      private static final boolean JCIP_READ = true;
50      private static final Integer JCIP_PAGES = 403;
51      private static final Supplier<String> JCIP_ABSTRACT = Suppliers.memoize(new BookAbstractSupplier("/com/atlassian/activeobjects/test/model/jcip.txt"));
52      private static final String JCIP_COVER = "/com/atlassian/activeobjects/test/model/jcip.jpg";
53  
54      private static final String EJ2 = "Effective Java (Second Edition)";
55      private static final double EJ2_PRICE = 41.24;
56      private static final Date EJ2_PUBLISHED = toDate("May 28, 2008");
57      private static final long EJ2_ISBN = 9780321356680L;
58      private static final boolean EJ2_READ = false;
59      private static final Integer EJ2_PAGES = null;
60      private static final Supplier<String> EJ2_ABSTRACT = Suppliers.memoize(new BookAbstractSupplier("/com/atlassian/activeobjects/test/model/ej2.txt"));
61      private static final String EJ2_COVER = "/com/atlassian/activeobjects/test/model/ej2.jpg";
62  
63      private static final String PIS = "Programming in Scala";
64      private static final double PIS_PRICE = 31.17;
65      private static final Date PIS_PUBLISHED = toDate("Jan 4, 2011");
66      private static final long PIS_ISBN = 9780981531601L;
67      private static final boolean PIS_READ = true;
68      private static final Integer PIS_PAGES = null;
69      private static final Supplier<String> PIS_ABSTRACT = Suppliers.memoize(new BookAbstractSupplier("/com/atlassian/activeobjects/test/model/pis.txt"));
70      private static final String PIS_COVER = "/com/atlassian/activeobjects/test/model/pis.jpg";
71  
72      private final Logger logger = LoggerFactory.getLogger(this.getClass());
73  
74      private final ActiveObjects ao;
75  
76      public Model(EntityManager entityManager) {
77          this.ao = new TestActiveObjects(checkNotNull(entityManager));
78      }
79  
80      public Model(ActiveObjects ao) {
81          this.ao = checkNotNull(ao);
82      }
83  
84      public void emptyDatabase() {
85          logger.debug("Emptying the database!");
86          ao.migrateDestructively();
87      }
88  
89      public void migrateEntities() {
90          final Class<? extends RawEntity<?>>[] entities = new Class[]{Book.class, Author.class, Authorship.class};
91          logger.debug("Migrating entities ({}), this will create tables", Joiner.on(',').join(entities));
92          ao.migrate(entities);
93      }
94  
95      public void createData() {
96          logger.info("Adding data to the database!");
97          resetDatabase();
98  
99          final Author[] jcip = authors(BRIAN_GOETZ, TIM_PEIERLS, JOSHUA_BLOCH, JOSEPH_BOWBEER, DAVID_HOLMES, DOUG_LEA);
100         book(JCIP, JCIP_PRICE, JCIP_ISBN, JCIP_PUBLISHED, JCIP_READ, JCIP_PAGES, JCIP_ABSTRACT.get(), jcip);
101 
102         final Author[] scala = authors(MARTIN_ODERSKY, LEX_SPOON, BILL_VENNERS);
103         book(PIS, PIS_PRICE, PIS_ISBN, PIS_PUBLISHED, PIS_READ, PIS_PAGES, PIS_ABSTRACT.get(), scala);
104 
105         book(EJ2, EJ2_PRICE, EJ2_ISBN, EJ2_PUBLISHED, EJ2_READ, EJ2_PAGES, EJ2_ABSTRACT.get(), findAuthorWithName(toList(jcip), JOSHUA_BLOCH)); // author is Josh Bloch
106     }
107 
108     private Author[] authors(String... names) {
109         return transform(newArrayList(names), new Function<String, Author>() {
110             public Author apply(String name) {
111                 return author(name);
112             }
113         }).toArray(new Author[names.length]);
114     }
115 
116     private Author author(String name) {
117         final Class<Author> type = Author.class;
118 
119         final Author author = ao.create(type);
120         author.setName(name);
121         author.save();
122         return author;
123     }
124 
125     private Book book(String title, double price, long isbn, Date published, boolean read, Integer pages,
126                       String bookAbstract, Author... authors) {
127         final Book book = ao.create(Book.class, ImmutableMap.<String, Object>of("ISBN", isbn));
128         book.setTitle(title);
129         book.setAbstract(bookAbstract);
130         book.setPrice(price);
131         book.setRead(read);
132         book.setNumberOfPages(pages);
133         book.setPublished(published);
134         book.save();
135 
136         for (Author author : authors) {
137             authorship(book, author);
138         }
139 
140         return book;
141     }
142 
143     private void authorship(Book book, Author author) {
144 
145         final Authorship authorship = ao.create(Authorship.class);
146         authorship.setBook(book);
147         authorship.setAuthor(author);
148         authorship.save();
149     }
150 
151     private void resetDatabase() {
152         emptyDatabase();
153         migrateEntities();
154     }
155 
156     public void checkAuthors() {
157         ImmutableList<Author> authors = allAuthors();
158         assertEquals(9, authors.size());
159 
160         assertEquals(1, findAuthorWithName(authors, BRIAN_GOETZ).getBooks().length);
161         assertEquals(1, findAuthorWithName(authors, TIM_PEIERLS).getBooks().length);
162         assertEquals(2, findAuthorWithName(authors, JOSHUA_BLOCH).getBooks().length);
163         assertEquals(1, findAuthorWithName(authors, JOSEPH_BOWBEER).getBooks().length);
164         assertEquals(1, findAuthorWithName(authors, DOUG_LEA).getBooks().length);
165         assertEquals(1, findAuthorWithName(authors, DAVID_HOLMES).getBooks().length);
166         assertEquals(1, findAuthorWithName(authors, MARTIN_ODERSKY).getBooks().length);
167         assertEquals(1, findAuthorWithName(authors, LEX_SPOON).getBooks().length);
168         assertEquals(1, findAuthorWithName(authors, BILL_VENNERS).getBooks().length);
169 
170         final String me = "Me"; // not a very good author if you ask me
171 
172         author(me); // adding a new author
173 
174         ao.flushAll();
175 
176         authors = allAuthors();
177         assertEquals(10, authors.size());
178         assertEquals(0, findAuthorWithName(authors, me).getBooks().length);
179     }
180 
181     private Author findAuthorWithName(Iterable<Author> authors, final String name) {
182         return Iterables.find(authors, new Predicate<Author>() {
183             @Override
184             public boolean apply(Author author) {
185                 return name.equals(author.getName());
186             }
187         });
188     }
189 
190     private ImmutableList<Author> allAuthors() {
191         return toList(ao.find(Author.class));
192     }
193 
194     public void checkBooks() {
195         final ImmutableList<Book> books = allBooks();
196 
197         assertEquals(3, books.size());
198 
199         checkBook(findBookWithTitle(books, JCIP), JCIP_ABSTRACT.get(), JCIP_PRICE, JCIP_ISBN, JCIP_PUBLISHED, JCIP_READ, JCIP_PAGES, 6);
200         checkBook(findBookWithTitle(books, PIS), PIS_ABSTRACT.get(), PIS_PRICE, PIS_ISBN, PIS_PUBLISHED, PIS_READ, PIS_PAGES, 3);
201         checkBook(findBookWithTitle(books, EJ2), EJ2_ABSTRACT.get(), EJ2_PRICE, EJ2_ISBN, EJ2_PUBLISHED, EJ2_READ, EJ2_PAGES, 1);
202     }
203 
204     private void checkBook(Book book, String bookAbstract, double price, long isbn, Date published, boolean read, Integer pages, int i) {
205         assertEquals(bookAbstract, book.getAbstract());
206         assertEquals(price, book.getPrice(), 0d);
207         assertEquals(published.getTime(), book.getPublished().getTime());
208         assertEquals(isbn, book.getIsbn());
209         assertEquals(read, book.isRead());
210         assertEquals(pages, book.getNumberOfPages());
211         assertEquals(i, book.getAuthors().length);
212     }
213 
214     private Book findBookWithTitle(Iterable<Book> books, final String title) {
215         return Iterables.find(books, new Predicate<Book>() {
216             @Override
217             public boolean apply(Book book) {
218                 return title.equals(book.getTitle());
219             }
220         });
221     }
222 
223     private ImmutableList<Book> allBooks() {
224         return toList(ao.find(Book.class));
225     }
226 
227     private <T> ImmutableList<T> toList(T[] authors) {
228         return ImmutableList.copyOf(newArrayList(authors));
229     }
230 
231     private static final class BookAbstractSupplier implements Supplier<String> {
232         private final String resource;
233 
234         public BookAbstractSupplier(String resource) {
235             this.resource = resource;
236         }
237 
238         @Override
239         public String get() {
240             return resource == null ? "" : load();
241         }
242 
243         private String load() {
244             InputStream is = null;
245             try {
246                 is = this.getClass().getResourceAsStream(resource);
247                 return IOUtils.toString(is, "UTF-8");
248             } catch (IOException e) {
249                 throw new IllegalStateException(e);
250             } finally {
251                 IOUtils.closeQuietly(is);
252             }
253         }
254     }
255 
256     private static Date toDate(String date) {
257         try {
258             final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT, Locale.US);
259             sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
260             return sdf.parse(date);
261         } catch (ParseException e) {
262             throw new RuntimeException(e);
263         }
264     }
265 }