Sync AppSearch from framework.
Contains changes: * 37a4e9: Split indexing configs into per-type configs. * 69d6e3: Add projection to the Get api. Bug: 175039682 Bug: 177572431 Bug: 171857731 Test: Presubmit Change-Id: Ida457b2d617be6e85557023bfb4716ad78c8db6c
This commit is contained in:
@@ -43,6 +43,15 @@ package android.app.appsearch {
|
||||
method @IntRange(from=0) public int getVersion();
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.BooleanPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.BooleanPropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.BooleanPropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.BooleanPropertyConfig.Builder setCardinality(int);
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.Builder {
|
||||
ctor public AppSearchSchema.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.Builder addProperty(@NonNull android.app.appsearch.AppSearchSchema.PropertyConfig);
|
||||
@@ -50,22 +59,58 @@ package android.app.appsearch {
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.Builder setVersion(@IntRange(from=0) int);
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.PropertyConfig {
|
||||
public static final class AppSearchSchema.BytesPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.BytesPropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.BytesPropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.BytesPropertyConfig.Builder setCardinality(int);
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.DocumentPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
method @NonNull public String getSchemaType();
|
||||
method public boolean isIndexNestedProperties();
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.DocumentPropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.DocumentPropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setCardinality(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setIndexNestedProperties(boolean);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DocumentPropertyConfig.Builder setSchemaType(@NonNull String);
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.DoublePropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.DoublePropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.DoublePropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.DoublePropertyConfig.Builder setCardinality(int);
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.Int64PropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.Int64PropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.Int64PropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.Int64PropertyConfig.Builder setCardinality(int);
|
||||
}
|
||||
|
||||
public abstract static class AppSearchSchema.PropertyConfig {
|
||||
method public int getCardinality();
|
||||
method public int getDataType();
|
||||
method public int getIndexingType();
|
||||
method @NonNull public String getName();
|
||||
method @Nullable public String getSchemaType();
|
||||
method public int getTokenizerType();
|
||||
field public static final int CARDINALITY_OPTIONAL = 2; // 0x2
|
||||
field public static final int CARDINALITY_REPEATED = 1; // 0x1
|
||||
field public static final int CARDINALITY_REQUIRED = 3; // 0x3
|
||||
field public static final int DATA_TYPE_BOOLEAN = 4; // 0x4
|
||||
field public static final int DATA_TYPE_BYTES = 5; // 0x5
|
||||
field public static final int DATA_TYPE_DOCUMENT = 6; // 0x6
|
||||
field public static final int DATA_TYPE_DOUBLE = 3; // 0x3
|
||||
field public static final int DATA_TYPE_INT64 = 2; // 0x2
|
||||
field public static final int DATA_TYPE_STRING = 1; // 0x1
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.StringPropertyConfig extends android.app.appsearch.AppSearchSchema.PropertyConfig {
|
||||
method public int getIndexingType();
|
||||
method public int getTokenizerType();
|
||||
field public static final int INDEXING_TYPE_EXACT_TERMS = 1; // 0x1
|
||||
field public static final int INDEXING_TYPE_NONE = 0; // 0x0
|
||||
field public static final int INDEXING_TYPE_PREFIXES = 2; // 0x2
|
||||
@@ -73,14 +118,12 @@ package android.app.appsearch {
|
||||
field public static final int TOKENIZER_TYPE_PLAIN = 1; // 0x1
|
||||
}
|
||||
|
||||
public static final class AppSearchSchema.PropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.PropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setCardinality(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setDataType(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setIndexingType(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setSchemaType(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.PropertyConfig.Builder setTokenizerType(int);
|
||||
public static final class AppSearchSchema.StringPropertyConfig.Builder {
|
||||
ctor public AppSearchSchema.StringPropertyConfig.Builder(@NonNull String);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig build();
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setCardinality(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setIndexingType(int);
|
||||
method @NonNull public android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder setTokenizerType(int);
|
||||
}
|
||||
|
||||
public final class AppSearchSession implements java.io.Closeable {
|
||||
@@ -143,11 +186,15 @@ package android.app.appsearch {
|
||||
|
||||
public final class GetByUriRequest {
|
||||
method @NonNull public String getNamespace();
|
||||
method @NonNull public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getProjections();
|
||||
method @NonNull public java.util.Set<java.lang.String> getUris();
|
||||
field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
|
||||
}
|
||||
|
||||
public static final class GetByUriRequest.Builder {
|
||||
ctor public GetByUriRequest.Builder();
|
||||
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addProjection(@NonNull String, @NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.lang.String...);
|
||||
method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
|
||||
method @NonNull public android.app.appsearch.GetByUriRequest build();
|
||||
|
||||
@@ -330,6 +330,7 @@ public class AppSearchManager {
|
||||
DEFAULT_DATABASE_NAME,
|
||||
request.getNamespace(),
|
||||
uris,
|
||||
request.getProjectionsVisibleToPackagesInternal(),
|
||||
mContext.getUserId(),
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
|
||||
@@ -311,8 +311,13 @@ public final class AppSearchSession implements Closeable {
|
||||
Objects.requireNonNull(callback);
|
||||
Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
|
||||
try {
|
||||
mService.getDocuments(mPackageName, mDatabaseName, request.getNamespace(),
|
||||
new ArrayList<>(request.getUris()), mUserId,
|
||||
mService.getDocuments(
|
||||
mPackageName,
|
||||
mDatabaseName,
|
||||
request.getNamespace(),
|
||||
new ArrayList<>(request.getUris()),
|
||||
request.getProjectionsVisibleToPackagesInternal(),
|
||||
mUserId,
|
||||
new IAppSearchBatchResultCallback.Stub() {
|
||||
public void onResult(AppSearchBatchResult result) {
|
||||
executor.execute(() -> {
|
||||
|
||||
@@ -97,6 +97,8 @@ interface IAppSearchManager {
|
||||
* @param databaseName The databaseName this document resides in.
|
||||
* @param namespace The namespace this document resides in.
|
||||
* @param uris The URIs of the documents to retrieve
|
||||
* @param typePropertyPaths A map of schema type to a list of property paths to return in the
|
||||
* result.
|
||||
* @param userId Id of the calling user
|
||||
* @param callback
|
||||
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
|
||||
@@ -110,6 +112,7 @@ interface IAppSearchManager {
|
||||
in String databaseName,
|
||||
in String namespace,
|
||||
in List<String> uris,
|
||||
in Map<String, List<String>> typePropertyPaths,
|
||||
in int userId,
|
||||
in IAppSearchBatchResultCallback callback);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.app.appsearch;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.appsearch.AppSearchSchema.PropertyConfig;
|
||||
import android.app.appsearch.AppSearchSchema.StringPropertyConfig;
|
||||
|
||||
/**
|
||||
* Encapsulates a {@link GenericDocument} that represent an email.
|
||||
@@ -41,46 +42,40 @@ public class AppSearchEmail extends GenericDocument {
|
||||
public static final AppSearchSchema SCHEMA =
|
||||
new AppSearchSchema.Builder(SCHEMA_TYPE)
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_FROM)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_FROM)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_TO)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_TO)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_CC)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_CC)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_BCC)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_BCC)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_SUBJECT)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_SUBJECT)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new PropertyConfig.Builder(KEY_BODY)
|
||||
.setDataType(PropertyConfig.DATA_TYPE_STRING)
|
||||
new StringPropertyConfig.Builder(KEY_BODY)
|
||||
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public final class AppSearchSchema {
|
||||
}
|
||||
List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
|
||||
for (int i = 0; i < propertyBundles.size(); i++) {
|
||||
ret.add(new PropertyConfig(propertyBundles.get(i)));
|
||||
ret.add(PropertyConfig.fromBundle(propertyBundles.get(i)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -210,18 +210,15 @@ public final class AppSearchSchema {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for a single property (field) of a document type.
|
||||
* Common configuration for a single property (field) in a Document.
|
||||
*
|
||||
* <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be a
|
||||
* property.
|
||||
*/
|
||||
public static final class PropertyConfig {
|
||||
private static final String NAME_FIELD = "name";
|
||||
private static final String DATA_TYPE_FIELD = "dataType";
|
||||
private static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
private static final String CARDINALITY_FIELD = "cardinality";
|
||||
private static final String INDEXING_TYPE_FIELD = "indexingType";
|
||||
private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
|
||||
public abstract static class PropertyConfig {
|
||||
static final String NAME_FIELD = "name";
|
||||
static final String DATA_TYPE_FIELD = "dataType";
|
||||
static final String CARDINALITY_FIELD = "cardinality";
|
||||
|
||||
/**
|
||||
* Physical data-types of the contents of the property.
|
||||
@@ -242,18 +239,31 @@ public final class AppSearchSchema {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DataType {}
|
||||
|
||||
/** @hide */
|
||||
public static final int DATA_TYPE_STRING = 1;
|
||||
|
||||
/** @hide */
|
||||
public static final int DATA_TYPE_INT64 = 2;
|
||||
|
||||
/** @hide */
|
||||
public static final int DATA_TYPE_DOUBLE = 3;
|
||||
|
||||
/** @hide */
|
||||
public static final int DATA_TYPE_BOOLEAN = 4;
|
||||
|
||||
/** Unstructured BLOB. */
|
||||
/**
|
||||
* Unstructured BLOB.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int DATA_TYPE_BYTES = 5;
|
||||
|
||||
/**
|
||||
* Indicates that the property is itself a {@link GenericDocument}, making it part of a
|
||||
* hierarchical schema. Any property using this DataType MUST have a valid {@link
|
||||
* PropertyConfig#getSchemaType}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int DATA_TYPE_DOCUMENT = 6;
|
||||
|
||||
@@ -282,6 +292,97 @@ public final class AppSearchSchema {
|
||||
/** Exactly one value [1]. */
|
||||
public static final int CARDINALITY_REQUIRED = 3;
|
||||
|
||||
final Bundle mBundle;
|
||||
|
||||
@Nullable private Integer mHashCode;
|
||||
|
||||
PropertyConfig(@NonNull Bundle bundle) {
|
||||
mBundle = Preconditions.checkNotNull(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mBundle.toString();
|
||||
}
|
||||
|
||||
/** Returns the name of this property. */
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return mBundle.getString(NAME_FIELD, "");
|
||||
}
|
||||
|
||||
/** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
|
||||
public @DataType int getDataType() {
|
||||
return mBundle.getInt(DATA_TYPE_FIELD, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cardinality of the property (whether it is optional, required or repeated).
|
||||
*/
|
||||
public @Cardinality int getCardinality() {
|
||||
return mBundle.getInt(CARDINALITY_FIELD, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof PropertyConfig)) {
|
||||
return false;
|
||||
}
|
||||
PropertyConfig otherProperty = (PropertyConfig) other;
|
||||
return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (mHashCode == null) {
|
||||
mHashCode = BundleUtil.deepHashCode(mBundle);
|
||||
}
|
||||
return mHashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link Bundle} into a {@link PropertyConfig} depending on its internal data
|
||||
* type.
|
||||
*
|
||||
* <p>The bundle is not cloned.
|
||||
*
|
||||
* @throws IllegalArgumentException if the bundle does no contain a recognized value in its
|
||||
* {@code DATA_TYPE_FIELD}.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public static PropertyConfig fromBundle(@NonNull Bundle propertyBundle) {
|
||||
switch (propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)) {
|
||||
case PropertyConfig.DATA_TYPE_STRING:
|
||||
return new StringPropertyConfig(propertyBundle);
|
||||
case PropertyConfig.DATA_TYPE_INT64:
|
||||
return new Int64PropertyConfig(propertyBundle);
|
||||
case PropertyConfig.DATA_TYPE_DOUBLE:
|
||||
return new DoublePropertyConfig(propertyBundle);
|
||||
case PropertyConfig.DATA_TYPE_BOOLEAN:
|
||||
return new BooleanPropertyConfig(propertyBundle);
|
||||
case PropertyConfig.DATA_TYPE_BYTES:
|
||||
return new BytesPropertyConfig(propertyBundle);
|
||||
case PropertyConfig.DATA_TYPE_DOCUMENT:
|
||||
return new DocumentPropertyConfig(propertyBundle);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported property bundle of type "
|
||||
+ propertyBundle.getInt(PropertyConfig.DATA_TYPE_FIELD)
|
||||
+ "; contents: "
|
||||
+ propertyBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property of type String in a Document. */
|
||||
public static final class StringPropertyConfig extends PropertyConfig {
|
||||
private static final String INDEXING_TYPE_FIELD = "indexingType";
|
||||
private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
|
||||
|
||||
/**
|
||||
* Encapsulates the configurations on how AppSearch should query/index these terms.
|
||||
*
|
||||
@@ -296,14 +397,7 @@ public final class AppSearchSchema {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface IndexingType {}
|
||||
|
||||
/**
|
||||
* Content in this property will not be tokenized or indexed.
|
||||
*
|
||||
* <p>Useful if the data type is not made up of terms (e.g. {@link
|
||||
* PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES} type). None
|
||||
* of the properties inside the nested property will be indexed regardless of the value of
|
||||
* {@code indexingType} for the nested properties.
|
||||
*/
|
||||
/** Content in this property will not be tokenized or indexed. */
|
||||
public static final int INDEXING_TYPE_NONE = 0;
|
||||
|
||||
/**
|
||||
@@ -338,54 +432,16 @@ public final class AppSearchSchema {
|
||||
public @interface TokenizerType {}
|
||||
|
||||
/**
|
||||
* It is only valid for tokenizer_type to be 'NONE' if the data type is {@link
|
||||
* PropertyConfig#DATA_TYPE_DOCUMENT}.
|
||||
* It is only valid for tokenizer_type to be 'NONE' if {@link #getIndexingType} is {@link
|
||||
* #INDEXING_TYPE_NONE}.
|
||||
*/
|
||||
public static final int TOKENIZER_TYPE_NONE = 0;
|
||||
|
||||
/** Tokenization for plain text. */
|
||||
public static final int TOKENIZER_TYPE_PLAIN = 1;
|
||||
|
||||
final Bundle mBundle;
|
||||
|
||||
@Nullable private Integer mHashCode;
|
||||
|
||||
PropertyConfig(@NonNull Bundle bundle) {
|
||||
mBundle = Preconditions.checkNotNull(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mBundle.toString();
|
||||
}
|
||||
|
||||
/** Returns the name of this property. */
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return mBundle.getString(NAME_FIELD, "");
|
||||
}
|
||||
|
||||
/** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
|
||||
public @DataType int getDataType() {
|
||||
return mBundle.getInt(DATA_TYPE_FIELD, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the logical schema-type of the contents of this property.
|
||||
*
|
||||
* <p>Only set when {@link #getDataType} is set to {@link #DATA_TYPE_DOCUMENT}. Otherwise,
|
||||
* it is {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
public String getSchemaType() {
|
||||
return mBundle.getString(SCHEMA_TYPE_FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cardinality of the property (whether it is optional, required or repeated).
|
||||
*/
|
||||
public @Cardinality int getCardinality() {
|
||||
return mBundle.getInt(CARDINALITY_FIELD, -1);
|
||||
StringPropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/** Returns how the property is indexed. */
|
||||
@@ -398,75 +454,19 @@ public final class AppSearchSchema {
|
||||
return mBundle.getInt(TOKENIZER_TYPE_FIELD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof PropertyConfig)) {
|
||||
return false;
|
||||
}
|
||||
PropertyConfig otherProperty = (PropertyConfig) other;
|
||||
return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (mHashCode == null) {
|
||||
mHashCode = BundleUtil.deepHashCode(mBundle);
|
||||
}
|
||||
return mHashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link PropertyConfig}.
|
||||
* Builder for {@link StringPropertyConfig}.
|
||||
*
|
||||
* <p>The following properties must be set, or {@link PropertyConfig} construction will
|
||||
* fail:
|
||||
*
|
||||
* <ul>
|
||||
* <li>dataType
|
||||
* <li>cardinality
|
||||
* </ul>
|
||||
*
|
||||
* <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
|
||||
* is also required.
|
||||
* <p>{@link #setCardinality} must be called or {@link #build} will fail.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link PropertyConfig.Builder}. */
|
||||
/** Creates a new {@link StringPropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of data the property contains (e.g. string, int, bytes, etc).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@NonNull
|
||||
public PropertyConfig.Builder setDataType(@DataType int dataType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
dataType, DATA_TYPE_STRING, DATA_TYPE_DOCUMENT, "dataType");
|
||||
mBundle.putInt(DATA_TYPE_FIELD, dataType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical schema-type of the contents of this property.
|
||||
*
|
||||
* <p>Only required when {@link #setDataType} is set to {@link #DATA_TYPE_DOCUMENT}.
|
||||
* Otherwise, it is ignored.
|
||||
*/
|
||||
@NonNull
|
||||
public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(schemaType);
|
||||
mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
|
||||
return this;
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,8 +474,9 @@ public final class AppSearchSchema {
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
public StringPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
@@ -487,7 +488,7 @@ public final class AppSearchSchema {
|
||||
* Configures how a property should be indexed so that it can be retrieved by queries.
|
||||
*/
|
||||
@NonNull
|
||||
public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
|
||||
public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
|
||||
@@ -497,7 +498,7 @@ public final class AppSearchSchema {
|
||||
|
||||
/** Configures how this property should be tokenized (split into words). */
|
||||
@NonNull
|
||||
public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
|
||||
public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
|
||||
@@ -505,6 +506,337 @@ public final class AppSearchSchema {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link StringPropertyConfig} from the contents of this builder.
|
||||
*
|
||||
* <p>After calling this method, the builder must no longer be used.
|
||||
*
|
||||
* @throws IllegalSchemaException if the property is not correctly populated
|
||||
*/
|
||||
@NonNull
|
||||
public StringPropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
// TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
|
||||
// of partially reimplementing some of the validation Icing does here.
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new StringPropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property containing a 64-bit integer. */
|
||||
public static final class Int64PropertyConfig extends PropertyConfig {
|
||||
Int64PropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link Int64PropertyConfig}.
|
||||
*
|
||||
* <p>{@link #setCardinality} must be called or {@link #build} will fail.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link Int64PropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_INT64);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cardinality of the property (whether it is optional, required or repeated).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public Int64PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
mBundle.putInt(CARDINALITY_FIELD, cardinality);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Int64PropertyConfig} from the contents of this builder.
|
||||
*
|
||||
* <p>After calling this method, the builder must no longer be used.
|
||||
*
|
||||
* @throws IllegalSchemaException if the property is not correctly populated
|
||||
*/
|
||||
@NonNull
|
||||
public Int64PropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new Int64PropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property containing a double-precision decimal number. */
|
||||
public static final class DoublePropertyConfig extends PropertyConfig {
|
||||
DoublePropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link DoublePropertyConfig}.
|
||||
*
|
||||
* <p>{@link #setCardinality} must be called or {@link #build} will fail.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link DoublePropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cardinality of the property (whether it is optional, required or repeated).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public DoublePropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
mBundle.putInt(CARDINALITY_FIELD, cardinality);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link DoublePropertyConfig} from the contents of this builder.
|
||||
*
|
||||
* <p>After calling this method, the builder must no longer be used.
|
||||
*
|
||||
* @throws IllegalSchemaException if the property is not correctly populated
|
||||
*/
|
||||
@NonNull
|
||||
public DoublePropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new DoublePropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property containing a boolean. */
|
||||
public static final class BooleanPropertyConfig extends PropertyConfig {
|
||||
BooleanPropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link BooleanPropertyConfig}.
|
||||
*
|
||||
* <p>{@link #setCardinality} must be called or {@link #build} will fail.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link BooleanPropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BOOLEAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cardinality of the property (whether it is optional, required or repeated).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public BooleanPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
mBundle.putInt(CARDINALITY_FIELD, cardinality);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link BooleanPropertyConfig} from the contents of this builder.
|
||||
*
|
||||
* <p>After calling this method, the builder must no longer be used.
|
||||
*
|
||||
* @throws IllegalSchemaException if the property is not correctly populated
|
||||
*/
|
||||
@NonNull
|
||||
public BooleanPropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new BooleanPropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property containing a byte array. */
|
||||
public static final class BytesPropertyConfig extends PropertyConfig {
|
||||
BytesPropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link BytesPropertyConfig}.
|
||||
*
|
||||
* <p>{@link #setCardinality} must be called or {@link #build} will fail.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link BytesPropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_BYTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cardinality of the property (whether it is optional, required or repeated).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public BytesPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
mBundle.putInt(CARDINALITY_FIELD, cardinality);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link BytesPropertyConfig} from the contents of this builder.
|
||||
*
|
||||
* <p>After calling this method, the builder must no longer be used.
|
||||
*
|
||||
* @throws IllegalSchemaException if the property is not correctly populated
|
||||
*/
|
||||
@NonNull
|
||||
public BytesPropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new BytesPropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for a property containing another Document. */
|
||||
public static final class DocumentPropertyConfig extends PropertyConfig {
|
||||
private static final String SCHEMA_TYPE_FIELD = "schemaType";
|
||||
private static final String INDEX_NESTED_PROPERTIES_FIELD = "indexNestedProperties";
|
||||
|
||||
DocumentPropertyConfig(@NonNull Bundle bundle) {
|
||||
super(bundle);
|
||||
}
|
||||
|
||||
/** Returns the logical schema-type of the contents of this document property. */
|
||||
@NonNull
|
||||
public String getSchemaType() {
|
||||
return Preconditions.checkNotNull(mBundle.getString(SCHEMA_TYPE_FIELD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether fields in the nested document should be indexed according to that
|
||||
* document's schema.
|
||||
*
|
||||
* <p>If false, the nested document's properties are not indexed regardless of its own
|
||||
* schema.
|
||||
*/
|
||||
public boolean isIndexNestedProperties() {
|
||||
return mBundle.getBoolean(INDEX_NESTED_PROPERTIES_FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link DocumentPropertyConfig}.
|
||||
*
|
||||
* <p>The following properties must be set, or {@link DocumentPropertyConfig} construction
|
||||
* will fail:
|
||||
*
|
||||
* <ul>
|
||||
* <li>cardinality
|
||||
* <li>schemaType
|
||||
* </ul>
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/** Creates a new {@link DocumentPropertyConfig.Builder}. */
|
||||
public Builder(@NonNull String propertyName) {
|
||||
mBundle.putString(NAME_FIELD, propertyName);
|
||||
mBundle.putInt(DATA_TYPE_FIELD, DATA_TYPE_DOCUMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical schema-type of the contents of this property.
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@NonNull
|
||||
public DocumentPropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(schemaType);
|
||||
mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cardinality of the property (whether it is optional, required or repeated).
|
||||
*
|
||||
* <p>This property must be set.
|
||||
*/
|
||||
@SuppressWarnings("MissingGetterMatchingBuilder") // getter defined in superclass
|
||||
@NonNull
|
||||
public DocumentPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkArgumentInRange(
|
||||
cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
|
||||
mBundle.putInt(CARDINALITY_FIELD, cardinality);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures whether fields in the nested document should be indexed according to that
|
||||
* document's schema.
|
||||
*
|
||||
* <p>If false, the nested document's properties are not indexed regardless of its own
|
||||
* schema.
|
||||
*/
|
||||
@NonNull
|
||||
public DocumentPropertyConfig.Builder setIndexNestedProperties(
|
||||
boolean indexNestedProperties) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mBundle.putBoolean(INDEX_NESTED_PROPERTIES_FIELD, indexNestedProperties);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link PropertyConfig} from the contents of this builder.
|
||||
*
|
||||
@@ -514,24 +846,16 @@ public final class AppSearchSchema {
|
||||
* missing {@code dataType}).
|
||||
*/
|
||||
@NonNull
|
||||
public PropertyConfig build() {
|
||||
public DocumentPropertyConfig build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
// TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
|
||||
// of partially reimplementing some of the validation Icing does here.
|
||||
if (!mBundle.containsKey(DATA_TYPE_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: dataType");
|
||||
}
|
||||
if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()
|
||||
&& mBundle.getInt(DATA_TYPE_FIELD) == DATA_TYPE_DOCUMENT) {
|
||||
throw new IllegalSchemaException(
|
||||
"Missing field: schemaType (required for configs with "
|
||||
+ "dataType = DOCUMENT)");
|
||||
if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()) {
|
||||
throw new IllegalSchemaException("Missing field: schemaType");
|
||||
}
|
||||
if (!mBundle.containsKey(CARDINALITY_FIELD)) {
|
||||
throw new IllegalSchemaException("Missing field: cardinality");
|
||||
}
|
||||
mBuilt = true;
|
||||
return new PropertyConfig(mBundle);
|
||||
return new DocumentPropertyConfig(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ public class GenericDocument {
|
||||
/**
|
||||
* The maximum number of indexed properties a document can have.
|
||||
*
|
||||
* <p>Indexed properties are properties where the {@link
|
||||
* AppSearchSchema.PropertyConfig#getIndexingType()} constant is anything other than {@link
|
||||
* AppSearchSchema.PropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
|
||||
* <p>Indexed properties are properties which are strings where the {@link
|
||||
* AppSearchSchema.StringPropertyConfig#getIndexingType} value is anything other than {@link
|
||||
* AppSearchSchema.StringPropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
|
||||
*/
|
||||
public static int getMaxIndexedProperties() {
|
||||
return MAX_INDEXED_PROPERTIES;
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
package android.app.appsearch;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -32,12 +36,24 @@ import java.util.Set;
|
||||
* @see AppSearchSession#getByUri
|
||||
*/
|
||||
public final class GetByUriRequest {
|
||||
/**
|
||||
* Schema type to be used in {@link android.app.appsearch.GetByUriRequest.Builder#addProjection}
|
||||
* to apply property paths to all results, excepting any types that have had their own, specific
|
||||
* property paths set.
|
||||
*/
|
||||
public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
|
||||
|
||||
private final String mNamespace;
|
||||
private final Set<String> mUris;
|
||||
private final Map<String, List<String>> mTypePropertyPathsMap;
|
||||
|
||||
GetByUriRequest(@NonNull String namespace, @NonNull Set<String> uris) {
|
||||
mNamespace = namespace;
|
||||
mUris = uris;
|
||||
GetByUriRequest(
|
||||
@NonNull String namespace,
|
||||
@NonNull Set<String> uris,
|
||||
@NonNull Map<String, List<String>> typePropertyPathsMap) {
|
||||
mNamespace = Preconditions.checkNotNull(namespace);
|
||||
mUris = Preconditions.checkNotNull(uris);
|
||||
mTypePropertyPathsMap = Preconditions.checkNotNull(typePropertyPathsMap);
|
||||
}
|
||||
|
||||
/** Returns the namespace to get documents from. */
|
||||
@@ -52,10 +68,43 @@ public final class GetByUriRequest {
|
||||
return Collections.unmodifiableSet(mUris);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map from schema type to property paths to be used for projection.
|
||||
*
|
||||
* <p>If the map is empty, then all properties will be retrieved for all results.
|
||||
*
|
||||
* <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned by this
|
||||
* function, rather than calling it multiple times.
|
||||
*/
|
||||
@NonNull
|
||||
public Map<String, List<String>> getProjections() {
|
||||
Map<String, List<String>> copy = new ArrayMap<>();
|
||||
for (String key : mTypePropertyPathsMap.keySet()) {
|
||||
copy.put(key, new ArrayList<>(mTypePropertyPathsMap.get(key)));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map from schema type to property paths to be used for projection.
|
||||
*
|
||||
* <p>If the map is empty, then all properties will be retrieved for all results.
|
||||
*
|
||||
* <p>A more efficient version of {@link #getProjections}, but it returns a modifiable map. This
|
||||
* is not meant to be unhidden and should only be used by internal classes.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Map<String, List<String>> getProjectionsVisibleToPackagesInternal() {
|
||||
return mTypePropertyPathsMap;
|
||||
}
|
||||
|
||||
/** Builder for {@link GetByUriRequest} objects. */
|
||||
public static final class Builder {
|
||||
private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
|
||||
private final Set<String> mUris = new ArraySet<>();
|
||||
private final Map<String, List<String>> mProjectionTypePropertyPaths = new ArrayMap<>();
|
||||
private boolean mBuilt = false;
|
||||
|
||||
/**
|
||||
@@ -87,12 +136,63 @@ public final class GetByUriRequest {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds property paths for the specified type to be used for projection. If property paths
|
||||
* are added for a type, then only the properties referred to will be retrieved for results
|
||||
* of that type. If a property path that is specified isn't present in a result, it will be
|
||||
* ignored for that result. Property paths cannot be null.
|
||||
*
|
||||
* <p>If no property paths are added for a particular type, then all properties of results
|
||||
* of that type will be retrieved.
|
||||
*
|
||||
* <p>If property path is added for the {@link
|
||||
* GetByUriRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will apply to
|
||||
* all results, excepting any types that have their own, specific property paths set.
|
||||
*
|
||||
* <p>{@see SearchSpec.Builder#addProjection(String, String...)}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addProjection(@NonNull String schemaType, @NonNull String... propertyPaths) {
|
||||
Preconditions.checkNotNull(propertyPaths);
|
||||
return addProjection(schemaType, Arrays.asList(propertyPaths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds property paths for the specified type to be used for projection. If property paths
|
||||
* are added for a type, then only the properties referred to will be retrieved for results
|
||||
* of that type. If a property path that is specified isn't present in a result, it will be
|
||||
* ignored for that result. Property paths cannot be null.
|
||||
*
|
||||
* <p>If no property paths are added for a particular type, then all properties of results
|
||||
* of that type will be retrieved.
|
||||
*
|
||||
* <p>If property path is added for the {@link
|
||||
* GetByUriRequest#PROJECTION_SCHEMA_TYPE_WILDCARD}, then those property paths will apply to
|
||||
* all results, excepting any types that have their own, specific property paths set.
|
||||
*
|
||||
* <p>{@see SearchSpec.Builder#addProjection(String, String...)}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addProjection(
|
||||
@NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
Preconditions.checkNotNull(schemaType);
|
||||
Preconditions.checkNotNull(propertyPaths);
|
||||
List<String> propertyPathsList = new ArrayList<>(propertyPaths.size());
|
||||
for (String propertyPath : propertyPaths) {
|
||||
Preconditions.checkNotNull(propertyPath);
|
||||
propertyPathsList.add(propertyPath);
|
||||
}
|
||||
mProjectionTypePropertyPaths.put(schemaType, propertyPathsList);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds a new {@link GetByUriRequest}. */
|
||||
@NonNull
|
||||
public GetByUriRequest build() {
|
||||
Preconditions.checkState(!mBuilt, "Builder has already been used");
|
||||
mBuilt = true;
|
||||
return new GetByUriRequest(mNamespace, mUris);
|
||||
return new GetByUriRequest(mNamespace, mUris, mProjectionTypePropertyPaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,7 @@ public class AppSearchManagerService extends SystemService {
|
||||
@NonNull String databaseName,
|
||||
@NonNull String namespace,
|
||||
@NonNull List<String> uris,
|
||||
@NonNull Map<String, List<String>> typePropertyPaths,
|
||||
@UserIdInt int userId,
|
||||
@NonNull IAppSearchBatchResultCallback callback) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
@@ -208,8 +209,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
for (int i = 0; i < uris.size(); i++) {
|
||||
String uri = uris.get(i);
|
||||
try {
|
||||
GenericDocument document =
|
||||
impl.getDocument(packageName, databaseName, namespace, uri);
|
||||
GenericDocument document = impl.getDocument(packageName, databaseName,
|
||||
namespace, uri, typePropertyPaths);
|
||||
resultBuilder.setSuccess(uri, document.getBundle());
|
||||
} catch (Throwable t) {
|
||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.WorkerThread;
|
||||
import android.app.appsearch.AppSearchResult;
|
||||
import android.app.appsearch.AppSearchSchema;
|
||||
import android.app.appsearch.GenericDocument;
|
||||
import android.app.appsearch.GetByUriRequest;
|
||||
import android.app.appsearch.PackageIdentifier;
|
||||
import android.app.appsearch.SearchResultPage;
|
||||
import android.app.appsearch.SearchSpec;
|
||||
@@ -38,6 +39,7 @@ import com.android.server.appsearch.external.localstorage.converter.GenericDocum
|
||||
import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
|
||||
|
||||
import com.google.android.icing.IcingSearchEngine;
|
||||
import com.google.android.icing.proto.DeleteByQueryResultProto;
|
||||
@@ -428,6 +430,8 @@ public final class AppSearchImpl {
|
||||
* @param databaseName The databaseName this document resides in.
|
||||
* @param namespace The namespace this document resides in.
|
||||
* @param uri The URI of the document to get.
|
||||
* @param typePropertyPaths A map of schema type to a list of property paths to return in the
|
||||
* result.
|
||||
* @return The Document contents
|
||||
* @throws AppSearchException on IcingSearchEngine error.
|
||||
*/
|
||||
@@ -436,16 +440,35 @@ public final class AppSearchImpl {
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String namespace,
|
||||
@NonNull String uri)
|
||||
@NonNull String uri,
|
||||
@NonNull Map<String, List<String>> typePropertyPaths)
|
||||
throws AppSearchException {
|
||||
GetResultProto getResultProto;
|
||||
List<TypePropertyMask> nonPrefixedPropertyMasks =
|
||||
TypePropertyPathToProtoConverter.toTypePropertyMaskList(typePropertyPaths);
|
||||
List<TypePropertyMask> prefixedPropertyMasks =
|
||||
new ArrayList<>(nonPrefixedPropertyMasks.size());
|
||||
for (int i = 0; i < nonPrefixedPropertyMasks.size(); ++i) {
|
||||
TypePropertyMask typePropertyMask = nonPrefixedPropertyMasks.get(i);
|
||||
String nonPrefixedType = typePropertyMask.getSchemaType();
|
||||
String prefixedType =
|
||||
nonPrefixedType.equals(GetByUriRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
|
||||
? nonPrefixedType
|
||||
: createPrefix(packageName, databaseName) + nonPrefixedType;
|
||||
prefixedPropertyMasks.add(
|
||||
typePropertyMask.toBuilder().setSchemaType(prefixedType).build());
|
||||
}
|
||||
GetResultSpecProto getResultSpec =
|
||||
GetResultSpecProto.newBuilder()
|
||||
.addAllTypePropertyMasks(prefixedPropertyMasks)
|
||||
.build();
|
||||
mReadWriteLock.readLock().lock();
|
||||
try {
|
||||
getResultProto =
|
||||
mIcingSearchEngineLocked.get(
|
||||
createPrefix(packageName, databaseName) + namespace,
|
||||
uri,
|
||||
GetResultSpecProto.getDefaultInstance());
|
||||
getResultSpec);
|
||||
} finally {
|
||||
mReadWriteLock.readLock().unlock();
|
||||
}
|
||||
|
||||
@@ -85,15 +85,14 @@ class VisibilityStore {
|
||||
private static final AppSearchSchema VISIBILITY_SCHEMA =
|
||||
new AppSearchSchema.Builder(VISIBILITY_TYPE)
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder(
|
||||
new AppSearchSchema.StringPropertyConfig.Builder(
|
||||
NOT_PLATFORM_SURFACEABLE_PROPERTY)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.build())
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder(PACKAGE_ACCESSIBLE_PROPERTY)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT)
|
||||
new AppSearchSchema.DocumentPropertyConfig.Builder(
|
||||
PACKAGE_ACCESSIBLE_PROPERTY)
|
||||
.setSchemaType(PACKAGE_ACCESSIBLE_TYPE)
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
@@ -107,22 +106,20 @@ class VisibilityStore {
|
||||
private static final AppSearchSchema PACKAGE_ACCESSIBLE_SCHEMA =
|
||||
new AppSearchSchema.Builder(PACKAGE_ACCESSIBLE_TYPE)
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
|
||||
new AppSearchSchema.StringPropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
.build())
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder(SHA_256_CERT_PROPERTY)
|
||||
new AppSearchSchema.BytesPropertyConfig.Builder(SHA_256_CERT_PROPERTY)
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES)
|
||||
.build())
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder(ACCESSIBLE_SCHEMA_PROPERTY)
|
||||
new AppSearchSchema.StringPropertyConfig.Builder(
|
||||
ACCESSIBLE_SCHEMA_PROPERTY)
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
@@ -238,7 +235,8 @@ class VisibilityStore {
|
||||
PACKAGE_NAME,
|
||||
DATABASE_NAME,
|
||||
NAMESPACE,
|
||||
/*uri=*/ addUriPrefix(prefix));
|
||||
/*uri=*/ addUriPrefix(prefix),
|
||||
/*typePropertyPaths=*/ Collections.emptyMap());
|
||||
|
||||
// Update platform visibility settings
|
||||
String[] schemas =
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.util.Log;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import com.google.android.icing.proto.DocumentIndexingConfig;
|
||||
import com.google.android.icing.proto.PropertyConfigProto;
|
||||
import com.google.android.icing.proto.SchemaTypeConfigProto;
|
||||
import com.google.android.icing.proto.SchemaTypeConfigProtoOrBuilder;
|
||||
@@ -65,7 +66,6 @@ public final class SchemaToProtoConverter {
|
||||
Preconditions.checkNotNull(property);
|
||||
PropertyConfigProto.Builder builder =
|
||||
PropertyConfigProto.newBuilder().setPropertyName(property.getName());
|
||||
StringIndexingConfig.Builder indexingConfig = StringIndexingConfig.newBuilder();
|
||||
|
||||
// Set dataType
|
||||
@AppSearchSchema.PropertyConfig.DataType int dataType = property.getDataType();
|
||||
@@ -76,12 +76,6 @@ public final class SchemaToProtoConverter {
|
||||
}
|
||||
builder.setDataType(dataTypeProto);
|
||||
|
||||
// Set schemaType
|
||||
String schemaType = property.getSchemaType();
|
||||
if (schemaType != null) {
|
||||
builder.setSchemaType(schemaType);
|
||||
}
|
||||
|
||||
// Set cardinality
|
||||
@AppSearchSchema.PropertyConfig.Cardinality int cardinality = property.getCardinality();
|
||||
PropertyConfigProto.Cardinality.Code cardinalityProto =
|
||||
@@ -91,36 +85,27 @@ public final class SchemaToProtoConverter {
|
||||
}
|
||||
builder.setCardinality(cardinalityProto);
|
||||
|
||||
// Set indexingType
|
||||
@AppSearchSchema.PropertyConfig.IndexingType int indexingType = property.getIndexingType();
|
||||
TermMatchType.Code termMatchTypeProto;
|
||||
switch (indexingType) {
|
||||
case AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE:
|
||||
termMatchTypeProto = TermMatchType.Code.UNKNOWN;
|
||||
break;
|
||||
case AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS:
|
||||
termMatchTypeProto = TermMatchType.Code.EXACT_ONLY;
|
||||
break;
|
||||
case AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES:
|
||||
termMatchTypeProto = TermMatchType.Code.PREFIX;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
|
||||
}
|
||||
indexingConfig.setTermMatchType(termMatchTypeProto);
|
||||
if (property instanceof AppSearchSchema.StringPropertyConfig) {
|
||||
AppSearchSchema.StringPropertyConfig stringProperty =
|
||||
(AppSearchSchema.StringPropertyConfig) property;
|
||||
StringIndexingConfig stringIndexingConfig =
|
||||
StringIndexingConfig.newBuilder()
|
||||
.setTermMatchType(
|
||||
convertTermMatchTypeToProto(stringProperty.getIndexingType()))
|
||||
.setTokenizerType(
|
||||
convertTokenizerTypeToProto(stringProperty.getTokenizerType()))
|
||||
.build();
|
||||
builder.setStringIndexingConfig(stringIndexingConfig);
|
||||
|
||||
// Set tokenizerType
|
||||
@AppSearchSchema.PropertyConfig.TokenizerType
|
||||
int tokenizerType = property.getTokenizerType();
|
||||
StringIndexingConfig.TokenizerType.Code tokenizerTypeProto =
|
||||
StringIndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
|
||||
if (tokenizerTypeProto == null) {
|
||||
throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
|
||||
} else if (property instanceof AppSearchSchema.DocumentPropertyConfig) {
|
||||
AppSearchSchema.DocumentPropertyConfig documentProperty =
|
||||
(AppSearchSchema.DocumentPropertyConfig) property;
|
||||
builder.setSchemaType(documentProperty.getSchemaType())
|
||||
.setDocumentIndexingConfig(
|
||||
DocumentIndexingConfig.newBuilder()
|
||||
.setIndexNestedProperties(
|
||||
documentProperty.isIndexNestedProperties()));
|
||||
}
|
||||
indexingConfig.setTokenizerType(tokenizerTypeProto);
|
||||
|
||||
// Build!
|
||||
builder.setStringIndexingConfig(indexingConfig);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -145,39 +130,99 @@ public final class SchemaToProtoConverter {
|
||||
private static AppSearchSchema.PropertyConfig toPropertyConfig(
|
||||
@NonNull PropertyConfigProto proto) {
|
||||
Preconditions.checkNotNull(proto);
|
||||
AppSearchSchema.PropertyConfig.Builder builder =
|
||||
new AppSearchSchema.PropertyConfig.Builder(proto.getPropertyName())
|
||||
.setDataType(proto.getDataType().getNumber())
|
||||
switch (proto.getDataType()) {
|
||||
case STRING:
|
||||
return toStringPropertyConfig(proto);
|
||||
case INT64:
|
||||
return new AppSearchSchema.Int64PropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.build();
|
||||
case DOUBLE:
|
||||
return new AppSearchSchema.DoublePropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.build();
|
||||
case BOOLEAN:
|
||||
return new AppSearchSchema.BooleanPropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.build();
|
||||
case BYTES:
|
||||
return new AppSearchSchema.BytesPropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.build();
|
||||
case DOCUMENT:
|
||||
return toDocumentPropertyConfig(proto);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid dataType: " + proto.getDataType());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static AppSearchSchema.StringPropertyConfig toStringPropertyConfig(
|
||||
@NonNull PropertyConfigProto proto) {
|
||||
AppSearchSchema.StringPropertyConfig.Builder builder =
|
||||
new AppSearchSchema.StringPropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.setTokenizerType(
|
||||
proto.getStringIndexingConfig().getTokenizerType().getNumber());
|
||||
|
||||
// Set schema
|
||||
if (!proto.getSchemaType().isEmpty()) {
|
||||
builder.setSchemaType(proto.getSchemaType());
|
||||
}
|
||||
|
||||
// Set indexingType
|
||||
@AppSearchSchema.PropertyConfig.IndexingType int indexingType;
|
||||
TermMatchType.Code termMatchTypeProto = proto.getStringIndexingConfig().getTermMatchType();
|
||||
switch (termMatchTypeProto) {
|
||||
case UNKNOWN:
|
||||
indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
|
||||
break;
|
||||
case EXACT_ONLY:
|
||||
indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS;
|
||||
break;
|
||||
case PREFIX:
|
||||
indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES;
|
||||
break;
|
||||
default:
|
||||
// Avoid crashing in the 'read' path; we should try to interpret the document to the
|
||||
// extent possible.
|
||||
Log.w(TAG, "Invalid indexingType: " + termMatchTypeProto.getNumber());
|
||||
indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
|
||||
}
|
||||
builder.setIndexingType(indexingType);
|
||||
builder.setIndexingType(convertTermMatchTypeFromProto(termMatchTypeProto));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static AppSearchSchema.DocumentPropertyConfig toDocumentPropertyConfig(
|
||||
@NonNull PropertyConfigProto proto) {
|
||||
return new AppSearchSchema.DocumentPropertyConfig.Builder(proto.getPropertyName())
|
||||
.setCardinality(proto.getCardinality().getNumber())
|
||||
.setSchemaType(proto.getSchemaType())
|
||||
.setIndexNestedProperties(
|
||||
proto.getDocumentIndexingConfig().getIndexNestedProperties())
|
||||
.build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static TermMatchType.Code convertTermMatchTypeToProto(
|
||||
@AppSearchSchema.StringPropertyConfig.IndexingType int indexingType) {
|
||||
switch (indexingType) {
|
||||
case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE:
|
||||
return TermMatchType.Code.UNKNOWN;
|
||||
case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS:
|
||||
return TermMatchType.Code.EXACT_ONLY;
|
||||
case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES:
|
||||
return TermMatchType.Code.PREFIX;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid indexingType: " + indexingType);
|
||||
}
|
||||
}
|
||||
|
||||
@AppSearchSchema.StringPropertyConfig.IndexingType
|
||||
private static int convertTermMatchTypeFromProto(@NonNull TermMatchType.Code termMatchType) {
|
||||
switch (termMatchType) {
|
||||
case UNKNOWN:
|
||||
return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
|
||||
case EXACT_ONLY:
|
||||
return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS;
|
||||
case PREFIX:
|
||||
return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES;
|
||||
default:
|
||||
// Avoid crashing in the 'read' path; we should try to interpret the document to the
|
||||
// extent possible.
|
||||
Log.w(TAG, "Invalid indexingType: " + termMatchType.getNumber());
|
||||
return AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static StringIndexingConfig.TokenizerType.Code convertTokenizerTypeToProto(
|
||||
@AppSearchSchema.StringPropertyConfig.TokenizerType int tokenizerType) {
|
||||
StringIndexingConfig.TokenizerType.Code tokenizerTypeProto =
|
||||
StringIndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
|
||||
if (tokenizerTypeProto == null) {
|
||||
throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType);
|
||||
}
|
||||
return tokenizerTypeProto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@ import com.google.android.icing.proto.ResultSpecProto;
|
||||
import com.google.android.icing.proto.ScoringSpecProto;
|
||||
import com.google.android.icing.proto.SearchSpecProto;
|
||||
import com.google.android.icing.proto.TermMatchType;
|
||||
import com.google.android.icing.proto.TypePropertyMask;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Translates a {@link SearchSpec} into icing search protos.
|
||||
@@ -61,22 +57,17 @@ public final class SearchSpecToProtoConverter {
|
||||
@NonNull
|
||||
public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) {
|
||||
Preconditions.checkNotNull(spec);
|
||||
ResultSpecProto.Builder builder =
|
||||
ResultSpecProto.newBuilder()
|
||||
.setNumPerPage(spec.getResultCountPerPage())
|
||||
.setSnippetSpec(
|
||||
ResultSpecProto.SnippetSpecProto.newBuilder()
|
||||
.setNumToSnippet(spec.getSnippetCount())
|
||||
.setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
|
||||
.setMaxWindowBytes(spec.getMaxSnippetSize()));
|
||||
Map<String, List<String>> projectionTypePropertyPaths = spec.getProjections();
|
||||
for (Map.Entry<String, List<String>> e : projectionTypePropertyPaths.entrySet()) {
|
||||
builder.addTypePropertyMasks(
|
||||
TypePropertyMask.newBuilder()
|
||||
.setSchemaType(e.getKey())
|
||||
.addAllPaths(e.getValue()));
|
||||
}
|
||||
return builder.build();
|
||||
return ResultSpecProto.newBuilder()
|
||||
.setNumPerPage(spec.getResultCountPerPage())
|
||||
.setSnippetSpec(
|
||||
ResultSpecProto.SnippetSpecProto.newBuilder()
|
||||
.setNumToSnippet(spec.getSnippetCount())
|
||||
.setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
|
||||
.setMaxWindowBytes(spec.getMaxSnippetSize()))
|
||||
.addAllTypePropertyMasks(
|
||||
TypePropertyPathToProtoConverter.toTypePropertyMaskList(
|
||||
spec.getProjections()))
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 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 com.android.server.appsearch.external.localstorage.converter;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import com.google.android.icing.proto.TypePropertyMask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Translates a <code>Map<String, List<String>></code> into <code>List<TypePropertyMask></code>.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class TypePropertyPathToProtoConverter {
|
||||
private TypePropertyPathToProtoConverter() {}
|
||||
|
||||
/** Extracts {@link TypePropertyMask} information from a {@link Map}. */
|
||||
@NonNull
|
||||
public static List<TypePropertyMask> toTypePropertyMaskList(
|
||||
@NonNull Map<String, List<String>> typePropertyPaths) {
|
||||
Preconditions.checkNotNull(typePropertyPaths);
|
||||
List<TypePropertyMask> typePropertyMasks = new ArrayList<>(typePropertyPaths.size());
|
||||
for (Map.Entry<String, List<String>> e : typePropertyPaths.entrySet()) {
|
||||
typePropertyMasks.add(
|
||||
TypePropertyMask.newBuilder()
|
||||
.setSchemaType(e.getKey())
|
||||
.addAllPaths(e.getValue())
|
||||
.build());
|
||||
}
|
||||
return typePropertyMasks;
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
I87d10a6c5f7b8e22a633fa910385061fbca0db24
|
||||
Iff96eae150c7cdd281c9ecb5d93f4ef697e89f1a
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.app.appsearch.SearchResultsShim;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class AppSearchTestUtils {
|
||||
@@ -59,6 +60,20 @@ public class AppSearchTestUtils {
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<GenericDocument> doGet(AppSearchSessionShim session, GetByUriRequest request)
|
||||
throws Exception {
|
||||
AppSearchBatchResult<String, GenericDocument> result =
|
||||
checkIsBatchResultSuccess(session.getByUri(request));
|
||||
Set<String> uris = request.getUris();
|
||||
assertThat(result.getSuccesses()).hasSize(uris.size());
|
||||
assertThat(result.getFailures()).isEmpty();
|
||||
List<GenericDocument> list = new ArrayList<>(uris.size());
|
||||
for (String uri : uris) {
|
||||
list.add(result.getSuccesses().get(uri));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<GenericDocument> convertSearchResultsToDocuments(
|
||||
SearchResultsShim searchResults) throws Exception {
|
||||
List<SearchResult> results = searchResults.getNextPage().get();
|
||||
|
||||
@@ -47,32 +47,24 @@ public class AppSearchPerson extends GenericDocument {
|
||||
}
|
||||
|
||||
public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
|
||||
.addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_NAME)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_NAME)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_KEY)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_KEY)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_IS_BOT)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN)
|
||||
).addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(KEY_IS_BOT)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_IS_IMPORTANT)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN)
|
||||
).addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(KEY_IS_IMPORTANT)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).build();
|
||||
|
||||
@@ -73,131 +73,100 @@ public class AppSearchShortcutInfo extends GenericDocument {
|
||||
public static final String KEY_DISABLED_REASON = "disabledReason";
|
||||
|
||||
public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
|
||||
.addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_PACKAGE_NAME)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_PACKAGE_NAME)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_ACTIVITY)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_ACTIVITY)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_TITLE)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_TITLE)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_TEXT)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_TEXT)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_DISABLED_MESSAGE)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_DISABLED_MESSAGE)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_CATEGORIES)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_CATEGORIES)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_INTENTS)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_INTENTS)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_INTENT_PERSISTABLE_EXTRAS)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES)
|
||||
).addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(
|
||||
KEY_INTENT_PERSISTABLE_EXTRAS)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_PERSON)
|
||||
).addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(KEY_PERSON)
|
||||
.setSchemaType(AppSearchPerson.SCHEMA_TYPE)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_LOCUS_ID)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_LOCUS_ID)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_RANK)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
|
||||
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_RANK)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_EXTRAS)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES)
|
||||
).addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(KEY_EXTRAS)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_FLAGS)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
|
||||
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_FLAGS)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_ICON_RES_ID)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
|
||||
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_ICON_RES_ID)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_ICON_RES_NAME)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_ICON_RES_NAME)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_ICON_URI)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_ICON_URI)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_BITMAP_PATH)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_BITMAP_PATH)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
|
||||
.build()
|
||||
|
||||
).addProperty(new AppSearchSchema.PropertyConfig.Builder(KEY_DISABLED_REASON)
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
|
||||
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_DISABLED_REASON)
|
||||
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
|
||||
.setTokenizerType(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
.setIndexingType(AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS)
|
||||
.build()
|
||||
|
||||
).build();
|
||||
|
||||
@@ -34,28 +34,26 @@ public class SchemaToProtoConverterTest {
|
||||
new AppSearchSchema.Builder("Email")
|
||||
.setVersion(12345)
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder("subject")
|
||||
.setDataType(
|
||||
AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
new AppSearchSchema.StringPropertyConfig.Builder("subject")
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setIndexingType(
|
||||
AppSearchSchema.PropertyConfig
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(
|
||||
AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.TOKENIZER_TYPE_PLAIN)
|
||||
.build())
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder("body")
|
||||
.setDataType(
|
||||
AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
new AppSearchSchema.StringPropertyConfig.Builder("body")
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setIndexingType(
|
||||
AppSearchSchema.PropertyConfig
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(
|
||||
AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.TOKENIZER_TYPE_PLAIN)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
@@ -102,26 +100,20 @@ public class SchemaToProtoConverterTest {
|
||||
AppSearchSchema musicRecordingSchema =
|
||||
new AppSearchSchema.Builder("MusicRecording")
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder("artist")
|
||||
.setDataType(
|
||||
AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
|
||||
new AppSearchSchema.StringPropertyConfig.Builder("artist")
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
|
||||
.setIndexingType(
|
||||
AppSearchSchema.PropertyConfig
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.INDEXING_TYPE_PREFIXES)
|
||||
.setTokenizerType(
|
||||
AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_PLAIN)
|
||||
AppSearchSchema.StringPropertyConfig
|
||||
.TOKENIZER_TYPE_PLAIN)
|
||||
.build())
|
||||
.addProperty(
|
||||
new AppSearchSchema.PropertyConfig.Builder("pubDate")
|
||||
.setDataType(AppSearchSchema.PropertyConfig.DATA_TYPE_INT64)
|
||||
new AppSearchSchema.Int64PropertyConfig.Builder("pubDate")
|
||||
.setCardinality(
|
||||
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
|
||||
.setIndexingType(
|
||||
AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE)
|
||||
.setTokenizerType(
|
||||
AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_NONE)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
@@ -147,14 +139,7 @@ public class SchemaToProtoConverterTest {
|
||||
.setPropertyName("pubDate")
|
||||
.setDataType(PropertyConfigProto.DataType.Code.INT64)
|
||||
.setCardinality(
|
||||
PropertyConfigProto.Cardinality.Code.OPTIONAL)
|
||||
.setStringIndexingConfig(
|
||||
StringIndexingConfig.newBuilder()
|
||||
.setTokenizerType(
|
||||
StringIndexingConfig.TokenizerType
|
||||
.Code.NONE)
|
||||
.setTermMatchType(
|
||||
TermMatchType.Code.UNKNOWN)))
|
||||
PropertyConfigProto.Cardinality.Code.OPTIONAL))
|
||||
.build();
|
||||
|
||||
assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(musicRecordingSchema))
|
||||
|
||||
Reference in New Issue
Block a user