Skip to content

Commit f813896

Browse files
committed
Adapt metadata model following review comments
1 parent 1803c09 commit f813896

1 file changed

Lines changed: 66 additions & 12 deletions

File tree

server/blob/blob-api/src/main/java/org/apache/james/blob/api/BlobStoreDAO.java

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,77 @@
2525
import java.nio.charset.StandardCharsets;
2626
import java.util.Collection;
2727
import java.util.Map;
28+
import java.util.Optional;
2829

2930
import org.reactivestreams.Publisher;
3031

32+
import com.google.common.base.CharMatcher;
33+
import com.google.common.base.Preconditions;
3134
import com.google.common.collect.ImmutableMap;
3235
import com.google.common.io.ByteSource;
3336
import com.google.common.io.FileBackedOutputStream;
3437

3538
public interface BlobStoreDAO {
3639
record BlobMetadataName(String name) {
37-
// TODO validation (a-z,A-Z,0-9 -_) &length 128 char & non empty
40+
private static final CharMatcher CHAR_MATCHER = CharMatcher.inRange('a', 'z')
41+
.and(CharMatcher.inRange('A', 'Z'))
42+
.and(CharMatcher.inRange('0', '9'))
43+
.and(CharMatcher.is('-'));
44+
45+
public BlobMetadataName {
46+
Preconditions.checkArgument(CHAR_MATCHER.matchesAllOf(name), "Invalid char in metadata name. Must be a-z,A-Z,0-9 or - got " + name);
47+
Preconditions.checkArgument(name.length() < 128, "Metadata name is too long. Size exceed 128 chars");
48+
}
3849
}
50+
3951
record BlobMetadataValue(String value) {
52+
public BlobMetadataValue {
53+
Preconditions.checkArgument(value.length() < 128, "Metadata value is too long. Size exceed 128 chars");
54+
}
55+
}
56+
57+
record ContentTransferEncoding(String value) {
58+
public static BlobMetadataName NAME = new BlobMetadataName("content-transfer-encoding");
59+
public static ContentTransferEncoding ZSTD = new ContentTransferEncoding("zstd");
60+
61+
public static ContentTransferEncoding fromValue(BlobMetadataValue value) {
62+
return new ContentTransferEncoding(value.value());
63+
}
64+
65+
public ContentTransferEncoding {
66+
Preconditions.checkArgument(value.length() < 128, "ContentTransferEncoding value is too long. Size exceed 128 chars");
67+
}
68+
69+
public BlobMetadataValue asValue() {
70+
return new BlobMetadataValue(value);
71+
}
4072

4173
}
4274

75+
record BlobMetadata(Map<BlobMetadataName, BlobMetadataValue> metadata) {
76+
public static BlobMetadata empty() {
77+
return new BlobMetadata(ImmutableMap.of());
78+
}
79+
80+
public BlobMetadata withMetadata(BlobMetadataName name, BlobMetadataValue value) {
81+
return new BlobMetadata(ImmutableMap.<BlobMetadataName, BlobMetadataValue>builder()
82+
.putAll(metadata)
83+
.put(name, value)
84+
.build());
85+
}
86+
87+
public Optional<ContentTransferEncoding> contentTransferEncoding() {
88+
return Optional.ofNullable(metadata.get(ContentTransferEncoding.NAME)).map(ContentTransferEncoding::fromValue);
89+
}
90+
91+
public BlobMetadata withContentTransferEncoding(ContentTransferEncoding contentTransferEncoding) {
92+
return withMetadata(ContentTransferEncoding.NAME, contentTransferEncoding.asValue());
93+
}
94+
}
95+
96+
4397
sealed interface Blob {
44-
Map<BlobMetadataName, BlobMetadataValue> metadata();
98+
BlobMetadata metadata();
4599

46100
// Have the POJOs encode some conversions ?
47101
InputStreamBlob asInputStream() throws IOException;
@@ -51,16 +105,16 @@ sealed interface Blob {
51105
ByteSourceBlob asByteSource() throws IOException;
52106
}
53107

54-
record BytesBlob(byte[] payload, Map<BlobMetadataName, BlobMetadataValue> metadata) implements Blob {
108+
record BytesBlob(byte[] payload, BlobMetadata metadata) implements Blob {
55109
public static BytesBlob of(byte[] payload) {
56-
return of(payload, ImmutableMap.of());
110+
return of(payload, BlobMetadata.empty());
57111
}
58112

59113
public static BytesBlob of(String payload) {
60-
return of(payload.getBytes(StandardCharsets.UTF_8), ImmutableMap.of());
114+
return of(payload.getBytes(StandardCharsets.UTF_8), BlobMetadata.empty());
61115
}
62116

63-
public static BytesBlob of(byte[] payload, Map<BlobMetadataName, BlobMetadataValue> metadata) {
117+
public static BytesBlob of(byte[] payload, BlobMetadata metadata) {
64118
return new BytesBlob(payload, metadata);
65119
}
66120

@@ -80,12 +134,12 @@ public ByteSourceBlob asByteSource() {
80134
}
81135
}
82136

83-
record InputStreamBlob(InputStream payload, Map<BlobMetadataName, BlobMetadataValue> metadata) implements Blob {
137+
record InputStreamBlob(InputStream payload, BlobMetadata metadata) implements Blob {
84138
public static InputStreamBlob of(InputStream payload) {
85-
return of(payload, ImmutableMap.of());
139+
return of(payload, BlobMetadata.empty());
86140
}
87141

88-
public static InputStreamBlob of(InputStream payload, Map<BlobMetadataName, BlobMetadataValue> metadata) {
142+
public static InputStreamBlob of(InputStream payload, BlobMetadata metadata) {
89143
return new InputStreamBlob(payload, metadata);
90144
}
91145

@@ -108,12 +162,12 @@ public ByteSourceBlob asByteSource() throws IOException {
108162
}
109163
}
110164

111-
record ByteSourceBlob(ByteSource payload, Map<BlobMetadataName, BlobMetadataValue> metadata) implements Blob {
165+
record ByteSourceBlob(ByteSource payload, BlobMetadata metadata) implements Blob {
112166
public static ByteSourceBlob of(ByteSource payload) {
113-
return of(payload, ImmutableMap.of());
167+
return of(payload, BlobMetadata.empty());
114168
}
115169

116-
public static ByteSourceBlob of(ByteSource payload, Map<BlobMetadataName, BlobMetadataValue> metadata) {
170+
public static ByteSourceBlob of(ByteSource payload, BlobMetadata metadata) {
117171
return new ByteSourceBlob(payload, metadata);
118172
}
119173

0 commit comments

Comments
 (0)