All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.objectify.impl.LoaderImpl Maven / Gradle / Ivy

There is a newer version: 6.1.2
Show newest version
package com.googlecode.objectify.impl;

import com.google.appengine.api.datastore.Entity;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.LoadResult;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.Result;
import com.googlecode.objectify.cmd.LoadType;
import com.googlecode.objectify.cmd.Loader;
import com.googlecode.objectify.impl.translate.LoadContext;
import com.googlecode.objectify.util.ResultCache;
import com.googlecode.objectify.util.ResultNowFunction;
import com.googlecode.objectify.util.ResultProxy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * 

Implementation of the Loader interface. This is also suitable for subclassing; you * can return your own subclass by overriding ObjectifyImpl.load().

* * @author Jeff Schnitzer */ public class LoaderImpl extends Queryable implements Loader, Cloneable { /** */ protected ObjectifyImpl ofy; /** */ protected LoadArrangement loadArrangement = new LoadArrangement(); /** */ public LoaderImpl(ObjectifyImpl ofy) { super(null); this.ofy = ofy; } /* (non-Javadoc) * @see com.googlecode.objectify.impl.cmd.QueryDefinition#createQuery() */ @Override QueryImpl createQuery() { return new QueryImpl<>(this); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#group(java.lang.Class[]) */ @Override @SuppressWarnings("unchecked") public L group(Class... groups) { LoaderImpl clone = this.clone(); clone.loadArrangement = new LoadArrangement(); clone.loadArrangement.addAll(Arrays.asList(groups)); clone.loadArrangement.addAll(this.loadArrangement); return (L)clone; } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#type(java.lang.Class) */ @Override public LoadType type(Class type) { return new LoadTypeImpl<>(this, Key.getKind(type), type); } @Override public LoadType kind(String kind) { return new LoadTypeImpl<>(this, kind, null); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#ref(com.googlecode.objectify.Ref) */ @Override public LoadResult ref(Ref ref) { return key(ref.key()); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#refs(com.googlecode.objectify.Ref[]) */ @Override @SuppressWarnings("unchecked") public Map, E> refs(Ref... refs) { return refs(Arrays.asList((Ref[])refs)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#refs(java.lang.Iterable) */ @Override public Map, E> refs(final Iterable> refs) { return values(refs); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#entity(com.googlecode.objectify.Key) */ @Override public LoadResult key(Key key) { return new LoadResult<>(key, createLoadEngine().load(key)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#entity(java.lang.Object) */ @Override public LoadResult entity(E entity) { return key(ofy.factory().keys().keyOf(entity)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#value(java.lang.Object) */ @Override @SuppressWarnings("unchecked") public LoadResult value(Object key) { return (LoadResult)key(ofy.factory().keys().anythingToKey(key)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#keys(com.googlecode.objectify.Key[]) */ @Override @SuppressWarnings("unchecked") public Map, E> keys(Key... keys) { return this.keys(Arrays.asList((Key[])keys)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#keys(java.lang.Iterable) */ @Override public Map, E> keys(Iterable> keys) { return values(keys); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#entities(E[]) */ @Override public Map, E> entities(E... entities) { return this.entities(Arrays.asList(entities)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#entities(java.lang.Iterable) */ @Override public Map, E> entities(Iterable values) { return values(values); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#values(java.lang.Object[]) */ @Override public Map, E> values(Object... values) { return values(Arrays.asList(values)); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#values(java.lang.Iterable) */ @Override @SuppressWarnings("unchecked") public Map, E> values(Iterable values) { // Do this in a separate pass so any errors converting keys will show up before we try loading something List> keys = new ArrayList<>(); for (Object keyish: values) keys.add((Key)ofy.factory().keys().anythingToKey(keyish)); LoadEngine engine = createLoadEngine(); final Map, Result> results = new LinkedHashMap<>(); for (Key key: keys) results.put(key, engine.load(key)); engine.execute(); // Now asynchronously translate into a normal-looking map. We must be careful to exclude results with // null (missing) values because that is the contract established by DatastoreService.get(). // We use the ResultProxy and create a new map because the performance of filtered views is questionable. return ResultProxy.create(Map.class, new ResultCache, E>>() { @Override public Map, E> nowUncached() { return Maps.newLinkedHashMap( Maps.filterValues( Maps.transformValues(results, ResultNowFunction.instance()), Predicates.notNull())); } }); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#getObjectify() */ @Override public Objectify getObjectify() { return ofy; } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#getLoadGroups() */ @Override public Set> getLoadGroups() { return Collections.unmodifiableSet(loadArrangement); } /** */ public ObjectifyImpl getObjectifyImpl() { return this.ofy; } /** * Use this once for one operation and then throw it away * @return a fresh engine that handles fundamental datastore operations for load commands */ LoadEngine createLoadEngine() { return new LoadEngine(ofy, ofy.getSession(), ofy.createAsyncDatastoreService(), loadArrangement); } /** * Use this once for one operation and then throw it away * @return a fresh engine that handles fundamental datastore operations for queries */ QueryEngine createQueryEngine() { return new QueryEngine(this, ofy.createAsyncDatastoreService(), ofy.getTransaction() == null ? null : ofy.getTransaction().getRaw()); } /* (non-Javadoc) * @see com.googlecode.objectify.cmd.Loader#now(com.googlecode.objectify.Key) */ @Override public E now(Key key) { return createLoadEngine().load(key).now(); } /* (non-Javadoc) * @see com.googlecode.objectify.Objectify#toPojo(com.google.appengine.api.datastore.Entity) */ @Override public T fromEntity(Entity entity) { LoadEngine engine = createLoadEngine(); LoadContext context = new LoadContext(engine); T result = engine.load(entity, context); context.done(); return result; } /* (non-Javadoc) * @see java.lang.Object#clone() */ @SuppressWarnings("unchecked") protected LoaderImpl clone() { try { return (LoaderImpl)super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); // impossible } } }