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);
}
}
}
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);
}
}
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;
}
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;
}
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();
}
Aggregations