package com.googlecode.objectify.util;
import com.google.appengine.api.datastore.EmbeddedEntity;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Projection;
import com.google.appengine.api.datastore.PropertyContainer;
import com.google.appengine.api.datastore.Query.SortPredicate;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.impl.Path;
import com.googlecode.objectify.impl.translate.SaveContext;
import java.util.ArrayList;
import java.util.List;
/**
* Some static utility methods for interacting with basic datastore objects like keys and queries.
*/
public class DatastoreUtils
{
private DatastoreUtils() {
}
/**
* Turn a list of refs into a list of raw keys.
*/
public static List<com.google.appengine.api.datastore.Key> getRawKeys(Iterable<? extends Ref<?>> refs) {
List<com.google.appengine.api.datastore.Key> rawKeys = new ArrayList<>();
for (Ref<?> ref: refs)
rawKeys.add(ref.getKey().getRaw());
return rawKeys;
}
/**
* Make a new Query object that is exactly like the old. Too bad Query isn't Cloneable.
*/
public static com.google.appengine.api.datastore.Query cloneQuery(com.google.appengine.api.datastore.Query orig) {
com.google.appengine.api.datastore.Query copy = new com.google.appengine.api.datastore.Query(orig.getKind(), orig.getAncestor());
copy.setFilter(orig.getFilter());
for (SortPredicate sort: orig.getSortPredicates())
copy.addSort(sort.getPropertyName(), sort.getDirection());
for (Projection projection: orig.getProjections())
copy.addProjection(projection);
if (orig.isKeysOnly())
copy.setKeysOnly();
copy.setDistinct(orig.getDistinct());
return copy;
}
/**
* Construct a Key<?> from a Long or String id
* @param id must be either Long or String
*/
public static <T> Key<T> createKey(Key<?> parent, Class<T> kind, Object id) {
if (id instanceof String)
return Key.create(parent, kind, (String)id);
else if (id instanceof Long)
return Key.create(parent, kind, (Long)id);
else
throw new IllegalArgumentException("id '" + id + "' must be String or Long");
}
/**
* Construct a Key<?> from a Long or String id
* @param id must be either Long or String
*/
public static <T> Key<T> createKey(Key<?> parent, String kind, Object id) {
com.google.appengine.api.datastore.Key key = createKey(parent == null ? null : parent.getRaw(), kind, id);
return Key.create(key);
}
/**
* Construct a Key from a Long or String id
* @param id must be either Long or String
*/
public static com.google.appengine.api.datastore.Key createKey(com.google.appengine.api.datastore.Key parent, String kind, Object id) {
if (id instanceof String)
return KeyFactory.createKey(parent, kind, (String)id);
else if (id instanceof Long)
return KeyFactory.createKey(parent, kind, (Long)id);
else
throw new IllegalArgumentException("id '" + id + "' must be String or Long");
}
/**
* Make a list of keys
* @param ids must contain either Long or String
*/
public static List<com.google.appengine.api.datastore.Key> createKeys(com.google.appengine.api.datastore.Key parent, String kind, Iterable<?> ids) {
List<com.google.appengine.api.datastore.Key> keys = new ArrayList<>();
for (Object id: ids)
keys.add(createKey(parent, kind, id));
return keys;
}
/**
* Make a list of Key<?>s
* @param ids must contain either Long or String
*/
public static <T> List<Key<T>> createKeys(Key<?> parent, Class<T> kind, Iterable<?> ids) {
List<Key<T>> keys = new ArrayList<>();
for (Object id: ids)
keys.add(createKey(parent, kind, id));
return keys;
}
/**
* Gets the String or Long id from the key, or null if incomplete
*/
@SuppressWarnings("unchecked")
public static <S> S getId(com.google.appengine.api.datastore.Key key) {
if (!key.isComplete())
return null;
else if (key.getName() != null)
return (S)key.getName();
else
return (S)(Long)key.getId();
}
/**
* Gets the String or Long id from the key, or null if incomplete
*/
public static <S> S getId(Key<?> key) {
return getId(key.getRaw());
}
/**
* Unfortunately Entity and EmbeddedEntity do not share a common interface for getting key.
*/
public static com.google.appengine.api.datastore.Key getKey(PropertyContainer container) {
if (container instanceof EmbeddedEntity)
return ((EmbeddedEntity)container).getKey();
else if (container instanceof Entity)
return ((Entity)container).getKey();
else
throw new IllegalArgumentException("Unknown type of property container: " + container.getClass());
}
/**
* Calls setProperty() or setUnindexedProperty() as determined by the index parameter.
* Also stuffs any values in the savecontext index.
*/
public static void setContainerProperty(PropertyContainer entity, String propertyName, Object value, boolean index, SaveContext ctx, Path propPath) {
if (index) {
entity.setProperty(propertyName, value);
ctx.addIndex(propPath, value);
} else {
entity.setUnindexedProperty(propertyName, value);
}
}
}