Skip to content

Commit 4ca852c

Browse files
committed
📝 Add comprehensive JavaDoc to org.restheart.utils package
1 parent 5c7ca0f commit 4ca852c

22 files changed

+1103
-225
lines changed

commons/src/main/java/org/restheart/utils/BsonUtils.java

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -75,32 +75,56 @@
7575
import org.slf4j.LoggerFactory;
7676

7777
/**
78+
* Utility class providing comprehensive BSON document manipulation operations.
79+
* This class contains methods for parsing, converting, escaping, and manipulating
80+
* BSON documents and values. It supports operations like key escaping/unescaping,
81+
* path-based property access, document flattening/unflattening, and JSON conversion.
82+
*
83+
* <p>Key features include:</p>
84+
* <ul>
85+
* <li>Key escaping for MongoDB compatibility (handles $ and . characters)</li>
86+
* <li>XPath-style property access using dot notation</li>
87+
* <li>Document flattening and unflattening operations</li>
88+
* <li>JSON parsing and serialization</li>
89+
* <li>Update operator detection and validation</li>
90+
* <li>Builder patterns for document and array construction</li>
91+
* </ul>
7892
*
7993
* @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
8094
*/
8195
public class BsonUtils {
8296

97+
/** Logger instance for this class. */
8398
static final Logger LOGGER = LoggerFactory.getLogger(BsonUtils.class);
8499

100+
/** Codec for encoding/decoding BSON arrays. */
85101
private static final BsonArrayCodec BSON_ARRAY_CODEC = new BsonArrayCodec(CodecRegistries.fromProviders(new BsonValueCodecProvider()));
102+
103+
/** Codec registry for document encoding/decoding operations. */
86104
private static final CodecRegistry REGISTRY = CodecRegistries.fromCodecs(new DocumentCodec());
87105

106+
/** Escaped representation of the dollar sign character. */
88107
private static final String ESCAPED_DOLLAR = "_$";
108+
109+
/** Escaped representation of the dot character. */
89110
private static final String ESCAPED_DOT = "::";
111+
112+
/** The dollar sign character. */
90113
private static final String DOLLAR = "$";
91114

92115
/**
93-
* replaces the underscore prefixed keys (eg _$exists) with the
94-
* corresponding key (eg $exists) and the dot (.) in property names. This is
95-
* needed because MongoDB does not allow to store keys that starts with $
96-
* and with dots in it
116+
* Replaces the underscore prefixed keys (e.g., _$exists) with the
117+
* corresponding key (e.g., $exists) and replaces escaped dots (::) with
118+
* actual dots (.) in property names. This operation reverses the escaping
119+
* applied by {@link #escapeKeys(BsonValue)} method.
97120
*
98-
* See
99-
* https://docs.mongodb.org/manual/reference/limits/#Restrictions-on-Field-Names
121+
* <p>This is needed because MongoDB does not allow storing keys that start with $
122+
* and contain dots in them.</p>
100123
*
101-
* @param json
102-
* @return the json object where the underscore prefixed keys are replaced
103-
* with the corresponding keys
124+
* @param json the BSON value to process (can be document, array, or primitive)
125+
* @return the BSON value where the underscore prefixed keys are replaced
126+
* with the corresponding unescaped keys, or null if input is null
127+
* @see <a href="https://docs.mongodb.org/manual/reference/limits/#Restrictions-on-Field-Names">MongoDB Field Name Restrictions</a>
104128
*/
105129
public static BsonValue unescapeKeys(BsonValue json) {
106130
if (json == null) {
@@ -156,14 +180,15 @@ public static BsonValue unescapeKeys(BsonValue json) {
156180
}
157181

158182
/**
159-
* replaces the dollar prefixed keys (eg $exists) with the corresponding
160-
* underscore prefixed key (eg _$exists). Also replaces dots if escapeDots
161-
* is true. This is needed because MongoDB does not allow to store keys that
162-
* starts with $ and that contains dots.
183+
* Replaces the dollar prefixed keys (e.g., $exists) with the corresponding
184+
* underscore prefixed key (e.g., _$exists). Also replaces dots with escaped
185+
* dots (::) if escapeDots is true. This is needed because MongoDB does not
186+
* allow storing keys that start with $ and contain dots.
163187
*
164-
* @param json
165-
* @param escapeDots
166-
* @return the json object where the keys are escaped
188+
* @param json the BSON value to process (can be document, array, or primitive)
189+
* @param escapeDots if true, dots in keys will be replaced with "::"
190+
* @return the BSON value where the keys are escaped for MongoDB compatibility,
191+
* or null if input is null
167192
*/
168193
public static BsonValue escapeKeys(BsonValue json, boolean escapeDots) {
169194
return escapeKeys(json, escapeDots, false);
@@ -738,10 +763,12 @@ public static String toJson(BsonValue bson, JsonMode mode) {
738763
}
739764

740765
/**
766+
* Converts a BSON value representing an ID to its string representation.
767+
* Handles different BSON types appropriately and can optionally quote string values.
741768
*
742-
* @param id
743-
* @param quote
744-
* @return the String representation of the id
769+
* @param id the BSON value to convert to string
770+
* @param quote if true, string values will be wrapped in single quotes
771+
* @return the string representation of the ID, or null if id is null
745772
*/
746773
public static String getIdAsString(BsonValue id, boolean quote) {
747774
if (id == null) {
@@ -757,12 +784,14 @@ public static String getIdAsString(BsonValue id, boolean quote) {
757784
}
758785
}
759786

787+
/** Default codec registry from MongoDB client settings for BSON encoding/decoding operations. */
760788
public static final CodecRegistry DEFAULT_CODEC_REGISTRY = MongoClientSettings.getDefaultCodecRegistry();
761789

762790
/**
791+
* Converts a Map to a BsonDocument using the default codec registry.
763792
*
764-
* @param map
765-
* @return
793+
* @param map the map to convert to BSON document
794+
* @return the BsonDocument representation of the map, or null if map is null
766795
*/
767796
public static BsonDocument toBsonDocument(Map<String, ? super Object> map) {
768797
if (map == null) {

commons/src/main/java/org/restheart/utils/BuffersUtils.java

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,25 @@
3232
import io.undertow.server.HttpServerExchange;
3333

3434
/**
35+
* Utility class for handling buffer operations and conversions.
36+
* Provides methods for converting between different buffer types, managing
37+
* pooled byte buffers, and performing buffer operations safely with size limits.
3538
*
3639
* @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
3740
*/
3841
public class BuffersUtils {
3942

43+
/** Logger instance for this class. */
4044
private static final Logger LOGGER = LoggerFactory.getLogger(BuffersUtils.class);
4145

4246
/**
43-
* @param srcs
44-
* @return
45-
* @throws java.io.IOException
47+
* Converts an array of pooled byte buffers to a single ByteBuffer.
48+
* This method consolidates multiple pooled buffers into one continuous buffer,
49+
* respecting the maximum content size limit.
50+
*
51+
* @param srcs array of pooled byte buffers to convert
52+
* @return a ByteBuffer containing all the data from the source buffers, or null if srcs is null
53+
* @throws IOException if the total content exceeds the maximum allowed size
4654
*/
4755
public static ByteBuffer toByteBuffer(final PooledByteBuffer[] srcs) throws IOException {
4856
if (srcs == null) {
@@ -72,6 +80,15 @@ public static ByteBuffer toByteBuffer(final PooledByteBuffer[] srcs) throws IOEx
7280
return dst.flip();
7381
}
7482

83+
/**
84+
* Converts an array of pooled byte buffers to a byte array.
85+
* This method first converts the pooled buffers to a ByteBuffer and then
86+
* extracts the data as a byte array.
87+
*
88+
* @param srcs array of pooled byte buffers to convert
89+
* @return a byte array containing all the data from the source buffers
90+
* @throws IOException if the conversion fails or content exceeds size limits
91+
*/
7592
public static byte[] toByteArray(final PooledByteBuffer[] srcs) throws IOException {
7693
var content = toByteBuffer(srcs);
7794

@@ -82,21 +99,38 @@ public static byte[] toByteArray(final PooledByteBuffer[] srcs) throws IOExcepti
8299
return ret;
83100
}
84101

102+
/**
103+
* Converts an array of pooled byte buffers to a string using the specified charset.
104+
*
105+
* @param srcs array of pooled byte buffers to convert
106+
* @param cs the charset to use for string conversion
107+
* @return a string representation of the buffer content
108+
* @throws IOException if the conversion fails or content exceeds size limits
109+
*/
85110
public static String toString(final PooledByteBuffer[] srcs, Charset cs) throws IOException {
86111
return new String(toByteArray(srcs), cs);
87112
}
88113

114+
/**
115+
* Converts a byte array to a string using the specified charset.
116+
*
117+
* @param src the byte array to convert
118+
* @param cs the charset to use for string conversion
119+
* @return a string representation of the byte array content
120+
* @throws IOException if the conversion fails
121+
*/
89122
public static String toString(final byte[] src, Charset cs) throws IOException {
90123
return new String(src, cs);
91124
}
92125

93126
/**
94-
* transfer the src data to the pooled buffers overwriting the exising data
127+
* Transfers data from a source ByteBuffer to pooled byte buffers, overwriting existing data.
128+
* This method allocates new pooled buffers as needed and clears existing ones before copying.
95129
*
96-
* @param src
97-
* @param dest
98-
* @param exchange
99-
* @return
130+
* @param src the source ByteBuffer containing data to transfer
131+
* @param dest array of pooled byte buffers to receive the data
132+
* @param exchange the HTTP server exchange for accessing the byte buffer pool
133+
* @return the number of bytes copied
100134
*/
101135
public static int transfer(final ByteBuffer src, final PooledByteBuffer[] dest, HttpServerExchange exchange) {
102136
var byteBufferPool = exchange.getConnection().getByteBufferPool();
@@ -132,6 +166,13 @@ public static int transfer(final ByteBuffer src, final PooledByteBuffer[] dest,
132166
return copied;
133167
}
134168

169+
/**
170+
* Dumps the content of pooled byte buffers to the debug log for debugging purposes.
171+
* This method logs the hexadecimal representation of each buffer's content.
172+
*
173+
* @param msg a message to include in the log output
174+
* @param data array of pooled byte buffers to dump
175+
*/
135176
public static void dump(String msg, PooledByteBuffer[] data) {
136177
int nbuf = 0;
137178
for (PooledByteBuffer dest : data) {
@@ -151,12 +192,13 @@ public static void dump(String msg, PooledByteBuffer[] data) {
151192
}
152193

153194
/**
154-
* append the src data to the pooled buffers
195+
* Appends data from a source ByteBuffer to pooled byte buffers.
196+
* Unlike transfer(), this method appends to existing buffer content rather than overwriting it.
155197
*
156-
* @param src
157-
* @param dest
158-
* @param exchange
159-
* @return
198+
* @param src the source ByteBuffer containing data to append
199+
* @param dest array of pooled byte buffers to append data to
200+
* @param exchange the HTTP server exchange for accessing the byte buffer pool
201+
* @return the number of bytes copied
160202
*/
161203
public static int append(final ByteBuffer src, final PooledByteBuffer[] dest, HttpServerExchange exchange) {
162204
var byteBufferPool = exchange.getConnection().getByteBufferPool();
@@ -192,6 +234,16 @@ public static int append(final ByteBuffer src, final PooledByteBuffer[] dest, Ht
192234
return copied;
193235
}
194236

237+
/**
238+
* Transfers data from source pooled byte buffers to destination pooled byte buffers.
239+
* This method copies data between two arrays of pooled buffers, allocating destination
240+
* buffers as needed.
241+
*
242+
* @param src array of source pooled byte buffers
243+
* @param dest array of destination pooled byte buffers
244+
* @param exchange the HTTP server exchange for accessing the byte buffer pool
245+
* @return the number of bytes copied
246+
*/
195247
public static int transfer(final PooledByteBuffer[] src, final PooledByteBuffer[] dest, final HttpServerExchange exchange) {
196248
var byteBufferPool = exchange.getConnection().getByteBufferPool();
197249
int copied = 0;

commons/src/main/java/org/restheart/utils/ChannelReader.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,21 @@
2626
import io.undertow.server.HttpServerExchange;
2727

2828
/**
29+
* Utility class for reading data from HTTP server exchange channels.
30+
* Provides convenient methods to read request body content as strings or byte arrays
31+
* using Undertow's asynchronous receiver API.
2932
*
3033
* @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
3134
*/
3235
public class ChannelReader {
3336
/**
37+
* Reads the complete request body as a string using UTF-8 encoding.
38+
* This method uses Undertow's asynchronous receiver to read the full request
39+
* content and convert it to a string.
3440
*
35-
* @param exchange
36-
* @return
37-
* @throws java.io.IOException
41+
* @param exchange the HTTP server exchange containing the request body
42+
* @return the complete request body as a UTF-8 encoded string
43+
* @throws IOException if an I/O error occurs during reading
3844
*/
3945
public static String readString(HttpServerExchange exchange) throws IOException {
4046
final var receiver = exchange.getRequestReceiver();
@@ -49,10 +55,13 @@ public static String readString(HttpServerExchange exchange) throws IOException
4955
}
5056

5157
/**
58+
* Reads the complete request body as a byte array.
59+
* This method uses Undertow's asynchronous receiver to read the full request
60+
* content as raw bytes.
5261
*
53-
* @param exchange
54-
* @return
55-
* @throws java.io.IOException
62+
* @param exchange the HTTP server exchange containing the request body
63+
* @return the complete request body as a byte array
64+
* @throws IOException if an I/O error occurs during reading
5665
*/
5766
public static byte[] readBytes(HttpServerExchange exchange) throws IOException {
5867
final var receiver = exchange.getRequestReceiver();

commons/src/main/java/org/restheart/utils/CheckersUtils.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,33 @@
2626
import org.restheart.exchange.MongoRequest;
2727

2828
/**
29+
* Utility class providing validation and checking methods for MongoDB requests.
30+
* This class contains methods to analyze request content and determine characteristics
31+
* such as whether a request is a bulk operation, uses update operators, or employs
32+
* dot notation in field names.
2933
*
3034
* @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
3135
*/
3236
public class CheckersUtils {
3337
/**
38+
* Determines if the given MongoDB request is a bulk request.
39+
* A request is considered bulk if it either explicitly declares bulk documents
40+
* or if its content is an array of documents.
3441
*
35-
* @param request
36-
* @return if the request is a bulk request
42+
* @param request the MongoDB request to check
43+
* @return true if the request is a bulk request, false otherwise
3744
*/
3845
public static boolean isBulkRequest(MongoRequest request) {
3946
return request.isBulkDocuments() || request.getContent().isArray();
4047
}
4148

4249
/**
50+
* Determines if the request content includes MongoDB update operators.
51+
* This method checks both single documents and arrays of documents for
52+
* the presence of update operators like $set, $unset, $inc, etc.
4353
*
44-
* @param content
45-
* @return true if the request content includes update operators
54+
* @param content the BSON content to analyze (document or array)
55+
* @return true if the content includes update operators, false otherwise
4656
*/
4757
public static boolean doesRequestUseUpdateOperators(BsonValue content) {
4858
if (content.isDocument()) {
@@ -63,10 +73,13 @@ public static boolean doesRequestUseUpdateOperators(BsonValue content) {
6373
}
6474

6575
/**
76+
* Determines if the request content includes properties identified with dot notation.
77+
* Dot notation is used in MongoDB to reference nested fields (e.g., "address.street").
78+
* This method checks both single documents and arrays of documents for field names
79+
* containing dots.
6680
*
67-
* @param content
68-
* @return true if the request content includes properties identified with
69-
* the dot notation
81+
* @param content the BSON content to analyze (document or array)
82+
* @return true if the content includes properties with dot notation, false otherwise
7083
*/
7184
public static boolean doesRequestUseDotNotation(BsonValue content) {
7285
if (content.isDocument()) {

0 commit comments

Comments
 (0)