cannot loop forever

This commit is contained in:
Athou
2014-11-07 08:46:09 +01:00
parent eea0c24d2b
commit a94ef980bb
4 changed files with 55 additions and 15 deletions

View File

@@ -1,12 +1,20 @@
package com.commafeed.backend.feed;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.JexlException;
import org.apache.commons.jexl2.JexlInfo;
import org.apache.commons.jexl2.MapContext;
import org.apache.commons.jexl2.Script;
import org.apache.commons.jexl2.introspection.JexlMethod;
import org.apache.commons.jexl2.introspection.JexlPropertyGet;
import org.apache.commons.jexl2.introspection.Uberspect;
@@ -63,12 +71,17 @@ public class FeedEntryFilter {
private final String filter;
public boolean matchesEntry(FeedEntry entry) {
public boolean matchesEntry(FeedEntry entry) throws FeedEntryFilterException {
if (StringUtils.isBlank(filter)) {
return true;
}
Expression expression = ENGINE.createExpression(filter);
Script script = null;
try {
script = ENGINE.createScript(filter);
} catch (JexlException e) {
throw new FeedEntryFilterException("Exception while parsing expression " + filter, e);
}
JexlContext context = new MapContext();
context.set("title", Jsoup.parse(entry.getContent().getTitle()).text().toLowerCase());
@@ -76,6 +89,25 @@ public class FeedEntryFilter {
context.set("content", Jsoup.parse(entry.getContent().getContent()).text().toLowerCase());
context.set("url", entry.getUrl().toLowerCase());
return (boolean) expression.evaluate(context);
Callable<Object> callable = script.callable(context);
Future<Object> future = Executors.newFixedThreadPool(1).submit(callable);
Object result = null;
try {
result = future.get(500, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new FeedEntryFilterException("interrupted while evaluating expression " + filter, e);
} catch (ExecutionException e) {
throw new FeedEntryFilterException("Exception while evaluating expression " + filter, e);
} catch (TimeoutException e) {
throw new FeedEntryFilterException("Took too long evaluating expression " + filter, e);
}
return (boolean) result;
}
@SuppressWarnings("serial")
public static class FeedEntryFilterException extends Exception {
public FeedEntryFilterException(String message, Throwable t) {
super(message, t);
}
}
}

View File

@@ -14,6 +14,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.feed.FeedEntryFilter;
import com.commafeed.backend.feed.FeedEntryFilter.FeedEntryFilterException;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryContent;
@@ -52,7 +53,7 @@ public class FeedUpdateService {
boolean matches = true;
try {
matches = filter.matchesEntry(entry);
} catch (Exception e) {
} catch (FeedEntryFilterException e) {
log.error("could not evaluate filter {}", sub.getFilter(), e);
}
if (!matches) {

View File

@@ -45,6 +45,7 @@ import com.commafeed.backend.dao.FeedCategoryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.feed.FeedEntryFilter;
import com.commafeed.backend.feed.FeedEntryFilter.FeedEntryFilterException;
import com.commafeed.backend.feed.FeedFetcher;
import com.commafeed.backend.feed.FeedQueues;
import com.commafeed.backend.feed.FeedUtils;
@@ -437,7 +438,7 @@ public class FeedREST {
try {
new FeedEntryFilter(req.getFilter()).matchesEntry(TEST_ENTRY);
} catch (Exception e) {
} catch (FeedEntryFilterException e) {
Throwable root = Throwables.getRootCause(e);
return Response.status(Status.BAD_REQUEST).entity(root.getMessage()).build();
}