You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/05/04 03:21:21 UTC
[james-project] 02/12: JAMES-2997 Strong type for ContentType Field
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 9d6aca49311252e6014e226fe7f9543996415147
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Apr 27 18:01:05 2020 +0700
JAMES-2997 Strong type for ContentType Field
---
.../apache/james/mailbox/AttachmentManager.java | 3 +-
.../james/mailbox/model/AttachmentMetadata.java | 17 +++---
.../java/org/apache/james/mailbox/model/Blob.java | 13 +++--
.../apache/james/mailbox/model/ContentType.java | 60 ++++++++++++++++++++++
.../james/mailbox/model/ParsedAttachment.java | 12 +++--
.../mailbox/model/AttachmentMetadataTest.java | 2 +-
.../org/apache/james/mailbox/model/BlobTest.java | 2 +-
.../cassandra/mail/CassandraAttachmentDAOV2.java | 11 ++--
.../cassandra/mail/CassandraAttachmentMapper.java | 3 +-
.../inmemory/mail/InMemoryAttachmentMapper.java | 3 +-
.../mailbox/store/StoreAttachmentManager.java | 3 +-
.../james/mailbox/store/StoreBlobManager.java | 3 +-
.../james/mailbox/store/mail/AttachmentMapper.java | 3 +-
.../store/mail/model/impl/MessageParser.java | 8 +--
.../mailbox/store/search/MessageSearches.java | 3 +-
.../james/mailbox/store/StoreBlobManagerTest.java | 3 +-
.../store/mail/model/AttachmentMapperTest.java | 19 +++----
.../store/mail/model/impl/MessageParserTest.java | 24 +++++----
.../methods/integration/SetMessagesMethodTest.java | 42 +++++++--------
.../james/jmap/draft/json/ObjectMapperFactory.java | 21 ++++++++
.../jmap/draft/methods/MIMEMessageConverter.java | 3 +-
.../apache/james/jmap/draft/model/Attachment.java | 18 ++++---
.../org/apache/james/jmap/http/DownloadRoutes.java | 5 +-
.../org/apache/james/jmap/http/UploadRoutes.java | 11 ++--
.../james/jmap/draft/model/AttachmentTest.java | 7 +--
25 files changed, 210 insertions(+), 89 deletions(-)
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index 468e037..3a7424b 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -27,6 +27,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.reactivestreams.Publisher;
public interface AttachmentManager extends AttachmentContentLoader {
@@ -37,7 +38,7 @@ public interface AttachmentManager extends AttachmentContentLoader {
List<AttachmentMetadata> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
- Publisher<AttachmentMetadata> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession);
+ Publisher<AttachmentMetadata> storeAttachment(ContentType contentType, InputStream attachmentContent, MailboxSession mailboxSession);
InputStream loadAttachmentContent(AttachmentId attachmentId, MailboxSession mailboxSession) throws AttachmentNotFoundException, IOException;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
index 9676f76..0f4e9f7 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
@@ -22,13 +22,12 @@ package org.apache.james.mailbox.model;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
public class AttachmentMetadata {
public static class Builder {
private AttachmentId attachmentId;
private Long size;
- private String type;
+ private ContentType type;
public Builder attachmentId(AttachmentId attachmentId) {
Preconditions.checkArgument(attachmentId != null);
@@ -36,12 +35,16 @@ public class AttachmentMetadata {
return this;
}
- public Builder type(String type) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(type));
+ public Builder type(ContentType type) {
this.type = type;
return this;
}
+ public Builder type(String type) {
+ this.type = ContentType.of(type);
+ return this;
+ }
+
public Builder size(long size) {
Preconditions.checkArgument(size >= 0, "'size' must be positive");
this.size = size;
@@ -62,10 +65,10 @@ public class AttachmentMetadata {
}
private final AttachmentId attachmentId;
- private final String type;
+ private final ContentType type;
private final long size;
- private AttachmentMetadata(AttachmentId attachmentId, String type, long size) {
+ private AttachmentMetadata(AttachmentId attachmentId, ContentType type, long size) {
this.attachmentId = attachmentId;
this.type = type;
this.size = size;
@@ -75,7 +78,7 @@ public class AttachmentMetadata {
return attachmentId;
}
- public String getType() {
+ public ContentType getType() {
return type;
}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
index 141f3a8..0103085 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
@@ -44,7 +44,7 @@ public class Blob {
public static class Builder {
private BlobId blobId;
private InputStreamSupplier payload;
- private String contentType;
+ private ContentType contentType;
private Long size;
private Builder() {
@@ -61,6 +61,11 @@ public class Blob {
}
public Builder contentType(String contentType) {
+ this.contentType = ContentType.of(contentType);
+ return this;
+ }
+
+ public Builder contentType(ContentType contentType) {
this.contentType = contentType;
return this;
}
@@ -86,11 +91,11 @@ public class Blob {
private final BlobId blobId;
private final InputStreamSupplier payload;
- private final String contentType;
+ private final ContentType contentType;
private final long size;
@VisibleForTesting
- Blob(BlobId blobId, InputStreamSupplier payload, String contentType, long size) {
+ Blob(BlobId blobId, InputStreamSupplier payload, ContentType contentType, long size) {
this.blobId = blobId;
this.payload = payload;
this.contentType = contentType;
@@ -109,7 +114,7 @@ public class Blob {
return size;
}
- public String getContentType() {
+ public ContentType getContentType() {
return contentType;
}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ContentType.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ContentType.java
new file mode 100644
index 0000000..ed8ecf5
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ContentType.java
@@ -0,0 +1,60 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mailbox.model;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class ContentType {
+ public static ContentType of(String value) {
+ Preconditions.checkState(!Strings.isNullOrEmpty(value), "'content type' is mandatory");
+ return new ContentType(value);
+ }
+
+ /**
+ * Follows syntax and usage as defined in https://tools.ietf.org/html/rfc2045#section-5
+ * Thus includes media type and parameters, including charset
+ * Example: text/plain; charset=utf-8
+ */
+ private final String value;
+
+ public ContentType(String value) {
+ this.value = value;
+ }
+
+ public String asString() {
+ return value;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof ContentType) {
+ ContentType that = (ContentType) o;
+
+ return java.util.Objects.equals(this.value, that.value);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return java.util.Objects.hash(value);
+ }
+}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
index c615473..429528e 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
@@ -26,7 +26,11 @@ public class ParsedAttachment {
interface Builder {
@FunctionalInterface
interface RequireContentType {
- RequireContent contentType(String contentType);
+ RequireContent contentType(ContentType contentType);
+
+ default RequireContent contentType(String contentType) {
+ return contentType(ContentType.of(contentType));
+ }
}
@FunctionalInterface
@@ -74,13 +78,13 @@ public class ParsedAttachment {
return contentType -> content -> name -> cid -> isInline -> new ParsedAttachment(contentType, content, name, cid, isInline);
}
- private final String contentType;
+ private final ContentType contentType;
private final byte[] content;
private final Optional<String> name;
private final Optional<Cid> cid;
private final boolean isInline;
- private ParsedAttachment(String contentType, byte[] content, Optional<String> name, Optional<Cid> cid, boolean isInline) {
+ private ParsedAttachment(ContentType contentType, byte[] content, Optional<String> name, Optional<Cid> cid, boolean isInline) {
this.contentType = contentType;
this.content = content;
this.name = name;
@@ -88,7 +92,7 @@ public class ParsedAttachment {
this.isInline = isInline;
}
- public String getContentType() {
+ public ContentType getContentType() {
return contentType;
}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
index 1c0eaba..f75bc1b 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
@@ -35,7 +35,7 @@ class AttachmentMetadataTest {
@Test
void builderShouldThrowWhenTypeIsNull() {
assertThatThrownBy(() -> AttachmentMetadata.builder()
- .type(null))
+ .type((String) null))
.isInstanceOf(IllegalArgumentException.class);
}
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
index 55c3b3c..931cf72 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
@@ -32,7 +32,7 @@ import nl.jqno.equalsverifier.EqualsVerifier;
class BlobTest {
static final BlobId ID = BlobId.fromString("123");
- static final String CONTENT_TYPE = "text/plain";
+ static final ContentType CONTENT_TYPE = ContentType.of("text/plain");
static final InputStreamSupplier PAYLOAD = () -> new ByteArrayInputStream("abc".getBytes(StandardCharsets.UTF_8));
static final int LENGTH = 3;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index 5d1cb80..8627a73 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -40,6 +40,7 @@ import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
import org.apache.james.blob.api.BlobId;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Row;
@@ -52,10 +53,10 @@ public class CassandraAttachmentDAOV2 {
public static class DAOAttachment {
private final AttachmentId attachmentId;
private final BlobId blobId;
- private final String type;
+ private final ContentType type;
private final long size;
- DAOAttachment(AttachmentId attachmentId, BlobId blobId, String type, long size) {
+ DAOAttachment(AttachmentId attachmentId, BlobId blobId, ContentType type, long size) {
this.attachmentId = attachmentId;
this.blobId = blobId;
this.type = type;
@@ -70,7 +71,7 @@ public class CassandraAttachmentDAOV2 {
return blobId;
}
- public String getType() {
+ public ContentType getType() {
return type;
}
@@ -117,7 +118,7 @@ public class CassandraAttachmentDAOV2 {
return new DAOAttachment(
AttachmentId.from(row.getString(ID)),
blobIfFactory.from(row.getString(BLOB_ID)),
- row.getString(TYPE),
+ ContentType.of(row.getString(TYPE)),
row.getLong(SIZE));
}
@@ -166,7 +167,7 @@ public class CassandraAttachmentDAOV2 {
.setUUID(ID_AS_UUID, attachment.getAttachmentId().asUUID())
.setString(ID, attachment.getAttachmentId().getId())
.setLong(SIZE, attachment.getSize())
- .setString(TYPE, attachment.getType())
+ .setString(TYPE, attachment.getType().asString())
.setString(BLOB_ID, attachment.getBlobId().asString()));
}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 8d84078..dd6edec 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageAttachmentMetadata;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.ParsedAttachment;
@@ -111,7 +112,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
}
@Override
- public Mono<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+ public Mono<AttachmentMetadata> storeAttachmentForOwner(ContentType contentType, InputStream inputStream, Username owner) {
CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(inputStream);
AttachmentId attachmentId = AttachmentId.random();
return ownerDAO.addOwner(attachmentId, owner)
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index d35f515..c5237b9 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -33,6 +33,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageAttachmentMetadata;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.ParsedAttachment;
@@ -86,7 +87,7 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
}
@Override
- public Mono<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+ public Mono<AttachmentMetadata> storeAttachmentForOwner(ContentType contentType, InputStream inputStream, Username owner) {
return Mono.fromCallable(() -> {
byte[] bytes = toByteArray(inputStream);
AttachmentMetadata attachment = AttachmentMetadata.builder()
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index 6f230b9..7a4efe2 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -34,6 +34,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
import org.reactivestreams.Publisher;
@@ -77,7 +78,7 @@ public class StoreAttachmentManager implements AttachmentManager {
}
@Override
- public Publisher<AttachmentMetadata> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession) {
+ public Publisher<AttachmentMetadata> storeAttachment(ContentType contentType, InputStream attachmentContent, MailboxSession mailboxSession) {
return attachmentMapperFactory.getAttachmentMapper(mailboxSession)
.storeAttachmentForOwner(contentType, attachmentContent, mailboxSession.getUser());
}
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
index 90674b1..ea7ff91 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.model.AttachmentMetadata;
import org.apache.james.mailbox.model.Blob;
import org.apache.james.mailbox.model.BlobId;
import org.apache.james.mailbox.model.Content;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.FetchGroup;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MessageResult;
@@ -42,7 +43,7 @@ import org.apache.james.mailbox.model.MessageResult;
import com.github.fge.lambdas.Throwing;
public class StoreBlobManager implements BlobManager {
- public static final String MESSAGE_RFC822_CONTENT_TYPE = "message/rfc822";
+ public static final ContentType MESSAGE_RFC822_CONTENT_TYPE = ContentType.of("message/rfc822");
private final AttachmentManager attachmentManager;
private final MessageIdManager messageIdManager;
private final MessageId.Factory messageIdFactory;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index 377651b..8a90153 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -28,6 +28,7 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageAttachmentMetadata;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.ParsedAttachment;
@@ -42,7 +43,7 @@ public interface AttachmentMapper extends Mapper {
List<AttachmentMetadata> getAttachments(Collection<AttachmentId> attachmentIds);
- Publisher<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream attachmentContent, Username owner);
+ Publisher<AttachmentMetadata> storeAttachmentForOwner(ContentType contentType, InputStream attachmentContent, Username owner);
List<MessageAttachmentMetadata> storeAttachmentsForMessage(Collection<ParsedAttachment> attachments, MessageId ownerMessageId) throws MailboxException;
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
index b8fc5ba..328a98d 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
@@ -28,6 +28,7 @@ import java.util.Optional;
import java.util.stream.Stream;
import org.apache.james.mailbox.model.Cid;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.ParsedAttachment;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.Body;
@@ -55,7 +56,7 @@ public class MessageParser {
private static final String CONTENT_TYPE = "Content-Type";
private static final String CONTENT_ID = "Content-ID";
private static final String CONTENT_DISPOSITION = "Content-Disposition";
- private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+ private static final ContentType DEFAULT_CONTENT_TYPE = ContentType.of("application/octet-stream");
private static final List<String> ATTACHMENT_CONTENT_DISPOSITIONS = ImmutableList.of(
ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT.toLowerCase(Locale.US),
ContentDispositionField.DISPOSITION_TYPE_INLINE.toLowerCase(Locale.US));
@@ -122,8 +123,9 @@ public class MessageParser {
private ParsedAttachment retrieveAttachment(Entity entity) throws IOException {
Optional<ContentTypeField> contentTypeField = getContentTypeField(entity);
Optional<ContentDispositionField> contentDispositionField = getContentDispositionField(entity);
- Optional<String> contentType = contentTypeField.map(ContentTypeField::getBody)
- .filter(string -> !string.isEmpty());
+ Optional<ContentType> contentType = contentTypeField.map(ContentTypeField::getBody)
+ .filter(string -> !string.isEmpty())
+ .map(ContentType::of);
Optional<String> name = name(contentTypeField, contentDispositionField);
Optional<Cid> cid = cid(readHeader(entity, CONTENT_ID, ContentIdField.class));
boolean isInline = isInline(readHeader(entity, CONTENT_DISPOSITION, ContentDispositionField.class)) && cid.isPresent();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index 583ec25..690fcbf 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -267,7 +267,8 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
return textExtractor
.extractContent(
rawData,
- attachment.getType())
+ // todo we likely want only the media type here
+ attachment.getType().asString())
.getTextualContent()
.stream();
} catch (Exception e) {
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
index 3390947..49f929e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -43,6 +43,7 @@ import org.apache.james.mailbox.model.AttachmentMetadata;
import org.apache.james.mailbox.model.Blob;
import org.apache.james.mailbox.model.BlobId;
import org.apache.james.mailbox.model.Content;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.FetchGroup;
import org.apache.james.mailbox.model.MessageResult;
import org.apache.james.mailbox.model.TestMessageId;
@@ -57,7 +58,7 @@ import com.google.common.collect.ImmutableList;
class StoreBlobManagerTest {
static final String ID = "abc";
static final AttachmentId ATTACHMENT_ID = AttachmentId.from(ID);
- static final String CONTENT_TYPE = "text/plain";
+ static final ContentType CONTENT_TYPE = ContentType.of("text/plain");
static final byte[] BYTES = "abc".getBytes(StandardCharsets.UTF_8);
static final TestMessageId MESSAGE_ID = TestMessageId.of(125);
static final BlobId BLOB_ID_ATTACHMENT = BlobId.fromString(ID);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index 0bf9af7..89c9c9c 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -31,6 +31,7 @@ import org.apache.james.core.Username;
import org.apache.james.mailbox.exception.AttachmentNotFoundException;
import org.apache.james.mailbox.model.AttachmentId;
import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.ParsedAttachment;
import org.apache.james.mailbox.store.mail.AttachmentMapper;
@@ -72,7 +73,7 @@ public abstract class AttachmentMapperTest {
@Test
void storeAttachmentForOwnerShouldReturnSuppliedInformation() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
@@ -85,7 +86,7 @@ public abstract class AttachmentMapperTest {
@Test
void getAttachmentShouldReturnTheAttachmentWhenReferenced() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
@@ -101,7 +102,7 @@ public abstract class AttachmentMapperTest {
@Test
void loadAttachmentContentShouldReturnStoredContent() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
@@ -126,10 +127,10 @@ public abstract class AttachmentMapperTest {
@Test
void getAttachmentsShouldReturnTheAttachmentsWhenSome() {
//Given
- String content1 = "content";
+ ContentType content1 = ContentType.of("content");
byte[] bytes1 = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored1 = Mono.from(attachmentMapper.storeAttachmentForOwner(content1, new ByteArrayInputStream(bytes1), OWNER)).block();
- String content2 = "content";
+ ContentType content2 = ContentType.of("content");
byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), OWNER)).block();
@@ -146,7 +147,7 @@ public abstract class AttachmentMapperTest {
@Test
void getOwnerMessageIdsShouldReturnEmptyWhenStoredWithoutMessageId() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
@@ -190,7 +191,7 @@ public abstract class AttachmentMapperTest {
@Test
void getOwnersShouldBeRetrievedWhenExplicitlySpecified() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
@@ -201,10 +202,10 @@ public abstract class AttachmentMapperTest {
@Test
void getOwnersShouldNotReturnUnrelatedOwners() throws Exception {
- String content = "content";
+ ContentType content = ContentType.of("content");
byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
- String content2 = "content";
+ ContentType content2 = ContentType.of("content");
byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
AttachmentMetadata stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), ADDITIONAL_OWNER)).block();
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index 3f29cee..0bf210a 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Optional;
import org.apache.james.mailbox.model.Cid;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.ParsedAttachment;
import org.apache.james.mdn.MDN;
import org.apache.james.mdn.MDNReport;
@@ -90,7 +91,8 @@ class MessageParserTest {
List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutContentType.eml"));
assertThat(attachments).hasSize(1);
- assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
+ assertThat(attachments.get(0).getContentType())
+ .isEqualTo(ContentType.of("application/octet-stream"));
}
@Test
@@ -98,7 +100,8 @@ class MessageParserTest {
List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithEmptyContentType.eml"));
assertThat(attachments).hasSize(1);
- assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
+ assertThat(attachments.get(0).getContentType())
+ .isEqualTo(ContentType.of("application/octet-stream"));
}
@Test
@@ -106,7 +109,8 @@ class MessageParserTest {
List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
assertThat(attachments).hasSize(1);
- assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream;\tname=\"exploits_of_a_mom.png\"");
+ assertThat(attachments.get(0).getContentType())
+ .isEqualTo(ContentType.of("application/octet-stream;\tname=\"exploits_of_a_mom.png\""));
}
@Test
@@ -128,7 +132,8 @@ class MessageParserTest {
List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithSimpleContentType.eml"));
assertThat(attachments).hasSize(1);
- assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
+ assertThat(attachments.get(0).getContentType())
+ .isEqualTo(ContentType.of("application/octet-stream"));
}
@Test
@@ -270,7 +275,8 @@ class MessageParserTest {
assertThat(attachments).hasSize(1)
.first()
- .satisfies(attachment -> assertThat(attachment.getContentType()).isEqualTo("text/calendar; charset=\"iso-8859-1\"; method=COUNTER"));
+ .satisfies(attachment -> assertThat(attachment.getContentType())
+ .isEqualTo(ContentType.of("text/calendar; charset=\"iso-8859-1\"; method=COUNTER")));
}
@Test
@@ -280,8 +286,8 @@ class MessageParserTest {
assertThat(attachments).hasSize(2)
.extracting(ParsedAttachment::getContentType)
- .containsOnly("text/calendar; charset=\"iso-8859-1\"; method=COUNTER",
- "text/calendar; charset=\"iso-4444-5\"; method=COUNTER");
+ .containsOnly(ContentType.of("text/calendar; charset=\"iso-8859-1\"; method=COUNTER"),
+ ContentType.of("text/calendar; charset=\"iso-4444-5\"; method=COUNTER"));
}
@Test
@@ -292,7 +298,7 @@ class MessageParserTest {
assertThat(attachments)
.hasSize(1)
.extracting(ParsedAttachment::getContentType)
- .containsExactly("text/calendar; charset=\"utf-8\"; method=COUNTER");
+ .containsExactly(ContentType.of("text/calendar; charset=\"utf-8\"; method=COUNTER"));
}
@Test
@@ -328,6 +334,6 @@ class MessageParserTest {
List<ParsedAttachment> result = testee.retrieveAttachments(new ByteArrayInputStream(DefaultMessageWriter.asBytes(message)));
assertThat(result).hasSize(1)
- .allMatch(attachment -> attachment.getContentType().equals("message/disposition-notification; charset=UTF-8"));
+ .allMatch(attachment -> attachment.getContentType().equals(ContentType.of("message/disposition-notification; charset=UTF-8")));
}
}
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index f17efc6..b70eab1 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -2109,7 +2109,7 @@ public abstract class SetMessagesMethodTest {
" \"keywords\": {\"$Draft\": true}," +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\"," +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\"," +
" \"size\" : " + uploadedAttachment.getSize() + "}" +
" ]," +
" \"mailboxIds\": [\"" + getDraftId(accessToken) + "\"]" +
@@ -3982,10 +3982,10 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment1.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment1.getSize() + "}," +
" {\"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment2.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment2.getSize() + ", " +
" \"cid\" : \"123456789\", " +
" \"isInline\" : true }" +
@@ -4051,10 +4051,10 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment1.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment1.getSize() + "}," +
" {\"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment2.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment2.getSize() + ", " +
" \"cid\" : \"123456789\", " +
" \"isInline\" : true }" +
@@ -4127,21 +4127,21 @@ public abstract class SetMessagesMethodTest {
" [" +
" {" +
" \"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment1.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment1.getSize() + "," +
" \"name\" : \"ديناصور.png\", " +
" \"isInline\" : false" +
" }," +
" {" +
" \"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment2.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment2.getSize() + "," +
" \"name\" : \"эволюционировать.png\", " +
" \"isInline\" : false" +
" }," +
" {" +
" \"blobId\" : \"" + uploadedAttachment3.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment3.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment3.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment3.getSize() + "," +
" \"name\" : \"进化还是不.png\"," +
" \"isInline\" : false" +
@@ -4204,21 +4204,21 @@ public abstract class SetMessagesMethodTest {
" [" +
" {" +
" \"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment1.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment1.getSize() + "," +
" \"name\" : \"ديناصور.png\", " +
" \"isInline\" : false" +
" }," +
" {" +
" \"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment2.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment2.getSize() + "," +
" \"name\" : \"эволюционировать.png\", " +
" \"isInline\" : false" +
" }," +
" {" +
" \"blobId\" : \"" + uploadedAttachment3.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment3.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment3.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment3.getSize() + "," +
" \"name\" : \"进化还是不.png\"," +
" \"isInline\" : false" +
@@ -4332,7 +4332,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment.getSize() + ", " +
" \"cid\" : \"123456789\", " +
" \"isInline\" : true }" +
@@ -4404,7 +4404,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment.getSize() + ", " +
" \"cid\" : \"123456789\", " +
" \"isInline\" : true }" +
@@ -4499,7 +4499,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment.getSize() + ", " +
" \"isInline\" : false }" +
" ]" +
@@ -4574,7 +4574,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment.getSize() + ", " +
" \"isInline\" : false }" +
" ]" +
@@ -4659,7 +4659,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment.getSize() + ", " +
" \"isInline\" : false }" +
" ]" +
@@ -5420,7 +5420,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"name\" : \"nonIndexableAttachment.html\", " +
" \"size\" : " + uploadedAttachment.getSize() + "}" +
" ]" +
@@ -5469,7 +5469,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"name\" : \"nonIndexableAttachment.html\", " +
" \"size\" : " + uploadedAttachment.getSize() + "}" +
" ]" +
@@ -5528,7 +5528,7 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment.getType().asString() + "\", " +
" \"name\" : \"nonIndexableAttachment.html\", " +
" \"size\" : " + uploadedAttachment.getSize() + "}" +
" ]" +
@@ -5582,10 +5582,10 @@ public abstract class SetMessagesMethodTest {
" \"mailboxIds\": [\"" + outboxId + "\"], " +
" \"attachments\": [" +
" {\"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment1.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment1.getSize() + "}," +
" {\"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
- " \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+ " \"type\" : \"" + uploadedAttachment2.getType().asString() + "\", " +
" \"size\" : " + uploadedAttachment2.getSize() + ", " +
" \"isInline\" : true }" +
" ]" +
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/json/ObjectMapperFactory.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/json/ObjectMapperFactory.java
index 345a80b..cb923f5 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/json/ObjectMapperFactory.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/json/ObjectMapperFactory.java
@@ -28,6 +28,7 @@ import javax.inject.Inject;
import org.apache.james.core.Username;
import org.apache.james.jmap.draft.model.mailbox.Rights;
import org.apache.james.mailbox.Role;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mdn.action.mode.DispositionActionMode;
@@ -87,10 +88,15 @@ public class ObjectMapperFactory {
mailboxIdModule.addDeserializer(DispositionSendingMode.class, new MDNSendingModeDeserializer());
mailboxIdModule.addDeserializer(DispositionType.class, new MDNTypeDeserializer());
+ SimpleModule contentTypeModule = new SimpleModule();
+ contentTypeModule.addDeserializer(ContentType.class, new ContentTypeDeserializer());
+ contentTypeModule.addSerializer(ContentType.class, new ContentTypeSerializer());
+
mailboxIdModule.setMixInAnnotation(Role.class, RoleMixIn.class);
jacksonModules = JACKSON_BASE_MODULES.add(mailboxIdModule)
.add(mdnModule)
+ .add(contentTypeModule)
.build();
}
@@ -134,6 +140,21 @@ public class ObjectMapperFactory {
}
}
+ public static class ContentTypeDeserializer extends JsonDeserializer<ContentType> {
+ @Override
+ public ContentType deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ String value = jsonParser.getValueAsString();
+ return ContentType.of(value);
+ }
+ }
+
+ public static class ContentTypeSerializer extends JsonSerializer<ContentType> {
+ @Override
+ public void serialize(ContentType value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
+ gen.writeString(value.asString());
+ }
+ }
+
public static class MDNTypeDeserializer extends JsonDeserializer<DispositionType> {
private static final ImmutableList<String> ALLOWED_VALUES = Arrays.stream(DispositionType.values())
.map(DispositionType::getValue)
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
index 4864f05..a7c9dc7 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
@@ -328,7 +328,8 @@ public class MIMEMessageConverter {
}
private ContentTypeField contentTypeField(MessageAttachmentMetadata att) {
- String type = att.getAttachment().getType();
+ // todo mailbox pojo should be able to expose itself as a mime4j object
+ String type = att.getAttachment().getType().asString();
ContentTypeField typeAsField = Fields.contentType(type);
if (att.getName().isPresent()) {
return Fields.contentType(typeAsField.getMimeType(),
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Attachment.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Attachment.java
index 271e442..1ea228f 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Attachment.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Attachment.java
@@ -22,12 +22,13 @@ package org.apache.james.jmap.draft.model;
import java.util.Objects;
import java.util.Optional;
+import org.apache.james.mailbox.model.ContentType;
+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
@JsonDeserialize(builder = Attachment.Builder.class)
public class Attachment {
@@ -39,7 +40,7 @@ public class Attachment {
@JsonPOJOBuilder(withPrefix = "")
public static class Builder {
private BlobId blobId;
- private String type;
+ private ContentType type;
private String name;
private Number size;
private String cid;
@@ -52,7 +53,13 @@ public class Attachment {
return this;
}
+ @JsonDeserialize
public Builder type(String type) {
+ this.type = ContentType.of(type);
+ return this;
+ }
+
+ public Builder type(ContentType type) {
this.type = type;
return this;
}
@@ -104,14 +111,13 @@ public class Attachment {
public Attachment build() {
Preconditions.checkState(blobId != null, "'blobId' is mandatory");
- Preconditions.checkState(!Strings.isNullOrEmpty(type), "'type' is mandatory");
Preconditions.checkState(size != null, "'size' is mandatory");
return new Attachment(blobId, type, Optional.ofNullable(name), size, Optional.ofNullable(cid), isInline, Optional.ofNullable(width), Optional.ofNullable(height));
}
}
private final BlobId blobId;
- private final String type;
+ private final ContentType type;
private final Optional<String> name;
private final Number size;
private final Optional<String> cid;
@@ -119,7 +125,7 @@ public class Attachment {
private final Optional<Number> width;
private final Optional<Number> height;
- @VisibleForTesting Attachment(BlobId blobId, String type, Optional<String> name, Number size, Optional<String> cid, boolean isInline, Optional<Number> width, Optional<Number> height) {
+ @VisibleForTesting Attachment(BlobId blobId, ContentType type, Optional<String> name, Number size, Optional<String> cid, boolean isInline, Optional<Number> width, Optional<Number> height) {
this.blobId = blobId;
this.type = type;
this.name = name;
@@ -134,7 +140,7 @@ public class Attachment {
return blobId;
}
- public String getType() {
+ public ContentType getType() {
return type;
}
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
index ddabcf7..7eb041a 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
@@ -52,6 +52,7 @@ import org.apache.james.mailbox.exception.BlobNotFoundException;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.Blob;
import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.mime4j.codec.EncoderUtil;
import org.apache.james.mime4j.codec.EncoderUtil.Usage;
@@ -222,10 +223,10 @@ public class DownloadRoutes implements JMAPRoutes {
}
}
- private Mono<Void> downloadBlob(Optional<String> optionalName, HttpServerResponse response, long blobSize, String blobContentType, InputStream stream) {
+ private Mono<Void> downloadBlob(Optional<String> optionalName, HttpServerResponse response, long blobSize, ContentType blobContentType, InputStream stream) {
return addContentDispositionHeader(optionalName, response)
.header("Content-Length", String.valueOf(blobSize))
- .header(CONTENT_TYPE, blobContentType)
+ .header(CONTENT_TYPE, blobContentType.asString())
.status(OK)
.send(ReactorUtils.toChunks(stream, BUFFER_SIZE)
.map(Unpooled::wrappedBuffer)
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
index 95e6d62..cc530b0 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
@@ -43,6 +43,7 @@ import org.apache.james.jmap.draft.model.UploadResponse;
import org.apache.james.jmap.exceptions.UnauthorizedException;
import org.apache.james.mailbox.AttachmentManager;
import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.ContentType;
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.util.ReactorUtils;
import org.slf4j.Logger;
@@ -98,7 +99,7 @@ public class UploadRoutes implements JMAPRoutes {
return response.status(BAD_REQUEST).send();
} else {
return authenticator.authenticate(request)
- .flatMap(session -> post(request, response, contentType, session)
+ .flatMap(session -> post(request, response, ContentType.of(contentType), session)
.subscriberContext(jmapAuthContext(session)))
.onErrorResume(CancelledUploadException.class, e -> handleCanceledUpload(response, e))
.onErrorResume(BadRequestException.class, e -> handleBadRequest(response, e))
@@ -111,13 +112,13 @@ public class UploadRoutes implements JMAPRoutes {
}
}
- private Mono<Void> post(HttpServerRequest request, HttpServerResponse response, String contentType, MailboxSession session) {
+ private Mono<Void> post(HttpServerRequest request, HttpServerResponse response, ContentType contentType, MailboxSession session) {
InputStream content = ReactorUtils.toInputStream(request.receive().asByteBuffer().subscribeOn(Schedulers.elastic()));
return Mono.from(metricFactory.runPublishingTimerMetric("JMAP-upload-post",
handle(contentType, content, session, response)));
}
- private Mono<Void> handle(String contentType, InputStream content, MailboxSession mailboxSession, HttpServerResponse response) {
+ private Mono<Void> handle(ContentType contentType, InputStream content, MailboxSession mailboxSession, HttpServerResponse response) {
return uploadContent(contentType, content, mailboxSession)
.flatMap(storedContent -> {
try {
@@ -131,11 +132,11 @@ public class UploadRoutes implements JMAPRoutes {
});
}
- private Mono<UploadResponse> uploadContent(String contentType, InputStream inputStream, MailboxSession session) {
+ private Mono<UploadResponse> uploadContent(ContentType contentType, InputStream inputStream, MailboxSession session) {
return Mono.from(attachmentManager.storeAttachment(contentType, inputStream, session))
.map(attachment -> UploadResponse.builder()
.blobId(attachment.getAttachmentId().getId())
- .type(attachment.getType())
+ .type(attachment.getType().asString())
.size(attachment.getSize())
.build())
.onErrorMap(e -> e.getCause() instanceof EOFException, any -> new CancelledUploadException())
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/AttachmentTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/AttachmentTest.java
index 9e7e122..b81c986 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/AttachmentTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/AttachmentTest.java
@@ -22,6 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.Optional;
+import org.apache.james.mailbox.model.ContentType;
import org.junit.Test;
public class AttachmentTest {
@@ -46,7 +47,7 @@ public class AttachmentTest {
Attachment.builder().blobId(BlobId.of("blobId")).type("type").name("name").build();
}
- @Test(expected = IllegalStateException.class)
+ @Test(expected = IllegalArgumentException.class)
public void buildShouldThrowWhenTypeIsEmpty() {
Attachment.builder().blobId(BlobId.of("blobId")).type("").name("name").size(123).build();
}
@@ -54,7 +55,7 @@ public class AttachmentTest {
@Test
public void buildShouldWorkWhenMandatoryFieldsArePresent() {
Number attachmentSize = Number.fromLong(123);
- Attachment expected = new Attachment(BlobId.of("blobId"), "type", Optional.empty(), attachmentSize, Optional.empty(), false, Optional.empty(), Optional.empty());
+ Attachment expected = new Attachment(BlobId.of("blobId"), ContentType.of("type"), Optional.empty(), attachmentSize, Optional.empty(), false, Optional.empty(), Optional.empty());
Attachment tested = Attachment.builder()
.blobId(BlobId.of("blobId"))
.type("type")
@@ -68,7 +69,7 @@ public class AttachmentTest {
Number attachmentSize = Number.fromLong(123);
Optional<Number> attachmentWidth = Optional.of(Number.fromLong(456L));
Optional<Number> attachmentHeight = Optional.of(Number.fromLong(789L));
- Attachment expected = new Attachment(BlobId.of("blobId"), "type", Optional.of("name"), attachmentSize, Optional.of("cid"), true,
+ Attachment expected = new Attachment(BlobId.of("blobId"), ContentType.of("type"), Optional.of("name"), attachmentSize, Optional.of("cid"), true,
attachmentWidth, attachmentHeight);
Attachment tested = Attachment.builder()
.blobId(BlobId.of("blobId"))
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org