blob: d493a1c28a3a2800255d3f8c3192a891e9319c66 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.appsearch;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
/**
* Provides results for AppSearch batch operations which encompass multiple documents.
*
* <p>Individual results of a batch operation are separated into two maps: one for successes and one
* for failures. For successes, {@link #getSuccesses()} will return a map of keys to instances of
* the value type. For failures, {@link #getFailures()} will return a map of keys to {@link
* AppSearchResult} objects.
*
* <p>Alternatively, {@link #getAll()} returns a map of keys to {@link AppSearchResult} objects for
* both successes and failures.
*
* @param <KeyType> The type of the keys for which the results will be reported.
* @param <ValueType> The type of the result objects for successful results.
* @see AppSearchSession#put
* @see AppSearchSession#getByDocumentId
* @see AppSearchSession#remove
*/
public final class AppSearchBatchResult<KeyType, ValueType> {
@NonNull private final Map<KeyType, ValueType> mSuccesses;
@NonNull private final Map<KeyType, AppSearchResult<ValueType>> mFailures;
@NonNull private final Map<KeyType, AppSearchResult<ValueType>> mAll;
AppSearchBatchResult(
@NonNull Map<KeyType, ValueType> successes,
@NonNull Map<KeyType, AppSearchResult<ValueType>> failures,
@NonNull Map<KeyType, AppSearchResult<ValueType>> all) {
mSuccesses = Objects.requireNonNull(successes);
mFailures = Objects.requireNonNull(failures);
mAll = Objects.requireNonNull(all);
}
/** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */
public boolean isSuccess() {
return mFailures.isEmpty();
}
/**
* Returns a {@link Map} of keys mapped to instances of the value type for all successful
* individual results.
*
* <p>Example: {@link AppSearchSession#getByDocumentId} returns an {@link AppSearchBatchResult}.
* Each key (the document ID, of {@code String} type) will map to a {@link GenericDocument}
* object.
*
* <p>The values of the {@link Map} will not be {@code null}.
*/
@NonNull
public Map<KeyType, ValueType> getSuccesses() {
return Collections.unmodifiableMap(mSuccesses);
}
/**
* Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all failed
* individual results.
*
* <p>The values of the {@link Map} will not be {@code null}.
*/
@NonNull
public Map<KeyType, AppSearchResult<ValueType>> getFailures() {
return Collections.unmodifiableMap(mFailures);
}
/**
* Returns a {@link Map} of keys mapped to instances of {@link AppSearchResult} for all
* individual results.
*
* <p>The values of the {@link Map} will not be {@code null}.
*/
@NonNull
public Map<KeyType, AppSearchResult<ValueType>> getAll() {
return Collections.unmodifiableMap(mAll);
}
@Override
@NonNull
public String toString() {
return "{\n successes: " + mSuccesses + "\n failures: " + mFailures + "\n}";
}
/**
* Builder for {@link AppSearchBatchResult} objects.
*
* @param <KeyType> The type of the keys for which the results will be reported.
* @param <ValueType> The type of the result objects for successful results.
*/
public static final class Builder<KeyType, ValueType> {
private ArrayMap<KeyType, ValueType> mSuccesses = new ArrayMap<>();
private ArrayMap<KeyType, AppSearchResult<ValueType>> mFailures = new ArrayMap<>();
private ArrayMap<KeyType, AppSearchResult<ValueType>> mAll = new ArrayMap<>();
private boolean mBuilt = false;
/**
* Associates the {@code key} with the provided successful return value.
*
* <p>Any previous mapping for a key, whether success or failure, is deleted.
*
* <p>This is a convenience function which is equivalent to {@code setResult(key,
* AppSearchResult.newSuccessfulResult(value))}.
*
* @param key The key to associate the result with; usually corresponds to some identifier
* from the input like an ID or name.
* @param value An optional value to associate with the successful result of the operation
* being performed.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // See getSuccesses
@NonNull
public Builder<KeyType, ValueType> setSuccess(
@NonNull KeyType key, @Nullable ValueType value) {
Objects.requireNonNull(key);
resetIfBuilt();
return setResult(key, AppSearchResult.newSuccessfulResult(value));
}
/**
* Associates the {@code key} with the provided failure code and error message.
*
* <p>Any previous mapping for a key, whether success or failure, is deleted.
*
* <p>This is a convenience function which is equivalent to {@code setResult(key,
* AppSearchResult.newFailedResult(resultCode, errorMessage))}.
*
* @param key The key to associate the result with; usually corresponds to some identifier
* from the input like an ID or name.
* @param resultCode One of the constants documented in {@link
* AppSearchResult#getResultCode}.
* @param errorMessage An optional string describing the reason or nature of the failure.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // See getFailures
@NonNull
public Builder<KeyType, ValueType> setFailure(
@NonNull KeyType key,
@AppSearchResult.ResultCode int resultCode,
@Nullable String errorMessage) {
Objects.requireNonNull(key);
resetIfBuilt();
return setResult(key, AppSearchResult.newFailedResult(resultCode, errorMessage));
}
/**
* Associates the {@code key} with the provided {@code result}.
*
* <p>Any previous mapping for a key, whether success or failure, is deleted.
*
* @param key The key to associate the result with; usually corresponds to some identifier
* from the input like an ID or name.
* @param result The result to associate with the key.
*/
@SuppressWarnings("MissingGetterMatchingBuilder") // See getAll
@NonNull
public Builder<KeyType, ValueType> setResult(
@NonNull KeyType key, @NonNull AppSearchResult<ValueType> result) {
Objects.requireNonNull(key);
Objects.requireNonNull(result);
resetIfBuilt();
if (result.isSuccess()) {
mSuccesses.put(key, result.getResultValue());
mFailures.remove(key);
} else {
mFailures.put(key, result);
mSuccesses.remove(key);
}
mAll.put(key, result);
return this;
}
/**
* Builds an {@link AppSearchBatchResult} object from the contents of this {@link Builder}.
*/
@NonNull
public AppSearchBatchResult<KeyType, ValueType> build() {
mBuilt = true;
return new AppSearchBatchResult<>(mSuccesses, mFailures, mAll);
}
private void resetIfBuilt() {
if (mBuilt) {
mSuccesses = new ArrayMap<>(mSuccesses);
mFailures = new ArrayMap<>(mFailures);
mAll = new ArrayMap<>(mAll);
mBuilt = false;
}
}
}
}