1 /* 2 * Copyright 2023 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.appsearch.builtintypes; 18 19 import static androidx.core.util.Preconditions.checkNotNull; 20 21 import androidx.annotation.OptIn; 22 import androidx.appsearch.annotation.Document; 23 import androidx.appsearch.app.ExperimentalAppSearchApi; 24 import androidx.appsearch.builtintypes.properties.Keyword; 25 26 import org.jspecify.annotations.NonNull; 27 import org.jspecify.annotations.Nullable; 28 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.List; 32 import java.util.Objects; 33 34 /** 35 * Represents an image file. 36 * 37 * <p>See <a href="http://schema.org/ImageObject">http://schema.org/ImageObject</a> for more 38 * context. 39 */ 40 @Document(name = "builtin:ImageObject") 41 public final class ImageObject extends Thing { 42 43 @Document.DocumentProperty(name = "keywords", indexNestedProperties = true) 44 private final @NonNull List<Keyword> mKeywords; 45 46 @Document.StringProperty 47 private final @Nullable String mSha256; 48 49 @Document.StringProperty 50 private final @Nullable String mThumbnailSha256; 51 52 @Document.BytesProperty 53 private final byte @Nullable [] mBytes; 54 55 @OptIn(markerClass = ExperimentalAppSearchApi.class) ImageObject(@onNull String namespace, @NonNull String id, int documentScore, long creationTimestampMillis, long documentTtlMillis, @Nullable String name, @Nullable List<String> alternateNames, @Nullable String description, @Nullable String image, @Nullable String url, @NonNull List<PotentialAction> potentialActions, @NonNull List<Keyword> keywords, @Nullable String sha256, @Nullable String thumbnailSha256, byte @Nullable [] bytes)56 ImageObject(@NonNull String namespace, @NonNull String id, int documentScore, 57 long creationTimestampMillis, long documentTtlMillis, @Nullable String name, 58 @Nullable List<String> alternateNames, @Nullable String description, 59 @Nullable String image, @Nullable String url, 60 @NonNull List<PotentialAction> potentialActions, 61 @NonNull List<Keyword> keywords, 62 @Nullable String sha256, @Nullable String thumbnailSha256, byte @Nullable [] bytes) { 63 super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name, 64 alternateNames, description, image, url, potentialActions); 65 mKeywords = checkNotNull(keywords); 66 mSha256 = sha256; 67 mThumbnailSha256 = thumbnailSha256; 68 mBytes = bytes; 69 } 70 71 /** 72 * Keywords or tags used to describe some item. 73 * 74 * <p>See <a href="http://schema.org/keywords">http://schema.org/keywords</a> for more context. 75 */ getKeywords()76 public @NonNull List<Keyword> getKeywords() { 77 return mKeywords; 78 } 79 80 /** 81 * The SHA-2 SHA256 hash of the content of the item. 82 * For example, a zero-length input has value 83 * 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'. 84 * 85 * <p>See <a href="http://schema.org/sha256">http://schema.org/sha256</a> for more context. 86 */ getSha256()87 public @Nullable String getSha256() { 88 return mSha256; 89 } 90 91 /** 92 * Returns the {@code sha256} for the thumbnail of this image or video. 93 */ getThumbnailSha256()94 public @Nullable String getThumbnailSha256() { 95 return mThumbnailSha256; 96 } 97 98 /** 99 * Returns the byte representation of this image or video. 100 * Can be a compressed bitmap (e.g. JPEG or PNG). 101 */ getBytes()102 public byte @Nullable [] getBytes() { 103 return mBytes; 104 } 105 106 @Override equals(Object o)107 public boolean equals(Object o) { 108 if (this == o) return true; 109 if (o == null || getClass() != o.getClass()) return false; 110 ImageObject that = (ImageObject) o; 111 return mKeywords.equals(that.mKeywords) && Objects.equals(mSha256, that.mSha256) 112 && Objects.equals(mThumbnailSha256, that.mThumbnailSha256) 113 && Arrays.equals(mBytes, that.mBytes); 114 } 115 116 @Override hashCode()117 public int hashCode() { 118 return Objects.hash(mKeywords, mSha256, mThumbnailSha256, Arrays.hashCode(mBytes)); 119 } 120 121 /** 122 * Builder for {@link ImageObject}. 123 */ 124 public static final class Builder extends BuilderImpl<Builder> { 125 /** 126 * Constructor for an empty {@link Builder}. 127 * 128 * @param namespace Namespace for the Document. See 129 * {@link Document.Namespace}. 130 * @param id Unique identifier for the Document. See {@link Document.Id}. 131 */ Builder(@onNull String namespace, @NonNull String id)132 public Builder(@NonNull String namespace, @NonNull String id) { 133 super(namespace, id); 134 } 135 136 /** 137 * Copy constructor. 138 */ Builder(@onNull ImageObject copyFrom)139 public Builder(@NonNull ImageObject copyFrom) { 140 super(copyFrom); 141 } 142 } 143 144 @SuppressWarnings("unchecked") 145 static class BuilderImpl<Self extends BuilderImpl<Self>> extends Thing.BuilderImpl<Self> { 146 protected final @NonNull List<Keyword> mKeywords; 147 148 protected @Nullable String mSha256; 149 150 protected @Nullable String mThumbnailSha256; 151 152 protected byte @Nullable [] mBytes; 153 BuilderImpl(@onNull String namespace, @NonNull String id)154 BuilderImpl(@NonNull String namespace, @NonNull String id) { 155 super(namespace, id); 156 mKeywords = new ArrayList<>(); 157 mSha256 = null; 158 mThumbnailSha256 = null; 159 mBytes = null; 160 } 161 BuilderImpl(@onNull ImageObject copyFrom)162 BuilderImpl(@NonNull ImageObject copyFrom) { 163 super(new Thing.Builder(checkNotNull(copyFrom)).build()); 164 mKeywords = new ArrayList<>(copyFrom.getKeywords()); 165 mSha256 = copyFrom.getSha256(); 166 mThumbnailSha256 = copyFrom.getThumbnailSha256(); 167 mBytes = copyFrom.getBytes(); 168 } 169 170 @Override build()171 public @NonNull ImageObject build() { 172 return new ImageObject(mNamespace, mId, mDocumentScore, mCreationTimestampMillis, 173 mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl, 174 mPotentialActions, new ArrayList<>(mKeywords), mSha256, mThumbnailSha256, 175 mBytes); 176 } 177 178 /** 179 * Appends the {@link Keyword} as a Text i.e. {@link String}. 180 */ 181 // Atypical overloads in the Builder to model union types. 182 @SuppressWarnings("MissingGetterMatchingBuilder") addKeyword(@onNull String text)183 public @NonNull Self addKeyword(@NonNull String text) { 184 mKeywords.add(new Keyword(checkNotNull(text))); 185 return (Self) this; 186 } 187 188 /** 189 * Appends the {@link Keyword}. 190 */ addKeyword(@onNull Keyword keyword)191 public @NonNull Self addKeyword(@NonNull Keyword keyword) { 192 mKeywords.add(checkNotNull(keyword)); 193 return (Self) this; 194 } 195 196 /** 197 * Appends all the {@code values}. 198 */ addKeywords(@onNull Iterable<Keyword> values)199 public @NonNull Self addKeywords(@NonNull Iterable<Keyword> values) { 200 for (Keyword value : checkNotNull(values)) { 201 mKeywords.add(checkNotNull(value)); 202 } 203 return (Self) this; 204 } 205 206 /** 207 * Sets the {@code sha256}. 208 */ setSha256(@ullable String text)209 public @NonNull Self setSha256(@Nullable String text) { 210 mSha256 = text; 211 return (Self) this; 212 } 213 214 /** 215 * Sets the {@code sha256} of the thumbnail of this image of video. 216 */ setThumbnailSha256(@ullable String text)217 public @NonNull Self setThumbnailSha256(@Nullable String text) { 218 mThumbnailSha256 = text; 219 return (Self) this; 220 } 221 222 /** 223 * Sets the byte representation of this image or video. 224 */ setBytes(byte @Nullable [] bytes)225 public @NonNull Self setBytes(byte @Nullable [] bytes) { 226 mBytes = bytes; 227 return (Self) this; 228 } 229 } 230 } 231