JAMES-2366 Break getMappings into smaller chunks Handling non recursive mappings first allow to gain one level of indentation
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a64ee174 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a64ee174 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a64ee174 Branch: refs/heads/master Commit: a64ee17466d7fb591971496252e8341830f3de62 Parents: 465da0e Author: Matthieu Baechler <matth...@apache.org> Authored: Tue Apr 17 16:37:08 2018 +0200 Committer: Matthieu Baechler <matth...@apache.org> Committed: Tue Apr 24 14:45:26 2018 +0200 ---------------------------------------------------------------------- .../java/org/apache/james/rrt/lib/Mapping.java | 2 + .../rrt/lib/AbstractRecipientRewriteTable.java | 119 +++++++++---------- .../org/apache/james/rrt/lib/MappingImpl.java | 30 +++++ 3 files changed, 87 insertions(+), 64 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/a64ee174/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java ---------------------------------------------------------------------- diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java index d85a6d2..3a7757a 100644 --- a/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java +++ b/server/data/data-api/src/main/java/org/apache/james/rrt/lib/Mapping.java @@ -100,4 +100,6 @@ public interface Mapping { String getErrorMessage(); + Optional<String> apply(MailAddress input); + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/a64ee174/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java ---------------------------------------------------------------------- diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java index 80d526d..ce9701c 100644 --- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java +++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/AbstractRecipientRewriteTable.java @@ -22,9 +22,10 @@ import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Stream; import javax.inject.Inject; -import javax.mail.internet.ParseException; +import javax.mail.internet.AddressException; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.HierarchicalConfiguration; @@ -39,6 +40,7 @@ import org.apache.james.rrt.lib.Mapping.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.github.fge.lambdas.Throwing; import com.google.common.base.Preconditions; public abstract class AbstractRecipientRewriteTable implements RecipientRewriteTable, Configurable { @@ -111,57 +113,62 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT throw new ErrorMappingException(targetMappings.getError().getErrorMessage()); } - MappingsImpl.Builder mappings = MappingsImpl.builder(); + try { + return MappingsImpl.fromMappings( + targetMappings.asStream() + .flatMap(Throwing.<Mapping, Stream<Mapping>>function(target -> convertAndRecurseMapping(target, user, domain, mappingLimit)).sneakyThrow())); + } catch (EmptyMappingException e) { + return MappingsImpl.empty(); + } + } - for (String target : targetMappings.asStrings()) { - Type type = Mapping.detectType(target); - Optional<String> maybeAddressWithMappingApplied = applyMapping(user, domain, target, type); + private static class EmptyMappingException extends RuntimeException { - if (!maybeAddressWithMappingApplied.isPresent()) { - continue; - } - String addressWithMappingApplied = maybeAddressWithMappingApplied.get(); - LOGGER.debug("Valid virtual user mapping {}@{} to {}", user, domain.name(), addressWithMappingApplied); - - if (recursive) { - - String userName; - Domain targetDomain; - String[] args = addressWithMappingApplied.split("@"); - - if (args.length > 1) { - userName = args[0]; - targetDomain = Domain.of(args[1]); - } else { - // TODO Is that the right todo here? - userName = addressWithMappingApplied; - targetDomain = domain; - } - - // Check if the returned mapping is the same as the - // input. If so return null to avoid loops - if (userName.equalsIgnoreCase(user) && targetDomain.equals(domain)) { - if (type.equals(Type.Forward)) { - mappings.add(toMapping(addressWithMappingApplied, type)); - continue; - } - return MappingsImpl.empty(); - } - - Mappings childMappings = getMappings(userName, targetDomain, mappingLimit - 1); - - if (childMappings.isEmpty()) { - // add mapping - mappings.add(toMapping(addressWithMappingApplied, type)); - } else { - mappings = mappings.addAll(childMappings); - } - - } else { - mappings.add(toMapping(addressWithMappingApplied, type)); + } + + private Stream<Mapping> convertAndRecurseMapping(Mapping target, String user, Domain domain, int remainingLoops) throws ErrorMappingException, RecipientRewriteTableException, EmptyMappingException, AddressException { + Optional<String> maybeAddressWithMappingApplied = target.apply(new MailAddress(user, domain)); + + if (!maybeAddressWithMappingApplied.isPresent()) { + return Stream.empty(); + } + String addressWithMappingApplied = maybeAddressWithMappingApplied.get(); + LOGGER.debug("Valid virtual user mapping {}@{} to {}", user, domain.name(), addressWithMappingApplied); + + if (!recursive) { + return Stream.of(toMapping(addressWithMappingApplied, target.getType())); + } + + String userName; + Domain targetDomain; + String[] args = addressWithMappingApplied.split("@"); + + if (args.length > 1) { + userName = args[0]; + targetDomain = Domain.of(args[1]); + } else { + // TODO Is that the right todo here? + userName = addressWithMappingApplied; + targetDomain = domain; + } + + // Check if the returned mapping is the same as the + // input. If so return null to avoid loops + if (userName.equalsIgnoreCase(user) && targetDomain.equals(domain)) { + if (target.getType().equals(Type.Forward)) { + return Stream.of(toMapping(addressWithMappingApplied, target.getType())); } + //throw exception ? + throw new EmptyMappingException(); + } + + Mappings childMappings = getMappings(userName, targetDomain, remainingLoops - 1); + + if (childMappings.isEmpty()) { + return Stream.of(toMapping(addressWithMappingApplied, target.getType())); + } else { + return childMappings.asStream(); } - return mappings.build(); } private Mapping toMapping(String mappedAddress, Type type) { @@ -178,22 +185,6 @@ public abstract class AbstractRecipientRewriteTable implements RecipientRewriteT throw new IllegalArgumentException("unhandled enum type"); } - private Optional<String> applyMapping(String user, Domain domain, String target, Type type) { - switch (type) { - case Regex: - try { - return RecipientRewriteTableUtil.regexMap(new MailAddress(user, domain.asString()), MappingImpl.of(target)); - } catch (PatternSyntaxException | ParseException e) { - LOGGER.error("Exception during regexMap processing: ", e); - return Optional.ofNullable(target); - } - case Domain: - return Optional.of(user + "@" + Type.Domain.withoutPrefix(target)); - default: - return Optional.of(type.withoutPrefix(target)); - } - } - @Override public void addRegexMapping(String user, Domain domain, String regex) throws RecipientRewriteTableException { try { http://git-wip-us.apache.org/repos/asf/james-project/blob/a64ee174/server/data/data-library/src/main/java/org/apache/james/rrt/lib/MappingImpl.java ---------------------------------------------------------------------- diff --git a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/MappingImpl.java b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/MappingImpl.java index c16d60c..54d265e 100644 --- a/server/data/data-library/src/main/java/org/apache/james/rrt/lib/MappingImpl.java +++ b/server/data/data-library/src/main/java/org/apache/james/rrt/lib/MappingImpl.java @@ -23,18 +23,23 @@ package org.apache.james.rrt.lib; import java.io.Serializable; import java.util.Optional; import java.util.function.Supplier; +import java.util.regex.PatternSyntaxException; import javax.mail.internet.AddressException; import org.apache.james.core.Domain; import org.apache.james.core.MailAddress; import org.apache.james.rrt.api.RecipientRewriteTableException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Objects; import com.google.common.base.Preconditions; public class MappingImpl implements Mapping, Serializable { + private static final Logger LOGGER = LoggerFactory.getLogger(MappingImpl.class); + private static final long serialVersionUID = 1L; public static MappingImpl of(String mapping) { @@ -136,6 +141,31 @@ public class MappingImpl implements Mapping, Serializable { } @Override + public Optional<String> apply(MailAddress address) { + switch (getType()) { + case Regex: + try { + return RecipientRewriteTableUtil.regexMap(address, this); + } catch (PatternSyntaxException e) { + LOGGER.error("Exception during regexMap processing: ", e); + return Optional.of(asString()); + } + case Domain: + return Optional.of(address.getLocalPart() + "@" + mapping); + case Forward: + return Optional.of(mapping); + case Group: + return Optional.of(mapping); + case Address: + return Optional.of(mapping); + case Error: + return Optional.empty(); + } + throw new IllegalArgumentException("unhandle enum type: " + getType()); + } + + + @Override public final boolean equals(Object other) { if (other instanceof MappingImpl) { MappingImpl otherMapping = (MappingImpl) other; --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org