package com.example.listmaker.server.dao; import com.google.appengine.api.datastore.QueryResultIterator; import com.googlecode.objectify.*; import com.example.listmaker.common.domain.*; import com.turbomanage.gwt.exception.TooManyResultsException; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.util.List; import java.util.Map; /** * Generic DAO for use with Objectify * * @author turbomanage * * @param <T> */ public class ObjectifyDao<T> extends OfyService { static final int BAD_MODIFIERS = Modifier.FINAL | Modifier.STATIC | Modifier.TRANSIENT; protected Class<T> clazz; public ObjectifyDao() { clazz = (Class<T>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } public Key<T> put(T entity) { return ofy().save().entity(entity).now(); } public Map<Key<T>, T> putAll(Iterable<T> entities) { return ofy().save().entities(entities).now(); } public void delete(T entity) { ofy().delete().entity(entity).now(); } public void delete(long id) { Key<T> key = Key.create(clazz, id); deleteKey(key); } public void deleteKey(Key<T> entityKey) { ofy().delete().key(entityKey).now(); } public void deleteAll(Iterable<T> entities) { ofy().delete().entities(entities).now(); } public void deleteKeys(Iterable<Key<T>> keys) { ofy().delete().keys(keys).now(); } public T get(Long id) throws NotFoundException { return ofy().load().type(this.clazz).id(id).safe(); } public T get(Key<T> key) throws NotFoundException { return ofy().load().key(key).safe(); } public Map<Key<T>, T> get(Iterable<Key<T>> keys) { return ofy().load().keys(keys); } public List<T> listAll() { return ofy().load().type(clazz).list(); } /** * Convenience method to get all objects matching a single property * * @param propName * @param propValue * @return T matching Object * @throws TooManyResultsException */ public T getByProperty(String propName, Object propValue) throws TooManyResultsException { QueryResultIterator<T> fetch = ofy().load().type(clazz) .filter(propName, propValue) .limit(2).iterator(); if (!fetch.hasNext()) { return null; } T obj = fetch.next(); if (fetch.hasNext()) { throw new TooManyResultsException(fetch.toString() + " returned too many results"); } return obj; } public List<T> listByProperty(String propName, Object propValue) { List<T> list = ofy().load().type(clazz).filter(propName, propValue).list(); return list; } public List<Key<T>> listKeysByProperty(String propName, Object propValue) { return ofy().load().type(clazz).filter(propName, propValue).keys().list(); } // public T getByExample(T exampleObj) throws TooManyResultsException // { // Query<T> q = buildQueryByExample(exampleObj); // Iterator<T> fetch = q.limit(2).list().iterator(); // if (!fetch.hasNext()) // { // return null; // } // T obj = fetch.next(); // if (fetch.hasNext()) // { // throw new TooManyResultsException(q.toString() // + " returned too many results"); // } // return obj; // } // public List<T> listByExample(T exampleObj) // { // Query<T> queryByExample = buildQueryByExample(exampleObj); // return queryByExample.list(); // } public T getByOwner(User u) throws TooManyResultsException { Ref<User> userKey = Ref.create(u); return getByProperty("ownerKey", userKey); } public List<T> listByOwner(User u) { Ref<User> userKey = Ref.create(u); return listByProperty("ownerKey", userKey); } public Key<T> key(T obj) { return ofy().factory().keys().keyOf(obj); } public List<T> listChildren(Object parent) { return ofy().load().type(clazz).ancestor(parent).list(); } public List<Key<T>> listChildKeys(Object parent) { return ofy().load().type(clazz).ancestor(parent).keys().list(); } // protected Query<T> buildQueryByExample(T exampleObj) // { // Query<T> q = ofy().query(clazz); // // // Add all non-null properties to query filter // for (Field field : clazz.getDeclaredFields()) // { // // Ignore transient, embedded, array, and collection properties // if (field.isAnnotationPresent(Transient.class) // || (field.isAnnotationPresent(Embedded.class)) // || (field.getType().isArray()) // || (field.getType().isArray()) // || (Collection.class.isAssignableFrom(field.getType())) // || ((field.getModifiers() & BAD_MODIFIERS) != 0)) // continue; // // field.setAccessible(true); // // Object value; // try // { // value = field.get(exampleObj); // } catch (IllegalArgumentException e) // { // throw new RuntimeException(e); // } catch (IllegalAccessException e) // { // throw new RuntimeException(e); // } // if (value != null) // { // q.filter(field.getName(), value); // } // } // // return q; // } }