Search in sources :

Example 6 with Node

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

the class RuleRewriter method action.

private void action(Element elem, Node node) {
    int numChildren = node.jjtGetNumChildren();
    for (int i = 0; i < numChildren; i++) {
        Node childNode = node.jjtGetChild(i);
        if (childNode instanceof ASTstring) {
            String val = ((SieveNode) childNode).getValue().toString();
            if (val.startsWith("text:")) {
                elem.addText(val.substring(5));
            } else {
                // Put quotes around value to maintain backward compatibility
                // with ZCS 5.x.  See bug 39911.
                StringBuilder buf = new StringBuilder();
                if (!val.startsWith("\"")) {
                    buf.append('"');
                }
                buf.append(val);
                if (!val.endsWith("\"")) {
                    buf.append('"');
                }
                elem.addElement(MailConstants.E_FILTER_ARG).setText(buf.toString());
            }
        } else {
            action(elem, childNode);
        }
    }
}
Also used : ASTstring(org.apache.jsieve.parser.generated.ASTstring) Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 7 with Node

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

the class RuleRewriter method test.

private void test(Element elem, Node node) {
    int numChildren = node.jjtGetNumChildren();
    for (int i = 0; i < numChildren; i++) {
        Node childNode = node.jjtGetChild(i);
        if (childNode instanceof ASTargument) {
            Object val = ((SieveNode) childNode).getValue();
            if (val != null) {
                if (MATCH_TYPES.contains(val.toString())) {
                    if (!mStack.isEmpty())
                        val = mStack.pop() + " " + val;
                    elem.addAttribute(MailConstants.A_OPERATION, val.toString());
                } else {
                    String cname = elem.getAttribute(MailConstants.A_NAME, null);
                    if ("size".equals(cname)) {
                        // special casing size test
                        elem.addAttribute(MailConstants.A_RHS, getSize(val.toString()));
                    } else {
                        elem.addAttribute(MailConstants.A_MODIFIER, val.toString());
                    }
                }
            }
        } else if (childNode instanceof ASTstring_list) {
            List<Object> val = getStringList(childNode);
            String cname = elem.getAttribute(MailConstants.A_NAME, null);
            String param = null;
            if ("date".equals(cname) || "body".equals(cname))
                param = MailConstants.A_RHS;
            else
                param = PARAM_PREFIX + String.valueOf(x++);
            elem.addAttribute(param, toString(val));
        }
        test(elem, childNode);
    }
}
Also used : SieveNode(org.apache.jsieve.parser.SieveNode) ASTstring_list(org.apache.jsieve.parser.generated.ASTstring_list) Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) ArrayList(java.util.ArrayList) List(java.util.List) ASTargument(org.apache.jsieve.parser.generated.ASTargument) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 8 with Node

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

the class RuleRewriter method getStringList.

private List<Object> getStringList(Node node) {
    int n = node.jjtGetNumChildren();
    List<Object> a = new ArrayList<Object>(n);
    for (int i = 0; i < n; i++) {
        Node cn = node.jjtGetChild(i);
        a.add(((SieveNode) cn).getValue());
    }
    return a;
}
Also used : Node(org.apache.jsieve.parser.generated.Node) SieveNode(org.apache.jsieve.parser.SieveNode) ArrayList(java.util.ArrayList) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 9 with Node

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

the class ApplyFilterRules method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Account account = getRequestedAccount(zsc);
    if (!canAccessAccount(zsc, account))
        throw ServiceException.PERM_DENIED("cannot access account");
    // Get rules.
    String fullScript = getRules(account);
    if (StringUtil.isNullOrEmpty(fullScript)) {
        throw ServiceException.INVALID_REQUEST("Account has no filter rules defined.", null);
    }
    List<Element> ruleElements = request.getElement(MailConstants.E_FILTER_RULES).listElements(MailConstants.E_FILTER_RULE);
    if (ruleElements.size() == 0) {
        String msg = String.format("No %s elements specified.", MailConstants.E_FILTER_RULE);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    // Concatenate script parts and create a new script to run on existing messages.
    StringBuilder buf = new StringBuilder();
    for (Element ruleEl : ruleElements) {
        String name = ruleEl.getAttribute(MailConstants.A_NAME);
        String singleRule = RuleManager.getRuleByName(fullScript, name);
        if (singleRule == null) {
            String msg = String.format("Could not find a rule named '%s'", name);
            throw ServiceException.INVALID_REQUEST(msg, null);
        }
        buf.append(singleRule).append("\n");
    }
    String partialScript = buf.toString();
    ZimbraLog.filter.debug("Applying partial script to existing messages: %s", partialScript);
    Node node = null;
    try {
        node = RuleManager.parse(partialScript);
    } catch (ParseException e) {
        throw ServiceException.FAILURE("Unable to parse Sieve script: " + partialScript, e);
    }
    // Get the ids of the messages to filter.
    Element msgEl = request.getOptionalElement(MailConstants.E_MSG);
    String query = getElementText(request, MailConstants.E_QUERY);
    if (msgEl != null && query != null) {
        String msg = String.format("Cannot specify both %s and %s elements.", MailConstants.E_MSG, MailConstants.E_QUERY);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    Mailbox mbox = getRequestedMailbox(zsc);
    List<Integer> messageIds = new ArrayList<Integer>();
    List<Integer> affectedIds = new ArrayList<Integer>();
    OperationContext octxt = getOperationContext(zsc, context);
    if (msgEl != null) {
        String[] ids = msgEl.getAttribute(MailConstants.A_IDS).split(",");
        for (String id : ids) {
            messageIds.add(Integer.valueOf(id));
        }
    } else if (query != null) {
        ZimbraQueryResults results = null;
        try {
            results = mbox.index.search(octxt, query, EnumSet.of(MailItem.Type.MESSAGE), SortBy.NONE, Integer.MAX_VALUE);
            while (results.hasNext()) {
                ZimbraHit hit = results.getNext();
                messageIds.add(hit.getItemId());
            }
        } catch (Exception e) {
            String msg = String.format("Unable to run search for query: '%s'", query);
            throw ServiceException.INVALID_REQUEST(msg, e);
        } finally {
            Closeables.closeQuietly(results);
        }
    } else {
        String msg = String.format("Must specify either the %s or %s element.", MailConstants.E_MSG, MailConstants.E_QUERY);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    int max = account.getFilterBatchSize();
    if (messageIds.size() > max) {
        throw ServiceException.INVALID_REQUEST("Attempted to apply filter rules to " + messageIds.size() + " messages, which exceeded the limit of " + max, null);
    }
    ZimbraLog.filter.info("Applying filter rules to %s existing messages.", messageIds.size());
    long sleepInterval = account.getFilterSleepInterval();
    // Apply filter rules.
    for (int i = 0; i < messageIds.size(); i++) {
        if (i > 0 && sleepInterval > 0) {
            try {
                Thread.sleep(sleepInterval);
            } catch (InterruptedException e) {
            }
        }
        int id = messageIds.get(i);
        try {
            mbox.getMessageById(octxt, id);
            if (RuleManager.applyRulesToExistingMessage(octxt, mbox, id, node)) {
                affectedIds.add(id);
            }
        } catch (NoSuchItemException e) {
            // Message was deleted since the search was done (bug 41609).
            ZimbraLog.filter.info("Skipping message %d: %s.", id, e.toString());
        } catch (ServiceException e) {
            ZimbraLog.filter.warn("Unable to filter message %d.", id, e);
        }
    }
    // Send response.
    Element response = zsc.createElement(getResponseElementName());
    if (affectedIds.size() > 0) {
        response.addElement(MailConstants.E_MSG).addAttribute(MailConstants.A_IDS, StringUtil.join(",", affectedIds));
    }
    return response;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ZimbraHit(com.zimbra.cs.index.ZimbraHit) Account(com.zimbra.cs.account.Account) Element(com.zimbra.common.soap.Element) Node(org.apache.jsieve.parser.generated.Node) ArrayList(java.util.ArrayList) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ServiceException(com.zimbra.common.service.ServiceException) ParseException(org.apache.jsieve.parser.generated.ParseException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) ParseException(org.apache.jsieve.parser.generated.ParseException)

Example 10 with Node

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

the class TestFilter method normalize.

/**
     * Converts the script to XML and back again.
     */
private String normalize(String script) throws ParseException, ServiceException {
    List<String> ruleNames = RuleManager.getRuleNames(script);
    Node node = RuleManager.getSieveFactory().parse(new ByteArrayInputStream(script.getBytes()));
    // Convert from Sieve to SOAP and back again.
    SieveToSoap sieveToSoap = new SieveToSoap(ruleNames);
    sieveToSoap.accept(node);
    SoapToSieve soapToSieve = new SoapToSieve(sieveToSoap.toFilterRules());
    return soapToSieve.getSieveScript();
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) Node(org.apache.jsieve.parser.generated.Node) SieveToSoap(com.zimbra.cs.filter.SieveToSoap) SoapToSieve(com.zimbra.cs.filter.SoapToSieve)

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