--- /dev/null
+package org.asamk.signal.manager.api;
+
+import org.whispersystems.signalservice.internal.util.Util;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+public class Profile {
+
+ private final long lastUpdateTimestamp;
+
+ private final String givenName;
+
+ private final String familyName;
+
+ private final String about;
+
+ private final String aboutEmoji;
+
+ private final String avatarUrlPath;
+
+ private final byte[] mobileCoinAddress;
+
+ private final UnidentifiedAccessMode unidentifiedAccessMode;
+
+ private final Set<Capability> capabilities;
+
+ public Profile(
+ final long lastUpdateTimestamp,
+ final String givenName,
+ final String familyName,
+ final String about,
+ final String aboutEmoji,
+ final String avatarUrlPath,
+ final byte[] mobileCoinAddress,
+ final UnidentifiedAccessMode unidentifiedAccessMode,
+ final Set<Capability> capabilities
+ ) {
+ this.lastUpdateTimestamp = lastUpdateTimestamp;
+ this.givenName = givenName;
+ this.familyName = familyName;
+ this.about = about;
+ this.aboutEmoji = aboutEmoji;
+ this.avatarUrlPath = avatarUrlPath;
+ this.mobileCoinAddress = mobileCoinAddress;
+ this.unidentifiedAccessMode = unidentifiedAccessMode;
+ this.capabilities = capabilities;
+ }
+
+ private Profile(final Builder builder) {
+ lastUpdateTimestamp = builder.lastUpdateTimestamp;
+ givenName = builder.givenName;
+ familyName = builder.familyName;
+ about = builder.about;
+ aboutEmoji = builder.aboutEmoji;
+ avatarUrlPath = builder.avatarUrlPath;
+ mobileCoinAddress = builder.mobileCoinAddress;
+ unidentifiedAccessMode = builder.unidentifiedAccessMode;
+ capabilities = builder.capabilities;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static Builder newBuilder(final Profile copy) {
+ Builder builder = new Builder();
+ builder.lastUpdateTimestamp = copy.getLastUpdateTimestamp();
+ builder.givenName = copy.getGivenName();
+ builder.familyName = copy.getFamilyName();
+ builder.about = copy.getAbout();
+ builder.aboutEmoji = copy.getAboutEmoji();
+ builder.avatarUrlPath = copy.getAvatarUrlPath();
+ builder.mobileCoinAddress = copy.getMobileCoinAddress();
+ builder.unidentifiedAccessMode = copy.getUnidentifiedAccessMode();
+ builder.capabilities = copy.getCapabilities();
+ return builder;
+ }
+
+ public long getLastUpdateTimestamp() {
+ return lastUpdateTimestamp;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ public String getInternalServiceName() {
+ if (familyName == null) {
+ return givenName == null ? "" : givenName;
+ }
+ return String.join("\0", givenName == null ? "" : givenName, familyName);
+ }
+
+ public String getDisplayName() {
+ final var noGivenName = Util.isEmpty(givenName);
+ final var noFamilyName = Util.isEmpty(familyName);
+
+ if (noGivenName && noFamilyName) {
+ return "";
+ } else if (noGivenName) {
+ return familyName;
+ } else if (noFamilyName) {
+ return givenName;
+ }
+
+ return givenName + " " + familyName;
+ }
+
+ public String getAbout() {
+ return about;
+ }
+
+ public String getAboutEmoji() {
+ return aboutEmoji;
+ }
+
+ public String getAvatarUrlPath() {
+ return avatarUrlPath;
+ }
+
+ public byte[] getMobileCoinAddress() {
+ return mobileCoinAddress;
+ }
+
+ public UnidentifiedAccessMode getUnidentifiedAccessMode() {
+ return unidentifiedAccessMode;
+ }
+
+ public Set<Capability> getCapabilities() {
+ return capabilities;
+ }
+
+ public enum UnidentifiedAccessMode {
+ UNKNOWN,
+ DISABLED,
+ ENABLED,
+ UNRESTRICTED;
+
+ public static UnidentifiedAccessMode valueOfOrUnknown(String value) {
+ try {
+ return valueOf(value);
+ } catch (IllegalArgumentException ignored) {
+ return UNKNOWN;
+ }
+ }
+ }
+
+ public enum Capability {
+ storage,
+ gv1Migration,
+ senderKey,
+ announcementGroup;
+
+ public static Capability valueOfOrNull(String value) {
+ try {
+ return valueOf(value);
+ } catch (IllegalArgumentException ignored) {
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ final Profile profile = (Profile) o;
+ return lastUpdateTimestamp == profile.lastUpdateTimestamp
+ && Objects.equals(givenName, profile.givenName)
+ && Objects.equals(familyName, profile.familyName)
+ && Objects.equals(about, profile.about)
+ && Objects.equals(aboutEmoji, profile.aboutEmoji)
+ && Objects.equals(avatarUrlPath, profile.avatarUrlPath)
+ && unidentifiedAccessMode == profile.unidentifiedAccessMode
+ && Objects.equals(capabilities, profile.capabilities);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lastUpdateTimestamp,
+ givenName,
+ familyName,
+ about,
+ aboutEmoji,
+ avatarUrlPath,
+ unidentifiedAccessMode,
+ capabilities);
+ }
+
+ public static final class Builder {
+
+ private String givenName;
+ private String familyName;
+ private String about;
+ private String aboutEmoji;
+ private String avatarUrlPath;
+ private byte[] mobileCoinAddress;
+ private UnidentifiedAccessMode unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN;
+ private Set<Capability> capabilities = Collections.emptySet();
+ private long lastUpdateTimestamp = 0;
+
+ private Builder() {
+ }
+
+ public Builder withGivenName(final String val) {
+ givenName = val;
+ return this;
+ }
+
+ public Builder withFamilyName(final String val) {
+ familyName = val;
+ return this;
+ }
+
+ public Builder withAbout(final String val) {
+ about = val;
+ return this;
+ }
+
+ public Builder withAboutEmoji(final String val) {
+ aboutEmoji = val;
+ return this;
+ }
+
+ public Builder withAvatarUrlPath(final String val) {
+ avatarUrlPath = val;
+ return this;
+ }
+
+ public Builder withUnidentifiedAccessMode(final UnidentifiedAccessMode val) {
+ unidentifiedAccessMode = val;
+ return this;
+ }
+
+ public Builder withCapabilities(final Set<Capability> val) {
+ capabilities = val;
+ return this;
+ }
+
+ public Profile build() {
+ return new Profile(this);
+ }
+
+ public Builder withLastUpdateTimestamp(final long val) {
+ lastUpdateTimestamp = val;
+ return this;
+ }
+
+ public Builder withMobileCoinAddress(final byte[] val) {
+ mobileCoinAddress = val;
+ return this;
+ }
+ }
+}