• 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 
17 package android.app.appsearch;
18 
19 import android.annotation.NonNull;
20 import android.app.appsearch.annotation.CanIgnoreReturnValue;
21 import android.util.ArrayMap;
22 import android.util.ArraySet;
23 
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.Set;
32 
33 /**
34  * Encapsulates a request to retrieve documents by namespace and IDs from the {@link
35  * AppSearchSession} database.
36  *
37  * @see AppSearchSession#getByDocumentId
38  */
39 public final class GetByDocumentIdRequest {
40     /**
41      * Schema type to be used in {@link GetByDocumentIdRequest.Builder#addProjection} to apply
42      * property paths to all results, excepting any types that have had their own, specific property
43      * paths set.
44      */
45     public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
46 
47     private final String mNamespace;
48     private final Set<String> mIds;
49     private final Map<String, List<String>> mTypePropertyPathsMap;
50 
GetByDocumentIdRequest( @onNull String namespace, @NonNull Set<String> ids, @NonNull Map<String, List<String>> typePropertyPathsMap)51     GetByDocumentIdRequest(
52             @NonNull String namespace,
53             @NonNull Set<String> ids,
54             @NonNull Map<String, List<String>> typePropertyPathsMap) {
55         mNamespace = Objects.requireNonNull(namespace);
56         mIds = Objects.requireNonNull(ids);
57         mTypePropertyPathsMap = Objects.requireNonNull(typePropertyPathsMap);
58     }
59 
60     /** Returns the namespace attached to the request. */
61     @NonNull
getNamespace()62     public String getNamespace() {
63         return mNamespace;
64     }
65 
66     /** Returns the set of document IDs attached to the request. */
67     @NonNull
getIds()68     public Set<String> getIds() {
69         return Collections.unmodifiableSet(mIds);
70     }
71 
72     /**
73      * Returns a map from schema type to property paths to be used for projection.
74      *
75      * <p>If the map is empty, then all properties will be retrieved for all results.
76      *
77      * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
78      * function, rather than calling it multiple times.
79      */
80     @NonNull
getProjections()81     public Map<String, List<String>> getProjections() {
82         Map<String, List<String>> copy = new ArrayMap<>();
83         for (Map.Entry<String, List<String>> entry : mTypePropertyPathsMap.entrySet()) {
84             copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
85         }
86         return copy;
87     }
88 
89     /**
90      * Returns a map from schema type to property paths to be used for projection.
91      *
92      * <p>If the map is empty, then all properties will be retrieved for all results.
93      *
94      * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
95      * function, rather than calling it multiple times.
96      */
97     @NonNull
getProjectionPaths()98     public Map<String, List<PropertyPath>> getProjectionPaths() {
99         Map<String, List<PropertyPath>> copy = new ArrayMap<>(mTypePropertyPathsMap.size());
100         for (Map.Entry<String, List<String>> entry : mTypePropertyPathsMap.entrySet()) {
101             List<PropertyPath> propertyPathList = new ArrayList<>(entry.getValue().size());
102             for (String p : entry.getValue()) {
103                 propertyPathList.add(new PropertyPath(p));
104             }
105             copy.put(entry.getKey(), propertyPathList);
106         }
107         return copy;
108     }
109 
110     /**
111      * Returns a map from schema type to property paths to be used for projection.
112      *
113      * <p>If the map is empty, then all properties will be retrieved for all results.
114      *
115      * <p>A more efficient version of {@link #getProjections}, but it returns a modifiable map. This
116      * is not meant to be unhidden and should only be used by internal classes.
117      *
118      * @hide
119      */
120     @NonNull
getProjectionsInternal()121     public Map<String, List<String>> getProjectionsInternal() {
122         return mTypePropertyPathsMap;
123     }
124 
125     /** Builder for {@link GetByDocumentIdRequest} objects. */
126     public static final class Builder {
127         private final String mNamespace;
128         private ArraySet<String> mIds = new ArraySet<>();
129         private ArrayMap<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
130         private boolean mBuilt = false;
131 
132         /** Creates a {@link GetByDocumentIdRequest.Builder} instance. */
Builder(@onNull String namespace)133         public Builder(@NonNull String namespace) {
134             mNamespace = Objects.requireNonNull(namespace);
135         }
136 
137         /** Adds one or more document IDs to the request. */
138         @CanIgnoreReturnValue
139         @NonNull
addIds(@onNull String... ids)140         public Builder addIds(@NonNull String... ids) {
141             Objects.requireNonNull(ids);
142             resetIfBuilt();
143             return addIds(Arrays.asList(ids));
144         }
145 
146         /** Adds a collection of IDs to the request. */
147         @CanIgnoreReturnValue
148         @NonNull
addIds(@onNull Collection<String> ids)149         public Builder addIds(@NonNull Collection<String> ids) {
150             Objects.requireNonNull(ids);
151             resetIfBuilt();
152             mIds.addAll(ids);
153             return this;
154         }
155 
156         /**
157          * Adds property paths for the specified type to be used for projection. If property paths
158          * are added for a type, then only the properties referred to will be retrieved for results
159          * of that type. If a property path that is specified isn't present in a result, it will be
160          * ignored for that result. Property paths cannot be null.
161          *
162          * <p>If no property paths are added for a particular type, then all properties of results
163          * of that type will be retrieved.
164          *
165          * <p>If property path is added for the {@link
166          * GetByDocumentIdRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will
167          * apply to all results, excepting any types that have their own, specific property paths
168          * set.
169          *
170          * @see SearchSpec.Builder#addProjectionPaths
171          */
172         @CanIgnoreReturnValue
173         @NonNull
addProjection( @onNull String schemaType, @NonNull Collection<String> propertyPaths)174         public Builder addProjection(
175                 @NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
176             Objects.requireNonNull(schemaType);
177             Objects.requireNonNull(propertyPaths);
178             resetIfBuilt();
179             List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
180             for (String propertyPath : propertyPaths) {
181                 Objects.requireNonNull(propertyPath);
182                 propertyPathsList.add(propertyPath);
183             }
184             mProjectionTypePropertyPaths.put(schemaType, propertyPathsList);
185             return this;
186         }
187 
188         /**
189          * Adds property paths for the specified type to be used for projection. If property paths
190          * are added for a type, then only the properties referred to will be retrieved for results
191          * of that type. If a property path that is specified isn't present in a result, it will be
192          * ignored for that result. Property paths cannot be null.
193          *
194          * <p>If no property paths are added for a particular type, then all properties of results
195          * of that type will be retrieved.
196          *
197          * <p>If property path is added for the {@link
198          * GetByDocumentIdRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will
199          * apply to all results, excepting any types that have their own, specific property paths
200          * set.
201          *
202          * @see SearchSpec.Builder#addProjectionPaths
203          */
204         @CanIgnoreReturnValue
205         @NonNull
addProjectionPaths( @onNull String schemaType, @NonNull Collection<PropertyPath> propertyPaths)206         public Builder addProjectionPaths(
207                 @NonNull String schemaType, @NonNull Collection<PropertyPath> propertyPaths) {
208             Objects.requireNonNull(schemaType);
209             Objects.requireNonNull(propertyPaths);
210             List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
211             for (PropertyPath propertyPath : propertyPaths) {
212                 propertyPathsList.add(propertyPath.toString());
213             }
214             return addProjection(schemaType, propertyPathsList);
215         }
216 
217         /** Builds a new {@link GetByDocumentIdRequest}. */
218         @NonNull
build()219         public GetByDocumentIdRequest build() {
220             mBuilt = true;
221             return new GetByDocumentIdRequest(mNamespace, mIds, mProjectionTypePropertyPaths);
222         }
223 
resetIfBuilt()224         private void resetIfBuilt() {
225             if (mBuilt) {
226                 mIds = new ArraySet<>(mIds);
227                 // No need to clone each propertyPathsList inside mProjectionTypePropertyPaths since
228                 // the builder only replaces it, never adds to it. So even if the builder is used
229                 // again, the previous one will remain with the object.
230                 mProjectionTypePropertyPaths = new ArrayMap<>(mProjectionTypePropertyPaths);
231                 mBuilt = false;
232             }
233         }
234     }
235 }
236