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

Reply via email to