summaryrefslogtreecommitdiff
path: root/android/view/textclassifier/TextLinks.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/view/textclassifier/TextLinks.java')
-rw-r--r--android/view/textclassifier/TextLinks.java252
1 files changed, 252 insertions, 0 deletions
diff --git a/android/view/textclassifier/TextLinks.java b/android/view/textclassifier/TextLinks.java
new file mode 100644
index 00000000..f3cc827f
--- /dev/null
+++ b/android/view/textclassifier/TextLinks.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textclassifier;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.LocaleList;
+import android.text.SpannableString;
+import android.text.style.ClickableSpan;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * A collection of links, representing subsequences of text and the entity types (phone number,
+ * address, url, etc) they may be.
+ */
+public final class TextLinks {
+ private final String mFullText;
+ private final List<TextLink> mLinks;
+
+ private TextLinks(String fullText, Collection<TextLink> links) {
+ mFullText = fullText;
+ mLinks = Collections.unmodifiableList(new ArrayList<>(links));
+ }
+
+ /**
+ * Returns an unmodifiable Collection of the links.
+ */
+ public Collection<TextLink> getLinks() {
+ return mLinks;
+ }
+
+ /**
+ * Annotates the given text with the generated links. It will fail if the provided text doesn't
+ * match the original text used to crete the TextLinks.
+ *
+ * @param text the text to apply the links to. Must match the original text.
+ * @param spanFactory a factory to generate spans from TextLinks. Will use a default if null.
+ *
+ * @return Success or failure.
+ */
+ public boolean apply(
+ @NonNull SpannableString text,
+ @Nullable Function<TextLink, ClickableSpan> spanFactory) {
+ Preconditions.checkNotNull(text);
+ if (!mFullText.equals(text.toString())) {
+ return false;
+ }
+
+ if (spanFactory == null) {
+ spanFactory = DEFAULT_SPAN_FACTORY;
+ }
+ for (TextLink link : mLinks) {
+ final ClickableSpan span = spanFactory.apply(link);
+ if (span != null) {
+ text.setSpan(span, link.getStart(), link.getEnd(), 0);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * A link, identifying a substring of text and possible entity types for it.
+ */
+ public static final class TextLink {
+ private final EntityConfidence<String> mEntityScores;
+ private final String mOriginalText;
+ private final int mStart;
+ private final int mEnd;
+
+ /**
+ * Create a new TextLink.
+ *
+ * @throws IllegalArgumentException if entityScores is null or empty.
+ */
+ public TextLink(String originalText, int start, int end, Map<String, Float> entityScores) {
+ Preconditions.checkNotNull(originalText);
+ Preconditions.checkNotNull(entityScores);
+ Preconditions.checkArgument(!entityScores.isEmpty());
+ Preconditions.checkArgument(start <= end);
+ mOriginalText = originalText;
+ mStart = start;
+ mEnd = end;
+ mEntityScores = new EntityConfidence<>();
+
+ for (Map.Entry<String, Float> entry : entityScores.entrySet()) {
+ mEntityScores.setEntityType(entry.getKey(), entry.getValue());
+ }
+ }
+
+ /**
+ * Returns the start index of this link in the original text.
+ *
+ * @return the start index.
+ */
+ public int getStart() {
+ return mStart;
+ }
+
+ /**
+ * Returns the end index of this link in the original text.
+ *
+ * @return the end index.
+ */
+ public int getEnd() {
+ return mEnd;
+ }
+
+ /**
+ * Returns the number of entity types that have confidence scores.
+ *
+ * @return the entity count.
+ */
+ public int getEntityCount() {
+ return mEntityScores.getEntities().size();
+ }
+
+ /**
+ * Returns the entity type at a given index. Entity types are sorted by confidence.
+ *
+ * @return the entity type at the provided index.
+ */
+ @NonNull public @TextClassifier.EntityType String getEntity(int index) {
+ return mEntityScores.getEntities().get(index);
+ }
+
+ /**
+ * Returns the confidence score for a particular entity type.
+ *
+ * @param entityType the entity type.
+ */
+ public @FloatRange(from = 0.0, to = 1.0) float getConfidenceScore(
+ @TextClassifier.EntityType String entityType) {
+ return mEntityScores.getConfidenceScore(entityType);
+ }
+ }
+
+ /**
+ * Optional input parameters for generating TextLinks.
+ */
+ public static final class Options {
+ private final LocaleList mLocaleList;
+
+ private Options(LocaleList localeList) {
+ this.mLocaleList = localeList;
+ }
+
+ /**
+ * Builder to construct Options.
+ */
+ public static final class Builder {
+ private LocaleList mLocaleList;
+
+ /**
+ * Sets the LocaleList to use.
+ *
+ * @return this Builder.
+ */
+ public Builder setLocaleList(@Nullable LocaleList localeList) {
+ this.mLocaleList = localeList;
+ return this;
+ }
+
+ /**
+ * Builds the Options object.
+ */
+ public Options build() {
+ return new Options(mLocaleList);
+ }
+ }
+ public @Nullable LocaleList getDefaultLocales() {
+ return mLocaleList;
+ }
+ };
+
+ /**
+ * A function to create spans from TextLinks.
+ *
+ * Applies only to TextViews.
+ * We can hide this until we are convinced we want it to be part of the public API.
+ *
+ * @hide
+ */
+ public static final Function<TextLink, ClickableSpan> DEFAULT_SPAN_FACTORY =
+ new Function<TextLink, ClickableSpan>() {
+ @Override
+ public ClickableSpan apply(TextLink textLink) {
+ // TODO: Implement.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+ };
+
+ /**
+ * A builder to construct a TextLinks instance.
+ */
+ public static final class Builder {
+ private final String mFullText;
+ private final Collection<TextLink> mLinks;
+
+ /**
+ * Create a new TextLinks.Builder.
+ *
+ * @param fullText The full text that links will be added to.
+ */
+ public Builder(@NonNull String fullText) {
+ mFullText = Preconditions.checkNotNull(fullText);
+ mLinks = new ArrayList<>();
+ }
+
+ /**
+ * Adds a TextLink.
+ *
+ * @return this instance.
+ */
+ public Builder addLink(TextLink link) {
+ Preconditions.checkNotNull(link);
+ mLinks.add(link);
+ return this;
+ }
+
+ /**
+ * Constructs a TextLinks instance.
+ *
+ * @return the constructed TextLinks.
+ */
+ public TextLinks build() {
+ return new TextLinks(mFullText, mLinks);
+ }
+ }
+}