• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.textclassifier.common.logging;
18 
19 import android.content.Context;
20 import android.text.TextUtils;
21 import com.android.textclassifier.common.base.LocaleCompat;
22 import com.google.common.base.Joiner;
23 import com.google.common.base.Objects;
24 import com.google.common.base.Optional;
25 import com.google.common.base.Preconditions;
26 import com.google.common.base.Splitter;
27 import com.google.common.collect.ImmutableList;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import javax.annotation.Nullable;
34 
35 /** Provide utils to generate and parse the result id. */
36 public final class ResultIdUtils {
37   private static final String CLASSIFIER_ID = "androidtc";
38   private static final String SEPARATOR_MODEL_NAME = ";";
39   private static final String SEPARATOR_LOCALES = ",";
40   private static final Pattern EXTRACT_MODEL_NAME_FROM_RESULT_ID =
41       Pattern.compile("^[^|]*\\|([^|]*)\\|[^|]*$");
42 
43   /** Creates a string id that may be used to identify a TextClassifier result. */
createId( Context context, String text, int start, int end, List<Optional<ModelInfo>> modelInfos)44   public static String createId(
45       Context context, String text, int start, int end, List<Optional<ModelInfo>> modelInfos) {
46     Preconditions.checkNotNull(text);
47     Preconditions.checkNotNull(context);
48     Preconditions.checkNotNull(modelInfos);
49     final int hash = Objects.hashCode(text, start, end, context.getPackageName());
50     return createId(hash, modelInfos);
51   }
52 
53   /** Creates a string id that may be used to identify a TextClassifier result. */
createId(int hash, List<Optional<ModelInfo>> modelInfos)54   public static String createId(int hash, List<Optional<ModelInfo>> modelInfos) {
55     Preconditions.checkNotNull(modelInfos);
56     final List<String> modelNames = new ArrayList<>();
57     for (Optional<ModelInfo> modelInfo : modelInfos) {
58       modelNames.add(modelInfo.transform(ModelInfo::toModelName).or(""));
59     }
60     return String.format(
61         Locale.US,
62         "%s|%s|%d",
63         CLASSIFIER_ID,
64         Joiner.on(SEPARATOR_MODEL_NAME).join(modelNames),
65         hash);
66   }
67 
68   /** Returns if the result id was generated from the default text classifier. */
isFromDefaultTextClassifier(String resultId)69   public static boolean isFromDefaultTextClassifier(String resultId) {
70     return resultId.startsWith(CLASSIFIER_ID + '|');
71   }
72 
73   /** Returns all the model names encoded in the signature. */
getModelNames(@ullable String signature)74   public static ImmutableList<String> getModelNames(@Nullable String signature) {
75     if (TextUtils.isEmpty(signature)) {
76       return ImmutableList.of();
77     }
78     Matcher matcher = EXTRACT_MODEL_NAME_FROM_RESULT_ID.matcher(signature);
79     if (!matcher.find()) {
80       return ImmutableList.of();
81     }
82     return ImmutableList.copyOf(Splitter.on(SEPARATOR_MODEL_NAME).splitToList(matcher.group(1)));
83   }
84 
ResultIdUtils()85   private ResultIdUtils() {}
86 
87   /** Model information of a model file. */
88   public static class ModelInfo {
89     private final String modelName;
90 
ModelInfo(int version, List<Locale> locales)91     public ModelInfo(int version, List<Locale> locales) {
92       this(version, createSupportedLanguageTagsString(locales));
93     }
94 
95     /**
96      * Creates a {@link ModelInfo} object.
97      *
98      * @param version model version
99      * @param supportedLanguageTags a comma-separated string of bcp47 language tags of supported
100      *     languages
101      */
ModelInfo(int version, String supportedLanguageTags)102     public ModelInfo(int version, String supportedLanguageTags) {
103       this.modelName = createModelName(version, supportedLanguageTags);
104     }
105 
createSupportedLanguageTagsString(List<Locale> locales)106     private static String createSupportedLanguageTagsString(List<Locale> locales) {
107       List<String> languageTags = new ArrayList<>();
108       for (Locale locale : locales) {
109         languageTags.add(LocaleCompat.toLanguageTag(locale));
110       }
111       return Joiner.on(SEPARATOR_LOCALES).join(languageTags);
112     }
113 
createModelName(int version, String supportedLanguageTags)114     private static String createModelName(int version, String supportedLanguageTags) {
115       return String.format(Locale.US, "%s_v%d", supportedLanguageTags, version);
116     }
117 
118     /** Returns a string representation of the model info. */
toModelName()119     public String toModelName() {
120       return modelName;
121     }
122   }
123 }
124