diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index e7ec9c49..88dae8ac 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -649,6 +649,14 @@ public abstract class ExchangeSession { * @return true if condition is empty */ public boolean isEmpty(); + + /** + * Test if the contact matches current condition. + * + * @param contact Exchange Contact + * @return true if contact matches condition + */ + public abstract boolean isMatch(ExchangeSession.Contact contact); } /** @@ -708,6 +716,27 @@ public abstract class ExchangeSession { } return isEmpty; } + + public boolean isMatch(ExchangeSession.Contact contact) { + if (operator == Operator.And) { + for (Condition condition : conditions) { + if (!condition.isMatch(contact)) { + return false; + } + } + return true; + } else if (operator == Operator.Or) { + for (Condition condition : conditions) { + if (condition.isMatch(contact)) { + return true; + } + } + return false; + } else { + return false; + } + } + } /** @@ -724,6 +753,9 @@ public abstract class ExchangeSession { return condition.isEmpty(); } + public boolean isMatch(ExchangeSession.Contact contact) { + return !condition.isMatch(contact); + } } /** @@ -741,6 +773,19 @@ public abstract class ExchangeSession { public boolean isEmpty() { return false; } + + public boolean isMatch(ExchangeSession.Contact contact) { + String actualValue = contact.get(attributeName); + if (operator == Operator.IsNull) { + return actualValue == null; + } else if (operator == Operator.IsFalse) { + return "false".equals(actualValue); + } else if (operator == Operator.IsTrue) { + return "true".equals(actualValue); + } else { + return false; + } + } } /** diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java index 58f90868..298e9dfa 100644 --- a/src/java/davmail/exchange/dav/DavExchangeSession.java +++ b/src/java/davmail/exchange/dav/DavExchangeSession.java @@ -449,6 +449,24 @@ public class DavExchangeSession extends ExchangeSession { buffer.append('\''); } } + + public boolean isMatch(ExchangeSession.Contact contact) { + String lowerCaseValue = value.toLowerCase(); + String actualValue = contact.get(attributeName); + if (actualValue == null) { + return false; + } + actualValue = actualValue.toLowerCase(); + if (operator == Operator.IsEqualTo) { + return actualValue.equals(lowerCaseValue); + } else if (operator == Operator.Like) { + return actualValue.contains(lowerCaseValue); + } else if (operator == Operator.StartsWith) { + return actualValue.startsWith(lowerCaseValue); + } else { + return false; + } + } } protected static class HeaderCondition extends AttributeCondition { diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index df3fc61a..26c86e6a 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -315,6 +315,14 @@ public class EwsExchangeSession extends ExchangeSession { } } } + + public List getConditions() { + return conditions; + } + + public Operator getOperator() { + return operator; + } } protected static class NotCondition extends ExchangeSession.NotCondition implements SearchExpression { @@ -389,9 +397,22 @@ public class EwsExchangeSession extends ExchangeSession { return attributeName; } - public ContainmentMode getContainmentMode() { - return containmentMode; + public boolean isMatch(ExchangeSession.Contact contact) { + String lowerCaseValue = value.toLowerCase(); + + String actualValue = contact.get(attributeName); + if (actualValue == null) { + return false; + } + actualValue = actualValue.toLowerCase(); + if (operator == Operator.IsEqualTo) { + return value.equals(actualValue); + } else { + return operator == Operator.Contains && ((containmentMode.equals(ContainmentMode.Substring) && actualValue.contains(lowerCaseValue)) || + (containmentMode.equals(ContainmentMode.Prefixed) && actualValue.startsWith(lowerCaseValue))); + } } + } protected static class HeaderCondition extends AttributeCondition { @@ -424,6 +445,11 @@ public class EwsExchangeSession extends ExchangeSession { return false; } + public boolean isMatch(ExchangeSession.Contact contact) { + String actualValue = contact.get(attributeName); + return actualValue == null; + } + } @Override @@ -704,7 +730,7 @@ public class EwsExchangeSession extends ExchangeSession { /** * Empty constructor for GalFind */ - public Contact() { + protected Contact() { } protected Set buildProperties() { @@ -1246,14 +1272,40 @@ public class EwsExchangeSession extends ExchangeSession { GALFIND_ATTRIBUTE_MAP.put("email3", "EmailAddress1"); } - protected List galFind(Condition condition) throws IOException { - List contacts = new ArrayList(); - if (condition instanceof AttributeCondition) { + protected Contact buildGalfindContact(EWSMethod.Item response) { + Contact contact = new Contact(); + contact.setName(response.get("DisplayName")); + for (Map.Entry entry : GALFIND_ATTRIBUTE_MAP.entrySet()) { + String attributeValue = response.get(entry.getValue()); + if (attributeValue != null) { + contact.put(entry.getKey(), attributeValue); + } + } + return contact; + } + + protected Map galFind(Condition condition) throws IOException { + Map contacts = new HashMap(); + if (condition instanceof MultiCondition) { + List conditions = ((MultiCondition) condition).getConditions(); + Operator operator = ((MultiCondition) condition).getOperator(); + if (operator == Operator.Or) { + for (Condition innerCondition : conditions) { + contacts.putAll(galFind(innerCondition)); + } + } else if (operator == Operator.And && !conditions.isEmpty()) { + Map innerContacts = galFind(conditions.get(0)); + for (ExchangeSession.Contact contact : innerContacts.values()) { + if (condition.isMatch(contact)) { + contacts.put(contact.getName(), contact); + } + } + } + } else if (condition instanceof AttributeCondition) { String mappedAttributeName = GALFIND_ATTRIBUTE_MAP.get(((AttributeCondition) condition).getAttributeName()); if (mappedAttributeName != null) { String value = ((AttributeCondition) condition).getValue().toLowerCase(); Operator operator = ((AttributeCondition) condition).getOperator(); - ContainmentMode containmentMode = ((AttributeCondition) condition).getContainmentMode(); String searchValue = value; if (mappedAttributeName.startsWith("EmailAddress")) { searchValue = "smtp:" + searchValue; @@ -1265,27 +1317,9 @@ public class EwsExchangeSession extends ExchangeSession { executeMethod(resolveNamesMethod); List responses = resolveNamesMethod.getResponseItems(); for (EWSMethod.Item response : responses) { - String actualValue = response.get(mappedAttributeName); - if (actualValue != null) { - actualValue = actualValue.toLowerCase(); - } - if (actualValue != null && ( - (operator == Operator.IsEqualTo && value.equals(actualValue)) || - (operator == Operator.Contains && containmentMode == ContainmentMode.Substring && actualValue.contains(value)) | - (operator == Operator.Contains && containmentMode == ContainmentMode.Prefixed && actualValue.startsWith(value)) - )) { - Contact contact = new Contact(); - contact.setName(response.get("DisplayName")); - for (Map.Entry entry : GALFIND_ATTRIBUTE_MAP.entrySet()) { - String attributeValue = response.get(entry.getValue()); - if (attributeValue != null) { - contact.put(entry.getKey(), attributeValue); - } - } - contacts.add(contact); - } else if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Actual value " + actualValue + " does not match " + - mappedAttributeName + ' ' + operator + ' ' + containmentMode + ' ' + value); + Contact contact = buildGalfindContact(response); + if (condition.isMatch(contact)) { + contacts.put(contact.getName(), contact); } } } diff --git a/src/test/davmail/exchange/ews/TestEwsExchangeSession.java b/src/test/davmail/exchange/ews/TestEwsExchangeSession.java index 5f5fce3e..2142a19d 100644 --- a/src/test/davmail/exchange/ews/TestEwsExchangeSession.java +++ b/src/test/davmail/exchange/ews/TestEwsExchangeSession.java @@ -23,6 +23,7 @@ import davmail.exchange.ExchangeSession; import java.io.IOException; import java.util.List; +import java.util.Map; /** * Webdav specific unit tests @@ -47,18 +48,21 @@ public class TestEwsExchangeSession extends AbstractExchangeSessionTestCase { public void testGalFind() throws IOException { // find a set of contacts - List contacts = ewsSession.galFind(ewsSession.startsWith("cn", "a")); - for (ExchangeSession.Contact contact : contacts) { + Map contacts = ewsSession.galFind(ewsSession.startsWith("cn", "a")); + for (ExchangeSession.Contact contact : contacts.values()) { System.out.println(contact); } - if (contacts.size() > 0) { - ExchangeSession.Contact testContact = contacts.get(0); + if (!contacts.isEmpty()) { + ExchangeSession.Contact testContact = contacts.values().iterator().next(); contacts = ewsSession.galFind(ewsSession.isEqualTo("cn", testContact.get("cn"))); assertEquals(1, contacts.size()); contacts = ewsSession.galFind(ewsSession.isEqualTo("email1", testContact.get("email1"))); assertEquals(1, contacts.size()); contacts = ewsSession.galFind(ewsSession.startsWith("email1", testContact.get("email1"))); assertEquals(1, contacts.size()); + contacts = ewsSession.galFind(ewsSession.and(ewsSession.isEqualTo("cn", testContact.get("cn")), + ewsSession.startsWith("email1", testContact.get("email1")))); + assertEquals(1, contacts.size()); } }