• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.app.appsearch;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.app.appsearch.annotation.CanIgnoreReturnValue;
21 import android.util.ArrayMap;
22 
23 import java.util.Collections;
24 import java.util.Map;
25 import java.util.Objects;
26 
27 /**
28  * Provides results for AppSearch batch operations which encompass multiple documents.
29  *
30  * <p>Individual results of a batch operation are separated into two maps: one for successes and one
31  * for failures. For successes, {@link #getSuccesses()} will return a map of keys to instances of
32  * the value type. For failures, {@link #getFailures()} will return a map of keys to {@link
33  * AppSearchResult} objects.
34  *
35  * <p>Alternatively, {@link #getAll()} returns a map of keys to {@link AppSearchResult} objects for
36  * both successes and failures.
37  *
38  * @param <KeyType> The type of the keys for which the results will be reported.
39  * @param <ValueType> The type of the result objects for successful results.
40  * @see AppSearchSession#put
41  * @see AppSearchSession#getByDocumentId
42  * @see AppSearchSession#remove
43  */
44 public final class AppSearchBatchResult<KeyType, ValueType> {
45     @NonNull private final Map<KeyType, ValueType> mSuccesses;
46     @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mFailures;
47     @NonNull private final Map<KeyType, AppSearchResult<ValueType>> mAll;
48 
AppSearchBatchResult( @onNull Map<KeyType, ValueType> successes, @NonNull Map<KeyType, AppSearchResult<ValueType>> failures, @NonNull Map<KeyType, AppSearchResult<ValueType>> all)49     AppSearchBatchResult(
50             @NonNull Map<KeyType, ValueType> successes,
51             @NonNull Map<KeyType, AppSearchResult<ValueType>> failures,
52             @NonNull Map<KeyType, AppSearchResult<ValueType>> all) {
53         mSuccesses = Objects.requireNonNull(successes);
54         mFailures = Objects.requireNonNull(failures);
55         mAll = Objects.requireNonNull(all);
56     }
57 
58     /** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */
isSuccess()59     public boolean isSuccess() {
60         return mFailures.isEmpty();
61     }
62 
63     /**
64      * Returns a {@link Map} of keys mapped to instances of the value type for all successful
65      * individual results.
66      *
67      * <p>Example: {@link AppSearchSession#getByDocumentId} returns an {@link AppSearchBatchResult}.
68      * Each key (the document ID, of {@code String} type) will map to a {@link GenericDocument}
69      * object.
70      *
71      * <p>The values of the {@link Map} will not be {@code null}.
72      */
73     @NonNull
getSuccesses()74     public Map<KeyType, ValueType> getSuccesses() {
75         return Collections.unmodifiableMap(mSuccesses);
76     }
77 
78     /**
79      * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all failed
80      * individual results.
81      *
82      * <p>The values of the {@link Map} will not be {@code null}.
83      */
84     @NonNull
getFailures()85     public Map<KeyType, AppSearchResult<ValueType>> getFailures() {
86         return Collections.unmodifiableMap(mFailures);
87     }
88 
89     /**
90      * Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all
91      * individual results.
92      *
93      * <p>The values of the {@link Map} will not be {@code null}.
94      */
95     @NonNull
getAll()96     public Map<KeyType, AppSearchResult<ValueType>> getAll() {
97         return Collections.unmodifiableMap(mAll);
98     }
99 
100     /**
101      * Asserts that this {@link AppSearchBatchResult} has no failures.
102      *
103      * @hide
104      */
checkSuccess()105     public void checkSuccess() {
106         if (!isSuccess()) {
107             throw new IllegalStateException("AppSearchBatchResult has failures: " + this);
108         }
109     }
110 
111     @Override
112     @NonNull
toString()113     public String toString() {
114         return "{\n  successes: " + mSuccesses + "\n  failures: " + mFailures + "\n}";
115     }
116 
117     /**
118      * Builder for {@link AppSearchBatchResult} objects.
119      *
120      * @param <KeyType> The type of the keys for which the results will be reported.
121      * @param <ValueType> The type of the result objects for successful results.
122      */
123     public static final class Builder<KeyType, ValueType> {
124         private ArrayMap<KeyType, ValueType> mSuccesses = new ArrayMap<>();
125         private ArrayMap<KeyType, AppSearchResult<ValueType>> mFailures = new ArrayMap<>();
126         private ArrayMap<KeyType, AppSearchResult<ValueType>> mAll = new ArrayMap<>();
127         private boolean mBuilt = false;
128 
129         /**
130          * Associates the {@code key} with the provided successful return value.
131          *
132          * <p>Any previous mapping for a key, whether success or failure, is deleted.
133          *
134          * <p>This is a convenience function which is equivalent to {@code setResult(key,
135          * AppSearchResult.newSuccessfulResult(value))}.
136          *
137          * @param key The key to associate the result with; usually corresponds to some identifier
138          *     from the input like an ID or name.
139          * @param value An optional value to associate with the successful result of the operation
140          *     being performed.
141          */
142         @CanIgnoreReturnValue
143         @SuppressWarnings("MissingGetterMatchingBuilder") // See getSuccesses
144         @NonNull
setSuccess( @onNull KeyType key, @Nullable ValueType value)145         public Builder<KeyType, ValueType> setSuccess(
146                 @NonNull KeyType key, @Nullable ValueType value) {
147             Objects.requireNonNull(key);
148             resetIfBuilt();
149             return setResult(key, AppSearchResult.newSuccessfulResult(value));
150         }
151 
152         /**
153          * Associates the {@code key} with the provided failure code and error message.
154          *
155          * <p>Any previous mapping for a key, whether success or failure, is deleted.
156          *
157          * <p>This is a convenience function which is equivalent to {@code setResult(key,
158          * AppSearchResult.newFailedResult(resultCode, errorMessage))}.
159          *
160          * @param key The key to associate the result with; usually corresponds to some identifier
161          *     from the input like an ID or name.
162          * @param resultCode One of the constants documented in {@link
163          *     AppSearchResult#getResultCode}.
164          * @param errorMessage An optional string describing the reason or nature of the failure.
165          */
166         @CanIgnoreReturnValue
167         @SuppressWarnings("MissingGetterMatchingBuilder") // See getFailures
168         @NonNull
setFailure( @onNull KeyType key, @AppSearchResult.ResultCode int resultCode, @Nullable String errorMessage)169         public Builder<KeyType, ValueType> setFailure(
170                 @NonNull KeyType key,
171                 @AppSearchResult.ResultCode int resultCode,
172                 @Nullable String errorMessage) {
173             Objects.requireNonNull(key);
174             resetIfBuilt();
175             return setResult(key, AppSearchResult.newFailedResult(resultCode, errorMessage));
176         }
177 
178         /**
179          * Associates the {@code key} with the provided {@code result}.
180          *
181          * <p>Any previous mapping for a key, whether success or failure, is deleted.
182          *
183          * @param key The key to associate the result with; usually corresponds to some identifier
184          *     from the input like an ID or name.
185          * @param result The result to associate with the key.
186          */
187         @CanIgnoreReturnValue
188         @SuppressWarnings("MissingGetterMatchingBuilder") // See getAll
189         @NonNull
setResult( @onNull KeyType key, @NonNull AppSearchResult<ValueType> result)190         public Builder<KeyType, ValueType> setResult(
191                 @NonNull KeyType key, @NonNull AppSearchResult<ValueType> result) {
192             Objects.requireNonNull(key);
193             Objects.requireNonNull(result);
194             resetIfBuilt();
195             if (result.isSuccess()) {
196                 mSuccesses.put(key, result.getResultValue());
197                 mFailures.remove(key);
198             } else {
199                 mFailures.put(key, result);
200                 mSuccesses.remove(key);
201             }
202             mAll.put(key, result);
203             return this;
204         }
205 
206         /**
207          * Builds an {@link AppSearchBatchResult} object from the contents of this {@link Builder}.
208          */
209         @NonNull
build()210         public AppSearchBatchResult<KeyType, ValueType> build() {
211             mBuilt = true;
212             return new AppSearchBatchResult<>(mSuccesses, mFailures, mAll);
213         }
214 
resetIfBuilt()215         private void resetIfBuilt() {
216             if (mBuilt) {
217                 mSuccesses = new ArrayMap<>(mSuccesses);
218                 mFailures = new ArrayMap<>(mFailures);
219                 mAll = new ArrayMap<>(mAll);
220                 mBuilt = false;
221             }
222         }
223     }
224 }
225