Search in sources :

Example 6 with SieveNode

use of org.apache.jsieve.parser.SieveNode 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 7 with SieveNode

use of org.apache.jsieve.parser.SieveNode 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 8 with SieveNode

use of org.apache.jsieve.parser.SieveNode 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)

Example 9 with SieveNode

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

the class RuleRewriter method rule.

private void rule(Element elem, Node parent) {
    int numChildren = parent.jjtGetNumChildren();
    for (int i = 0; i < numChildren; i++) {
        Node node = parent.jjtGetChild(i);
        String name = ((SieveNode) node).getName();
        if (node instanceof ASTtest) {
            if ("anyof".equals(name) || "allof".equals(name)) {
                Element condsElem = elem.addElement(MailConstants.E_CONDITION_GROUP).addAttribute(MailConstants.A_OPERATION, name);
                rule(condsElem, node);
            } else if ("not".equals(name)) {
                mStack.push(name);
                rule(elem, node);
            } else {
                if ("exists".equals(name) && !mStack.isEmpty()) {
                    name = mStack.pop() + " " + name;
                }
                Element cElem = elem.addElement(MailConstants.E_CONDITION).addAttribute(MailConstants.A_NAME, name);
                x = 0;
                test(cElem, node);
            }
        } else if (node instanceof ASTcommand) {
            Element actionElem = elem.addElement(MailConstants.E_ACTION).addAttribute(MailConstants.A_NAME, ((SieveNode) node).getName());
            action(actionElem, node);
        } else {
            rule(elem, node);
        }
    }
}
Also used : SieveNode(org.apache.jsieve.parser.SieveNode) Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) Element(com.zimbra.common.soap.Element) ASTcommand(org.apache.jsieve.parser.generated.ASTcommand) ASTtest(org.apache.jsieve.parser.generated.ASTtest) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Aggregations

SieveNode (org.apache.jsieve.parser.SieveNode)9 Node (org.apache.jsieve.parser.generated.Node)8 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)5 ArrayList (java.util.ArrayList)4 Element (com.zimbra.common.soap.Element)2 List (java.util.List)2 ASTcommand (org.apache.jsieve.parser.generated.ASTcommand)2 Sieve (com.zimbra.common.filter.Sieve)1 FilterTest (com.zimbra.soap.mail.type.FilterTest)1 Date (java.util.Date)1 TagArgument (org.apache.jsieve.TagArgument)1 ASTargument (org.apache.jsieve.parser.generated.ASTargument)1 ASTstring (org.apache.jsieve.parser.generated.ASTstring)1 ASTstring_list (org.apache.jsieve.parser.generated.ASTstring_list)1 ASTtest (org.apache.jsieve.parser.generated.ASTtest)1