Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / datastore / BaseCallbackContext.java
blobbfca795557194febc7734ed7bf5ef2942b7461b1
1 // Copyright 2011 Google. All Rights Reserved.
2 package com.google.appengine.api.datastore;
4 import com.google.common.base.MoreObjects;
5 import com.google.common.base.Preconditions;
6 import com.google.common.collect.Iterables;
7 import com.google.common.collect.Multimap;
9 import java.util.Collection;
10 import java.util.Collections;
11 import java.util.List;
13 /**
14 * Abstract base class with a common {@link CallbackContext} implementation.
17 abstract class BaseCallbackContext<T> implements CallbackContext<T> {
18 private final CurrentTransactionProvider currentTxnProvider;
20 /**
21 * All elements provided to the operation that triggered the callback.
23 private final List<T> elements;
25 /**
26 * The index into {@link #elements} of the "current" element.
28 private int currentIndex;
30 /**
31 * @param currentTxnProvider Provides the current transaction
32 * @param elements All elements involved in the operation that triggered the
33 * callback.
35 BaseCallbackContext(CurrentTransactionProvider currentTxnProvider, List<T> elements) {
36 this.currentTxnProvider = Preconditions.checkNotNull(currentTxnProvider);
37 this.elements = Collections.unmodifiableList(Preconditions.checkNotNull(elements));
40 @Override
41 public List<T> getElements() {
42 return elements;
45 @Override
46 public Transaction getCurrentTransaction() {
47 return currentTxnProvider.getCurrentTransaction(null);
50 @Override
51 public int getCurrentIndex() {
52 return currentIndex;
55 @Override
56 public T getCurrentElement() {
57 return elements.get(currentIndex);
60 /**
61 * Executes all appropriate callbacks for the elements in this context.
63 * @param callbacksByKind A Multimap containing lists of callbacks, organized by
64 * kind.
65 * @param noKindCallbacks Callbacks that apply to all elements, independent
66 * of kind.
68 * @throws IllegalStateException If this method has already been called.
70 void executeCallbacks(Multimap<String, DatastoreCallbacksImpl.Callback> callbacksByKind,
71 Collection<DatastoreCallbacksImpl.Callback> noKindCallbacks) {
72 Preconditions.checkState(currentIndex == 0,
73 "executeCallbacks cannot be called more than once.");
74 for (T ele : elements) {
75 Iterable<DatastoreCallbacksImpl.Callback> allCallbacksToRun =
76 Iterables.concat(callbacksByKind.get(getKind(ele)), noKindCallbacks);
77 for (DatastoreCallbacksImpl.Callback callback : allCallbacksToRun) {
78 callback.run(this);
80 currentIndex++;
84 /**
85 * Abstract method that, given an element, knows how to extract its kind.
87 abstract String getKind(T ele);
89 @Override
90 public String toString() {
91 return MoreObjects.toStringHelper(this)
92 .add("elements", elements)
93 .add("currentIndex", currentIndex)
94 .toString();