]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/Utils.java
1c75d9cc8faf679ff8a4a4ca9c82e548a1efe7fc
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / storage / Utils.java
1 package org.asamk.signal.manager.storage;
2
3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
4 import com.fasterxml.jackson.annotation.PropertyAccessor;
5 import com.fasterxml.jackson.core.JsonGenerator;
6 import com.fasterxml.jackson.core.JsonParser;
7 import com.fasterxml.jackson.databind.DeserializationFeature;
8 import com.fasterxml.jackson.databind.JsonNode;
9 import com.fasterxml.jackson.databind.ObjectMapper;
10 import com.fasterxml.jackson.databind.SerializationFeature;
11
12 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.whispersystems.signalservice.api.push.ServiceId;
16 import org.whispersystems.signalservice.api.push.ServiceIdType;
17 import org.whispersystems.signalservice.api.util.UuidUtil;
18
19 import java.io.InvalidObjectException;
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.util.Optional;
24 import java.util.Spliterator;
25 import java.util.Spliterators;
26 import java.util.function.Consumer;
27 import java.util.stream.Stream;
28 import java.util.stream.StreamSupport;
29
30 public class Utils {
31
32 private static final Logger logger = LoggerFactory.getLogger(Utils.class);
33
34 private Utils() {
35 }
36
37 public static ObjectMapper createStorageObjectMapper() {
38 final ObjectMapper objectMapper = new ObjectMapper();
39
40 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.PUBLIC_ONLY);
41 objectMapper.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print
42 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
43 objectMapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
44 objectMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
45
46 return objectMapper;
47 }
48
49 public static JsonNode getNotNullNode(JsonNode parent, String name) throws InvalidObjectException {
50 var node = parent.get(name);
51 if (node == null || node.isNull()) {
52 throw new InvalidObjectException(String.format("Incorrect file format: expected parameter %s not found ",
53 name));
54 }
55
56 return node;
57 }
58
59 public static RecipientAddress getRecipientAddressFromIdentifier(final String identifier) {
60 if (UuidUtil.isUuid(identifier)) {
61 return new RecipientAddress(ServiceId.parseOrThrow(identifier));
62 } else {
63 return new RecipientAddress(Optional.empty(), Optional.of(identifier));
64 }
65 }
66
67 public static int getAccountIdType(ServiceIdType serviceIdType) {
68 return switch (serviceIdType) {
69 case ACI -> 0;
70 case PNI -> 1;
71 };
72 }
73
74 public static <T> T executeQuerySingleRow(
75 PreparedStatement statement, ResultSetMapper<T> mapper
76 ) throws SQLException {
77 final var resultSet = statement.executeQuery();
78 if (!resultSet.next()) {
79 throw new RuntimeException("Expected a row in result set, but none found.");
80 }
81 return mapper.apply(resultSet);
82 }
83
84 public static <T> Optional<T> executeQueryForOptional(
85 PreparedStatement statement, ResultSetMapper<T> mapper
86 ) throws SQLException {
87 final var resultSet = statement.executeQuery();
88 if (!resultSet.next()) {
89 return Optional.empty();
90 }
91 return Optional.ofNullable(mapper.apply(resultSet));
92 }
93
94 public static <T> Stream<T> executeQueryForStream(
95 PreparedStatement statement, ResultSetMapper<T> mapper
96 ) throws SQLException {
97 final var resultSet = statement.executeQuery();
98
99 return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, Spliterator.ORDERED) {
100 @Override
101 public boolean tryAdvance(final Consumer<? super T> consumer) {
102 try {
103 if (!resultSet.next()) {
104 return false;
105 }
106 consumer.accept(mapper.apply(resultSet));
107 return true;
108 } catch (SQLException e) {
109 logger.warn("Failed to read from database result", e);
110 throw new RuntimeException(e);
111 }
112 }
113 }, false);
114 }
115
116 public interface ResultSetMapper<T> {
117
118 T apply(ResultSet resultSet) throws SQLException;
119 }
120 }