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