JAMES-2578 MailImpl internal data model should rely on Attribute*
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ee085ee6 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ee085ee6 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ee085ee6 Branch: refs/heads/master Commit: ee085ee65dbe374eb1ebc273305a2e1c11f45b7c Parents: 5b98f73 Author: Benoit Tellier <[email protected]> Authored: Fri Nov 2 11:02:25 2018 +0700 Committer: Antoine Duprat <[email protected]> Committed: Mon Nov 5 11:58:06 2018 +0100 ---------------------------------------------------------------------- .../org/apache/james/server/core/MailImpl.java | 92 ++++++++++++++------ 1 file changed, 66 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ee085ee6/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java ---------------------------------------------------------------------- diff --git a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java index 28626cc..c168c7a 100644 --- a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java +++ b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java @@ -37,6 +37,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; import javax.mail.Address; @@ -65,6 +67,7 @@ import com.github.fge.lambdas.Throwing; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.primitives.Chars; @@ -118,7 +121,7 @@ public class MailImpl implements Disposable, Mail { private Optional<String> state; private Optional<String> errorMessage; private Optional<Date> lastUpdated; - private Map<String, Serializable> attributes; + private Map<AttributeName, Attribute> attributes; private Optional<String> remoteAddr; private Optional<String> remoteHost; private PerRecipientHeaders perRecipientHeaders; @@ -188,7 +191,6 @@ public class MailImpl implements Disposable, Mail { return this; } - public Builder sender(MaybeSender sender) { this.sender = sender.asOptional(); return this; @@ -213,13 +215,28 @@ public class MailImpl implements Disposable, Mail { return this; } + @Deprecated public Builder attribute(String name, Serializable object) { - this.attributes.put(name, object); + attribute(Attribute.convertToAttribute(name, object)); return this; } + @Deprecated public Builder attributes(Map<String, Serializable> attributes) { - this.attributes.putAll(attributes); + this.attributes(toAttributeMap(attributes).values()); + return this; + } + + public Builder attribute(Attribute attribute) { + this.attributes.put(attribute.getName(), attribute); + return this; + } + + public Builder attributes(Collection<Attribute> attributes) { + this.attributes.putAll(attributes.stream() + .collect(ImmutableMap.toImmutableMap( + Attribute::getName, + Function.identity()))); return this; } @@ -252,7 +269,7 @@ public class MailImpl implements Disposable, Mail { state.ifPresent(mail::setState); errorMessage.ifPresent(mail::setErrorMessage); lastUpdated.ifPresent(mail::setLastUpdated); - mail.setAttributes(new HashMap<>(attributes)); + mail.setAttributes(attributes); remoteAddr.ifPresent(mail::setRemoteAddr); remoteHost.ifPresent(mail::setRemoteHost); mail.perRecipientSpecificHeaders.addAll(perRecipientHeaders); @@ -260,6 +277,15 @@ public class MailImpl implements Disposable, Mail { } } + private static Map<AttributeName, Attribute> toAttributeMap(Map<String, ?> attributes) { + return attributes.entrySet() + .stream() + .map(entry -> Attribute.convertToAttribute(entry.getKey(), entry.getValue())) + .collect(Collectors.toMap( + Attribute::getName, + Function.identity())); + } + private static ImmutableList<MailAddress> getRecipients(MimeMessage mimeMessage) throws MessagingException { return Arrays.stream(mimeMessage.getAllRecipients()) .map(Throwing.function(MailImpl::castToMailAddress).sneakyThrow()) @@ -365,7 +391,7 @@ public class MailImpl implements Disposable, Mail { /** * Attributes added to this MailImpl instance */ - private Map<String, Object> attributes; + private Map<AttributeName, Attribute> attributes; /** * Specific headers for some recipients * These headers will be added at delivery time @@ -656,7 +682,7 @@ public class MailImpl implements Disposable, Mail { // the following is under try/catch to be backwards compatible // with messages created with James version <= 2.2.0a8 try { - attributes = (HashMap<String, Object>) in.readObject(); + setAttributesRaw((Map<String, Object>) in.readObject()); } catch (OptionalDataException ode) { if (ode.eof) { attributes = new HashMap<>(); @@ -682,7 +708,7 @@ public class MailImpl implements Disposable, Mail { out.writeObject(remoteHost); out.writeObject(remoteAddr); out.writeObject(lastUpdated); - out.writeObject(attributes); + out.writeObject(getAttributesRaw()); out.writeObject(perRecipientSpecificHeaders); } @@ -706,12 +732,11 @@ public class MailImpl implements Disposable, Mail { * @since 2.2.0 */ public Map<String, Object> getAttributesRaw() { - return Maps.newHashMap(attributes); - } - - public void setAttributes(Map<String, Object> attr) { - Preconditions.checkNotNull(attr); - this.attributes = attr; + return attributes.values() + .stream() + .collect(Collectors.toMap( + attribute -> attribute.getName().asString(), + attribute -> attribute.getValue().value())); } /** @@ -728,47 +753,52 @@ public class MailImpl implements Disposable, Mail { * @since 2.2.0 */ public void setAttributesRaw(Map<String, Object> attr) { - this.attributes = Optional.ofNullable(attr).orElse(new HashMap<>()); + this.attributes = toAttributeMap(attr); + } + + private void setAttributes(Map<AttributeName, Attribute> attr) { + this.attributes = Maps.newHashMap(attr); } @Override public Stream<Attribute> attributes() { - return this.attributes.entrySet().stream().map(entry -> new Attribute(AttributeName.of(entry.getKey()), AttributeValue.ofAny(entry.getValue()))); + return this.attributes.values().stream(); } @Override public Serializable getAttribute(String key) { - return (Serializable) attributes.get(key); + return toSerializable(attributes.get(AttributeName.of(key))); } @Override public Optional<Attribute> getAttribute(AttributeName name) { - return Optional.ofNullable(attributes.get(name.asString())).map(value -> new Attribute(name, AttributeValue.ofAny(value))); + return Optional.ofNullable(attributes.get(name)); } @Override public Serializable setAttribute(String key, Serializable object) { Preconditions.checkNotNull(key, "Key of an attribute should not be null"); - Serializable previous = (Serializable) attributes.put(key, object); - return previous; + Attribute attribute = Attribute.convertToAttribute(key, object); + Attribute previous = attributes.put(attribute.getName(), attribute); + + return toSerializable(previous); } @Override public Optional<Attribute> setAttribute(Attribute attribute) { Preconditions.checkNotNull(attribute.getName().asString(), "AttributeName should not be null"); - Object previous = this.attributes.put(attribute.getName().asString(), attribute.getValue().value()); - return Optional.ofNullable(previous).map(value -> new Attribute(attribute.getName(), AttributeValue.ofAny(value))); + return Optional.ofNullable(this.attributes.put(attribute.getName(), attribute)); } @Override public Serializable removeAttribute(String key) { - return (Serializable) attributes.remove(key); + return toSerializable(attributes.remove(AttributeName.of(key))); } @Override public Optional<Attribute> removeAttribute(AttributeName attributeName) { - Object previous = attributes.remove(attributeName.asString()); - return Optional.ofNullable(previous).map(value -> new Attribute(attributeName, AttributeValue.ofAny(value))); + Attribute previous = attributes.remove(attributeName); + return Optional.ofNullable(previous); } @Override @@ -778,7 +808,10 @@ public class MailImpl implements Disposable, Mail { @Override public Iterator<String> getAttributeNames() { - return attributes.keySet().iterator(); + return attributes.keySet() + .stream() + .map(AttributeName::asString) + .iterator(); } @Override @@ -786,6 +819,13 @@ public class MailImpl implements Disposable, Mail { return attributes().map(Attribute::getName); } + private Serializable toSerializable(Attribute previous) { + return (Serializable) Optional.ofNullable(previous) + .map(Attribute::getValue) + .map(AttributeValue::getValue) + .orElse(null); + } + @Override public boolean hasAttributes() { return !attributes.isEmpty(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
