]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/storage/groups/GroupInfoV1.java
Implement support for sending/receiving Group V2 messages
[signal-cli] / src / main / java / org / asamk / signal / storage / groups / GroupInfoV1.java
diff --git a/src/main/java/org/asamk/signal/storage/groups/GroupInfoV1.java b/src/main/java/org/asamk/signal/storage/groups/GroupInfoV1.java
new file mode 100644 (file)
index 0000000..9ec5178
--- /dev/null
@@ -0,0 +1,157 @@
+package org.asamk.signal.storage.groups;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import org.whispersystems.signalservice.api.push.SignalServiceAddress;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+public class GroupInfoV1 extends GroupInfo {
+
+    private static final ObjectMapper jsonProcessor = new ObjectMapper();
+
+    @JsonProperty
+    public String name;
+
+    @JsonProperty
+    @JsonDeserialize(using = MembersDeserializer.class)
+    @JsonSerialize(using = MembersSerializer.class)
+    public Set<SignalServiceAddress> members = new HashSet<>();
+    @JsonProperty
+    public String color;
+    @JsonProperty(defaultValue = "0")
+    public int messageExpirationTime;
+    @JsonProperty(defaultValue = "false")
+    public boolean blocked;
+    @JsonProperty
+    public Integer inboxPosition;
+    @JsonProperty(defaultValue = "false")
+    public boolean archived;
+
+    public GroupInfoV1(byte[] groupId) {
+        super(groupId);
+    }
+
+    @Override
+    public String getTitle() {
+        return name;
+    }
+
+    public GroupInfoV1(@JsonProperty("groupId") byte[] groupId, @JsonProperty("name") String name, @JsonProperty("members") Collection<SignalServiceAddress> members, @JsonProperty("avatarId") long _ignored_avatarId, @JsonProperty("color") String color, @JsonProperty("blocked") boolean blocked, @JsonProperty("inboxPosition") Integer inboxPosition, @JsonProperty("archived") boolean archived, @JsonProperty("messageExpirationTime") int messageExpirationTime, @JsonProperty("active") boolean _ignored_active) {
+        super(groupId);
+        this.name = name;
+        this.members.addAll(members);
+        this.color = color;
+        this.blocked = blocked;
+        this.inboxPosition = inboxPosition;
+        this.archived = archived;
+        this.messageExpirationTime = messageExpirationTime;
+    }
+
+    @JsonIgnore
+    public Set<SignalServiceAddress> getMembers() {
+        return members;
+    }
+
+    @Override
+    public boolean isBlocked() {
+        return blocked;
+    }
+
+    @Override
+    public void setBlocked(final boolean blocked) {
+        this.blocked = blocked;
+    }
+
+    @Override
+    public int getMessageExpirationTime() {
+        return messageExpirationTime;
+    }
+
+    public void addMembers(Collection<SignalServiceAddress> addresses) {
+        for (SignalServiceAddress address : addresses) {
+            if (this.members.contains(address)) {
+                continue;
+            }
+            removeMember(address);
+            this.members.add(address);
+        }
+    }
+
+    public void removeMember(SignalServiceAddress address) {
+        this.members.removeIf(member -> member.matches(address));
+    }
+
+    private static final class JsonSignalServiceAddress {
+
+        @JsonProperty
+        private UUID uuid;
+
+        @JsonProperty
+        private String number;
+
+        JsonSignalServiceAddress(@JsonProperty("uuid") final UUID uuid, @JsonProperty("number") final String number) {
+            this.uuid = uuid;
+            this.number = number;
+        }
+
+        JsonSignalServiceAddress(SignalServiceAddress address) {
+            this.uuid = address.getUuid().orNull();
+            this.number = address.getNumber().orNull();
+        }
+
+        SignalServiceAddress toSignalServiceAddress() {
+            return new SignalServiceAddress(uuid, number);
+        }
+    }
+
+    private static class MembersSerializer extends JsonSerializer<Set<SignalServiceAddress>> {
+
+        @Override
+        public void serialize(final Set<SignalServiceAddress> value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
+            jgen.writeStartArray(value.size());
+            for (SignalServiceAddress address : value) {
+                if (address.getUuid().isPresent()) {
+                    jgen.writeObject(new JsonSignalServiceAddress(address));
+                } else {
+                    jgen.writeString(address.getNumber().get());
+                }
+            }
+            jgen.writeEndArray();
+        }
+    }
+
+    private static class MembersDeserializer extends JsonDeserializer<Set<SignalServiceAddress>> {
+
+        @Override
+        public Set<SignalServiceAddress> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+            Set<SignalServiceAddress> addresses = new HashSet<>();
+            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+            for (JsonNode n : node) {
+                if (n.isTextual()) {
+                    addresses.add(new SignalServiceAddress(null, n.textValue()));
+                } else {
+                    JsonSignalServiceAddress address = jsonProcessor.treeToValue(n, JsonSignalServiceAddress.class);
+                    addresses.add(address.toSignalServiceAddress());
+                }
+            }
+
+            return addresses;
+        }
+    }
+}