Search in sources :

Example 11 with Node

use of org.apache.jsieve.parser.generated.Node in project zm-mailbox by Zimbra.

the class SieveVisitor method acceptTest.

private void acceptTest(Node node, RuleProperties props) throws ServiceException {
    visitTest(node, VisitPhase.begin, props);
    String nodeName = getNodeName(node);
    if ("not".equalsIgnoreCase(nodeName)) {
        props.isNegativeTest = true;
        accept(node, props);
    } else {
        if ("allof".equalsIgnoreCase(nodeName)) {
            props.condition = Sieve.Condition.allof;
            visitRule(node, VisitPhase.begin, props);
            accept(node, props);
            visitRule(node, VisitPhase.end, props);
        } else if ("anyof".equalsIgnoreCase(nodeName)) {
            props.condition = Sieve.Condition.anyof;
            visitRule(node, VisitPhase.begin, props);
            accept(node, props);
            visitRule(node, VisitPhase.end, props);
        } else if ("header".equalsIgnoreCase(nodeName) || "mime_header".equalsIgnoreCase(nodeName)) {
            boolean caseSensitive = false;
            List<String> headers;
            String value;
            Sieve.ValueComparison valueComparison = null;
            boolean isCount = false;
            Sieve.StringComparison comparison = null;
            Sieve.Comparator comparator = null;
            int headersArgIndex = 0;
            // There can be up to two tag arguments
            SieveNode firstTagArgNode, secondTagArgNode;
            firstTagArgNode = (SieveNode) getNode(node, 0, 0);
            if (firstTagArgNode.getValue() instanceof TagArgument) {
                String argStr = stripLeadingColon(firstTagArgNode.getValue().toString());
                try {
                    if ("count".equals(argStr) || "value".equals(argStr)) {
                        if ("count".equals(argStr)) {
                            isCount = true;
                        }
                        valueComparison = Sieve.ValueComparison.valueOf(getValue(node, 0, 1, 0, 0));
                        headersArgIndex += 2;
                        secondTagArgNode = (SieveNode) getNode(node, 0, 2);
                        if (secondTagArgNode.getValue() instanceof TagArgument) {
                            comparator = Sieve.Comparator.fromString(getValue(node, 0, 3, 0, 0));
                            headersArgIndex += 2;
                        }
                    } else {
                        // assume that the first tag arg is match-type arg
                        comparison = Sieve.StringComparison.valueOf(argStr);
                        headersArgIndex++;
                        secondTagArgNode = (SieveNode) getNode(node, 0, 1);
                        if (secondTagArgNode.getValue() instanceof TagArgument) {
                            caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 2, 0, 0));
                            headersArgIndex += 2;
                        }
                    }
                } catch (IllegalArgumentException e) {
                    // so the first tag arg is not match-type arg, it must be :comparator arg then
                    caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 1, 0, 0));
                    headersArgIndex += 2;
                    secondTagArgNode = (SieveNode) getNode(node, 0, 2);
                    if (secondTagArgNode.getValue() instanceof TagArgument) {
                        argStr = stripLeadingColon(secondTagArgNode.getValue().toString());
                        comparison = Sieve.StringComparison.fromString(argStr);
                        headersArgIndex++;
                    }
                }
            }
            headers = getMultiValue(node, 0, headersArgIndex, 0);
            value = getValue(node, 0, headersArgIndex + 1, 0, 0);
            validateCountComparator(isCount, comparator);
            if ("header".equalsIgnoreCase(nodeName)) {
                if (valueComparison != null) {
                    visitHeaderTest(node, VisitPhase.begin, props, headers, valueComparison, isCount, value);
                    accept(node, props);
                    visitHeaderTest(node, VisitPhase.end, props, headers, valueComparison, isCount, value);
                } else {
                    visitHeaderTest(node, VisitPhase.begin, props, headers, comparison, caseSensitive, value);
                    accept(node, props);
                    visitHeaderTest(node, VisitPhase.end, props, headers, comparison, caseSensitive, value);
                }
            } else {
                visitMimeHeaderTest(node, VisitPhase.begin, props, headers, comparison, caseSensitive, value);
                accept(node, props);
                visitMimeHeaderTest(node, VisitPhase.end, props, headers, comparison, caseSensitive, value);
            }
        } else if ("address".equalsIgnoreCase(nodeName) || "envelope".equalsIgnoreCase(nodeName)) {
            Sieve.AddressPart part = Sieve.AddressPart.all;
            Sieve.StringComparison comparison = Sieve.StringComparison.is;
            boolean caseSensitive = false;
            List<String> headers;
            String value;
            int nextArgIndex = 0;
            boolean isCount = false;
            Sieve.ValueComparison valueComparison = null;
            Sieve.Comparator comparator = null;
            SieveNode firstTagArgNode;
            firstTagArgNode = (SieveNode) getNode(node, 0, 0);
            if (firstTagArgNode.getValue() instanceof TagArgument) {
                String firstArgStr = firstTagArgNode.getValue().toString();
                if (":count".equals(firstArgStr) || ":value".equals(firstArgStr)) {
                    if (":count".equals(firstArgStr)) {
                        isCount = true;
                    }
                    valueComparison = Sieve.ValueComparison.valueOf(getValue(node, 0, 1, 0, 0));
                    nextArgIndex += 2;
                }
            }
            SieveNode argNode = (SieveNode) getNode(node, 0, nextArgIndex);
            // There can be up to three tag arguments
            for (int i = 0; i < 3 && argNode.getValue() instanceof TagArgument; i++) {
                TagArgument tagArg = (TagArgument) argNode.getValue();
                if (tagArg.isComparator()) {
                    comparator = Sieve.Comparator.fromString(getValue(node, 0, nextArgIndex + 1, 0, 0));
                    caseSensitive = Sieve.Comparator.ioctet == comparator;
                    nextArgIndex += 2;
                } else {
                    String argStr = stripLeadingColon(argNode.getValue().toString());
                    try {
                        // first assume that the next tag arg is match-type arg
                        comparison = Sieve.StringComparison.valueOf(argStr);
                    } catch (IllegalArgumentException e) {
                        // so the next tag arg is not match-type arg, it must be address-part arg then
                        part = Sieve.AddressPart.fromString(argStr);
                    }
                    nextArgIndex++;
                }
                argNode = (SieveNode) getNode(node, 0, nextArgIndex);
            }
            headers = getMultiValue(node, 0, nextArgIndex, 0);
            value = getValue(node, 0, nextArgIndex + 1, 0, 0);
            validateCountComparator(isCount, comparator);
            if ("envelope".equalsIgnoreCase(nodeName)) {
                if (valueComparison != null) {
                    visitEnvelopeTest(node, VisitPhase.begin, props, headers, part, valueComparison, isCount, value);
                    accept(node, props);
                    visitEnvelopeTest(node, VisitPhase.end, props, headers, part, valueComparison, isCount, value);
                } else {
                    visitEnvelopeTest(node, VisitPhase.begin, props, headers, part, comparison, caseSensitive, value);
                    accept(node, props);
                    visitEnvelopeTest(node, VisitPhase.end, props, headers, part, comparison, caseSensitive, value);
                }
            } else {
                if (valueComparison != null) {
                    visitAddressTest(node, VisitPhase.begin, props, headers, part, valueComparison, isCount, value);
                    accept(node, props);
                    visitAddressTest(node, VisitPhase.end, props, headers, part, valueComparison, isCount, value);
                } else {
                    visitAddressTest(node, VisitPhase.begin, props, headers, part, comparison, caseSensitive, value);
                    accept(node, props);
                    visitAddressTest(node, VisitPhase.end, props, headers, part, comparison, caseSensitive, value);
                }
            }
        } else if ("exists".equalsIgnoreCase(nodeName)) {
            String header = getValue(node, 0, 0, 0, 0);
            visitHeaderExistsTest(node, VisitPhase.begin, props, header);
            accept(node, props);
            visitHeaderExistsTest(node, VisitPhase.end, props, header);
        } else if ("size".equalsIgnoreCase(nodeName)) {
            String s = stripLeadingColon(getValue(node, 0, 0));
            Sieve.NumberComparison comparison = Sieve.NumberComparison.fromString(s);
            SieveNode sizeNode = (SieveNode) getNode(node, 0, 1);
            String sizeString = sizeNode.getFirstToken().toString();
            int size;
            try {
                size = FilterUtil.parseSize(sizeString);
            } catch (NumberFormatException e) {
                throw ServiceException.INVALID_REQUEST("Invalid size value " + sizeString, e);
            }
            visitSizeTest(node, VisitPhase.begin, props, comparison, size, sizeString);
            accept(node, props);
            visitSizeTest(node, VisitPhase.end, props, comparison, size, sizeString);
        } else if ("date".equalsIgnoreCase(nodeName)) {
            String s = stripLeadingColon(getValue(node, 0, 0));
            Sieve.DateComparison comparison = Sieve.DateComparison.fromString(s);
            String dateString = getValue(node, 0, 1, 0, 0);
            Date date = Sieve.DATE_PARSER.parse(dateString);
            if (date == null) {
                throw ServiceException.PARSE_ERROR("Invalid date value: " + dateString, null);
            }
            visitDateTest(node, VisitPhase.begin, props, comparison, date);
            accept(node, props);
            visitDateTest(node, VisitPhase.end, props, comparison, date);
        } else if ("body".equalsIgnoreCase(nodeName)) {
            boolean caseSensitive = false;
            String value;
            if (getNode(node, 0, 1).jjtGetNumChildren() == 0) {
                // must be :comparator
                if (!":comparator".equals(getValue(node, 0, 1)))
                    throw ServiceException.PARSE_ERROR("Expected :comparator argument", null);
                caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 2, 0, 0));
                value = getValue(node, 0, 3, 0, 0);
            } else {
                value = getValue(node, 0, 1, 0, 0);
            }
            visitBodyTest(node, VisitPhase.begin, props, caseSensitive, value);
            accept(node, props);
            visitBodyTest(node, VisitPhase.end, props, caseSensitive, value);
        } else if ("attachment".equalsIgnoreCase(nodeName)) {
            visitAttachmentTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitAttachmentTest(node, VisitPhase.end, props);
        } else if ("addressbook".equalsIgnoreCase(nodeName)) {
            StringBuilder format = new StringBuilder();
            Node argNode = getNode(node, 0, 1, 0);
            int argNodeLen = argNode.jjtGetNumChildren();
            for (int i = 0; i < argNodeLen; i++) {
                if (i > 0) {
                    format.append(",");
                }
                format.append(getValue(argNode, i));
            }
            String header = format.toString();
            visitAddressBookTest(node, VisitPhase.begin, props, header);
            accept(node, props);
            visitAddressBookTest(node, VisitPhase.end, props, header);
        } else if ("contact_ranking".equalsIgnoreCase(nodeName)) {
            String header = getValue(node, 0, 1, 0, 0);
            visitContactRankingTest(node, VisitPhase.begin, props, header);
            accept(node, props);
            visitContactRankingTest(node, VisitPhase.end, props, header);
        } else if ("me".equalsIgnoreCase(nodeName)) {
            String header = getValue(node, 0, 1, 0, 0);
            visitMeTest(node, VisitPhase.begin, props, header);
            accept(node, props);
            visitMeTest(node, VisitPhase.end, props, header);
        } else if ("invite".equalsIgnoreCase(nodeName)) {
            List<String> methods = Collections.emptyList();
            if (getNode(node, 0).jjtGetNumChildren() > 0) {
                // Arguments node has children.
                methods = getMultiValue(node, 0, 1, 0);
            }
            visitInviteTest(node, VisitPhase.begin, props, methods);
            accept(node, props);
            visitInviteTest(node, VisitPhase.end, props, methods);
        } else if ("current_time".equalsIgnoreCase(nodeName)) {
            String s = stripLeadingColon(getValue(node, 0, 0));
            Sieve.DateComparison comparison = Sieve.DateComparison.fromString(s);
            String timeString = getValue(node, 0, 1, 0, 0);
            visitCurrentTimeTest(node, VisitPhase.begin, props, comparison, timeString);
            accept(node, props);
            visitCurrentTimeTest(node, VisitPhase.end, props, comparison, timeString);
        } else if ("current_day_of_week".equalsIgnoreCase(nodeName)) {
            List<String> days = getMultiValue(node, 0, 1, 0);
            visitCurrentDayOfWeekTest(node, VisitPhase.begin, props, days);
            accept(node, props);
            visitCurrentDayOfWeekTest(node, VisitPhase.end, props, days);
        } else if ("conversation".equalsIgnoreCase(nodeName)) {
            String where = getValue(node, 0, 1, 0, 0);
            visitConversationTest(node, VisitPhase.begin, props, where);
            accept(node, props);
            visitConversationTest(node, VisitPhase.end, props, where);
        } else if ("facebook".equalsIgnoreCase(nodeName)) {
            visitFacebookTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitFacebookTest(node, VisitPhase.end, props);
        } else if ("linkedin".equalsIgnoreCase(nodeName)) {
            visitLinkedInTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitLinkedInTest(node, VisitPhase.end, props);
        } else if ("socialcast".equalsIgnoreCase(nodeName)) {
            visitSocialcastTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitSocialcastTest(node, VisitPhase.end, props);
        } else if ("twitter".equalsIgnoreCase(nodeName)) {
            visitTwitterTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitTwitterTest(node, VisitPhase.end, props);
        } else if ("list".equalsIgnoreCase(nodeName)) {
            visitListTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitListTest(node, VisitPhase.end, props);
        } else if ("bulk".equalsIgnoreCase(nodeName)) {
            visitBulkTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitBulkTest(node, VisitPhase.end, props);
        } else if ("importance".equalsIgnoreCase(nodeName)) {
            FilterTest.Importance importance = FilterTest.Importance.fromString(getValue(node, 0, 0, 0, 0));
            visitImportanceTest(node, VisitPhase.begin, props, importance);
            accept(node, props);
            visitImportanceTest(node, VisitPhase.end, props, importance);
        } else if ("flagged".equalsIgnoreCase(nodeName)) {
            Sieve.Flag flag = Sieve.Flag.fromString(getValue(node, 0, 0, 0, 0));
            visitFlaggedTest(node, VisitPhase.begin, props, flag);
            accept(node, props);
            visitFlaggedTest(node, VisitPhase.end, props, flag);
        } else if ("true".equalsIgnoreCase(nodeName)) {
            visitTrueTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitTrueTest(node, VisitPhase.end, props);
        } else if ("community_requests".equalsIgnoreCase(nodeName)) {
            visitCommunityRequestsTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitCommunityRequestsTest(node, VisitPhase.end, props);
        } else if ("community_content".equalsIgnoreCase(nodeName)) {
            visitCommunityContentTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitCommunityContentTest(node, VisitPhase.end, props);
        } else if ("community_connections".equalsIgnoreCase(nodeName)) {
            visitCommunityConnectionsTest(node, VisitPhase.begin, props);
            accept(node, props);
            visitCommunityConnectionsTest(node, VisitPhase.end, props);
        } else {
            ZimbraLog.filter.debug("Ignoring unrecognized test type '%s'.", nodeName);
            accept(node, props);
        }
        // Done processing the current test.  Reset the negative test flag for
        // the next test (bug 46007).
        props.isNegativeTest = false;
    }
    visitTest(node, VisitPhase.end, props);
}
Also used : Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) TagArgument(org.apache.jsieve.TagArgument) ArrayList(java.util.ArrayList) List(java.util.List) Sieve(com.zimbra.common.filter.Sieve) Date(java.util.Date) SieveNode(org.apache.jsieve.parser.SieveNode) FilterTest(com.zimbra.soap.mail.type.FilterTest)

Example 12 with Node

use of org.apache.jsieve.parser.generated.Node in project zm-mailbox by Zimbra.

the class SieveVisitor method getMultiValue.

private List<String> getMultiValue(Node parent, int... indexes) throws ServiceException {
    Node child = getNode(parent, indexes);
    List<String> values = new ArrayList<String>();
    for (int i = 0; i < child.jjtGetNumChildren(); i++) {
        Object value = ((SieveNode) child.jjtGetChild(i)).getValue();
        values.add(value == null ? null : value.toString());
    }
    return values;
}
Also used : SieveNode(org.apache.jsieve.parser.SieveNode) Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) ArrayList(java.util.ArrayList)

Example 13 with Node

use of org.apache.jsieve.parser.generated.Node in project zm-mailbox by Zimbra.

the class RuleManager method getRulesAsXML.

private static List<FilterRule> getRulesAsXML(Account account, FilterType filterType) throws ServiceException {
    Node node;
    try {
        node = getRulesNode(account, filterType, false);
    } catch (ParseException e) {
        throw ServiceException.PARSE_ERROR("parsing Sieve script", e);
    } catch (TokenMgrError e) {
        throw ServiceException.PARSE_ERROR("parsing Sieve script", e);
    }
    String sieveScriptAttrName = null;
    if (filterType == FilterType.INCOMING) {
        sieveScriptAttrName = Provisioning.A_zimbraMailSieveScript;
    } else {
        sieveScriptAttrName = Provisioning.A_zimbraMailOutgoingSieveScript;
    }
    SieveToSoap sieveToSoap = new SieveToSoap(getRuleNames(account.getAttr(sieveScriptAttrName)));
    sieveToSoap.accept(node);
    return sieveToSoap.toFilterRules();
}
Also used : Node(org.apache.jsieve.parser.generated.Node) TokenMgrError(org.apache.jsieve.parser.generated.TokenMgrError) ParseException(org.apache.jsieve.parser.generated.ParseException)

Example 14 with Node

use of org.apache.jsieve.parser.generated.Node in project zm-mailbox by Zimbra.

the class RuleManager method tagDeleted.

private static void tagDeleted(Account account, String tagName, String sieveScriptAttrName, String rulesCacheKey) throws ServiceException {
    String script = getRules(account, sieveScriptAttrName);
    if (script != null) {
        Node node;
        try {
            node = parse(script);
        } catch (ParseException e) {
            ZimbraLog.filter.warn("Unable to update %s after tag '%s' was deleted.", sieveScriptAttrName, tagName, e);
            return;
        }
        TagDeleted deleted = new TagDeleted(tagName);
        deleted.accept(node);
        if (deleted.modified()) {
            // Kind of a hacky way to convert a Node tree to a script.  We
            // convert to XML first, and then to a String.  Unfortunately
            // jSieve 0.2 doesn't have an API that generates a script from
            // a Node tree.
            List<String> ruleNames = getRuleNames(script);
            SieveToSoap sieveToSoap = new SieveToSoap(ruleNames);
            sieveToSoap.accept(node);
            SoapToSieve soapToSieve = new SoapToSieve(sieveToSoap.toFilterRules());
            String newScript = soapToSieve.getSieveScript();
            setRules(account, newScript, sieveScriptAttrName, rulesCacheKey);
            ZimbraLog.filter.info("Updated %s after tag %s was deleted.", sieveScriptAttrName, tagName);
            ZimbraLog.filter.debug("Old rules:\n%s, new rules:\n%s", script, newScript);
        }
    }
}
Also used : Node(org.apache.jsieve.parser.generated.Node) ParseException(org.apache.jsieve.parser.generated.ParseException)

Example 15 with Node

use of org.apache.jsieve.parser.generated.Node in project zm-mailbox by Zimbra.

the class RuleRewriter method traverse.

private void traverse(Node node) {
    int numChildren = node.jjtGetNumChildren();
    int nameIndex = 0;
    for (int i = 0; i < numChildren; i++) {
        Node childNode = node.jjtGetChild(i);
        String name = ((SieveNode) childNode).getName();
        if (childNode instanceof ASTcommand && ("if".equals(name) || "elsif".equals(name) || "disabled_if".equals(name))) {
            String ruleName = "";
            if (mRuleNames != null && nameIndex < mRuleNames.size()) {
                ruleName = mRuleNames.get(nameIndex);
                nameIndex++;
            }
            Element ruleElem = mRoot.addElement(MailConstants.E_RULE).addAttribute(MailConstants.A_NAME, ruleName);
            ruleElem.addAttribute(MailConstants.A_ACTIVE, !"disabled_if".equals(name));
            rule(ruleElem, childNode);
        } else {
            traverse(childNode);
        }
    }
}
Also used : SieveNode(org.apache.jsieve.parser.SieveNode) Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) ASTcommand(org.apache.jsieve.parser.generated.ASTcommand) Element(com.zimbra.common.soap.Element) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Aggregations

Node (org.apache.jsieve.parser.generated.Node)22 ParseException (org.apache.jsieve.parser.generated.ParseException)10 SieveNode (org.apache.jsieve.parser.SieveNode)9 TokenMgrError (org.apache.jsieve.parser.generated.TokenMgrError)6 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)5 ArrayList (java.util.ArrayList)5 Account (com.zimbra.cs.account.Account)4 ServiceException (com.zimbra.common.service.ServiceException)3 Element (com.zimbra.common.soap.Element)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 SieveException (org.apache.jsieve.exception.SieveException)3 ASTcommand (org.apache.jsieve.parser.generated.ASTcommand)3 DeliveryServiceException (com.zimbra.common.service.DeliveryServiceException)2 ErejectException (com.zimbra.cs.filter.jsieve.ErejectException)2 Message (com.zimbra.cs.mailbox.Message)2 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)2 ItemId (com.zimbra.cs.service.util.ItemId)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 List (java.util.List)2