Home | History | Annotate | Download | only in textclassifier
      1 /*
      2  * Copyright (C) 2018 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 androidx.textclassifier;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 import androidx.annotation.IntDef;
     23 import androidx.annotation.RestrictTo;
     24 import androidx.annotation.StringDef;
     25 import androidx.collection.ArraySet;
     26 
     27 import java.lang.annotation.Retention;
     28 import java.lang.annotation.RetentionPolicy;
     29 import java.util.ArrayList;
     30 import java.util.Arrays;
     31 import java.util.Collection;
     32 import java.util.Collections;
     33 import java.util.List;
     34 
     35 /**
     36  * Interface for providing text classification related features.
     37  *
     38  * TextClassifier acts as a proxy to either the system provided TextClassifier, or an equivalent
     39  * implementation provided by an app. Each instance of the class therefore represents one connection
     40  * to the classifier implementation.
     41  *
     42  * <p>Unless otherwise stated, methods of this interface are blocking operations.
     43  * Avoid calling them on the UI thread.
     44  */
     45 public class TextClassifier {
     46 
     47     // TODO: describe in the class documentation how a TC implementation in chosen/located.
     48 
     49     /** Signifies that the TextClassifier did not identify an entity. */
     50     public static final String TYPE_UNKNOWN = "";
     51     /** Signifies that the classifier ran, but didn't recognize a know entity. */
     52     public static final String TYPE_OTHER = "other";
     53     /** Identifies an e-mail address. */
     54     public static final String TYPE_EMAIL = "email";
     55     /** Identifies a phone number. */
     56     public static final String TYPE_PHONE = "phone";
     57     /** Identifies a physical address. */
     58     public static final String TYPE_ADDRESS = "address";
     59     /** Identifies a URL. */
     60     public static final String TYPE_URL = "url";
     61 
     62     /** @hide */
     63     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     64     @Retention(RetentionPolicy.SOURCE)
     65     @StringDef(value = {
     66             TYPE_UNKNOWN,
     67             TYPE_OTHER,
     68             TYPE_EMAIL,
     69             TYPE_PHONE,
     70             TYPE_ADDRESS,
     71             TYPE_URL,
     72     })
     73     @interface EntityType {}
     74 
     75     /** Designates that the TextClassifier should identify all entity types it can. **/
     76     static final int ENTITY_PRESET_ALL = 0;
     77     /** Designates that the TextClassifier should identify no entities. **/
     78     static final int ENTITY_PRESET_NONE = 1;
     79     /** Designates that the TextClassifier should identify a base set of entities determined by the
     80      * TextClassifier. **/
     81     static final int ENTITY_PRESET_BASE = 2;
     82 
     83     /** @hide */
     84     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     85     @Retention(RetentionPolicy.SOURCE)
     86     @IntDef(value = {ENTITY_PRESET_ALL, ENTITY_PRESET_NONE, ENTITY_PRESET_BASE})
     87     @interface EntityPreset {}
     88 
     89     // TODO: add constructor, suggestSelection, classifyText, generateLinks, logEvent
     90 
     91     /**
     92      * Returns a {@link Collection} of the entity types in the specified preset.
     93      *
     94      * @see #ENTITY_PRESET_ALL
     95      * @see #ENTITY_PRESET_NONE
     96      */
     97     /* package */ Collection<String> getEntitiesForPreset(@EntityPreset int entityPreset) {
     98         // TODO: forward call to the classifier implementation.
     99         return Collections.EMPTY_LIST;
    100     }
    101 
    102     /**
    103      * Configuration object for specifying what entities to identify.
    104      *
    105      * Configs are initially based on a predefined preset, and can be modified from there.
    106      */
    107     static final class EntityConfig implements Parcelable {
    108         private final @EntityPreset int mEntityPreset;
    109         private final Collection<String> mExcludedEntityTypes;
    110         private final Collection<String> mIncludedEntityTypes;
    111 
    112         EntityConfig(@EntityPreset int mEntityPreset) {
    113             this.mEntityPreset = mEntityPreset;
    114             mExcludedEntityTypes = new ArraySet<>();
    115             mIncludedEntityTypes = new ArraySet<>();
    116         }
    117 
    118         /**
    119          * Specifies an entity to include in addition to any specified by the enity preset.
    120          *
    121          * Note that if an entity has been excluded, the exclusion will take precedence.
    122          */
    123         public EntityConfig includeEntities(String... entities) {
    124             mIncludedEntityTypes.addAll(Arrays.asList(entities));
    125             return this;
    126         }
    127 
    128         /**
    129          * Specifies an entity to be excluded.
    130          */
    131         public EntityConfig excludeEntities(String... entities) {
    132             mExcludedEntityTypes.addAll(Arrays.asList(entities));
    133             return this;
    134         }
    135 
    136         /**
    137          * Returns an unmodifiable list of the final set of entities to find.
    138          */
    139         public List<String> getEntities(TextClassifier textClassifier) {
    140             ArrayList<String> entities = new ArrayList<>();
    141             for (String entity : textClassifier.getEntitiesForPreset(mEntityPreset)) {
    142                 if (!mExcludedEntityTypes.contains(entity)) {
    143                     entities.add(entity);
    144                 }
    145             }
    146             for (String entity : mIncludedEntityTypes) {
    147                 if (!mExcludedEntityTypes.contains(entity) && !entities.contains(entity)) {
    148                     entities.add(entity);
    149                 }
    150             }
    151             return Collections.unmodifiableList(entities);
    152         }
    153 
    154         @Override
    155         public int describeContents() {
    156             return 0;
    157         }
    158 
    159         @Override
    160         public void writeToParcel(Parcel dest, int flags) {
    161             dest.writeInt(mEntityPreset);
    162             dest.writeStringList(new ArrayList<>(mExcludedEntityTypes));
    163             dest.writeStringList(new ArrayList<>(mIncludedEntityTypes));
    164         }
    165 
    166         public static final Parcelable.Creator<EntityConfig> CREATOR =
    167                 new Parcelable.Creator<EntityConfig>() {
    168                     @Override
    169                     public EntityConfig createFromParcel(Parcel in) {
    170                         return new EntityConfig(in);
    171                     }
    172 
    173                     @Override
    174                     public EntityConfig[] newArray(int size) {
    175                         return new EntityConfig[size];
    176                     }
    177                 };
    178 
    179         private EntityConfig(Parcel in) {
    180             mEntityPreset = in.readInt();
    181             mExcludedEntityTypes = new ArraySet<>(in.createStringArrayList());
    182             mIncludedEntityTypes = new ArraySet<>(in.createStringArrayList());
    183         }
    184     }
    185 }
    186