1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.rssaggregator.importhandler;
35
36 import static java.lang.String.format;
37
38 import info.magnolia.module.rssaggregator.util.Assert;
39
40 import java.util.Collection;
41 import java.util.Set;
42
43 import org.apache.commons.beanutils.MethodUtils;
44 import org.apache.commons.lang3.StringUtils;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.rometools.rome.feed.synd.SyndContent;
49 import com.rometools.rome.feed.synd.SyndEntry;
50
51
52
53
54
55 public class AggregateFilter {
56
57 private static final Logger log = LoggerFactory.getLogger(AggregateFilter.class);
58
59 private final Set<FilterPredicate> filters;
60
61 public AggregateFilter(Set<FilterPredicate> filters) {
62 Assert.notNull(filters, "'filters' must not be null");
63 this.filters = filters;
64 }
65
66 public boolean include(SyndEntry entry) {
67 boolean include = true;
68 boolean firstPass = true;
69
70 for (FilterPredicate filter : filters) {
71 String property = filter.getProperty();
72 String getterName = format("get%s", StringUtils.capitalize(property));
73 Object propertyValue = "";
74 try {
75 propertyValue = MethodUtils.invokeExactMethod(entry, getterName, null);
76 } catch (Exception e) {
77 log.warn("Property {} can't be retrieved from the feed and will be treated as if it was empty during filtering", property);
78 }
79
80 String regularExpression = filter.getRegularExpression();
81 FilterPredicate.Condition condition = filter.getCondition();
82 if (propertyValue instanceof Collection) {
83 Collection<Object> propertyValues = (Collection<Object>) propertyValue;
84 boolean hit = getHit(propertyValues, regularExpression);
85 switch (condition) {
86 case AND:
87 include &= hit;
88 break;
89 case OR:
90 include &= !firstPass;
91 include |= hit;
92 break;
93 case NOT:
94 include &= !hit;
95 break;
96 }
97 } else if (propertyValue instanceof SyndContent) {
98 include = matchSingleString(include, ((SyndContent) propertyValue).getValue(), regularExpression, condition, firstPass);
99 } else if (propertyValue != null) {
100 include = matchSingleString(include, propertyValue.toString(), regularExpression, condition, firstPass);
101 } else {
102 include = false;
103 }
104 firstPass = false;
105 }
106 return include;
107 }
108
109
110 protected boolean getHit(Collection<Object> propertyValues, String regularExpression) {
111 boolean hit = false;
112 for (Object valueWrapper : propertyValues) {
113 String single;
114 try {
115 single = (String) MethodUtils.invokeExactMethod(valueWrapper, "getName", null);
116 } catch (Exception e) {
117 single = valueWrapper.toString();
118 }
119 if (single.matches(regularExpression)) {
120 hit = true;
121 break;
122 }
123 }
124 return hit;
125 }
126
127 protected boolean matchSingleString(boolean passed, String propValue, String regularExpression, FilterPredicate.Condition condition, boolean firstPass) {
128 switch (condition) {
129 case AND:
130 passed &= propValue.matches(regularExpression);
131 break;
132 case OR:
133 passed &= !firstPass;
134 passed |= propValue.matches(regularExpression);
135 break;
136 case NOT:
137 passed &= !propValue.matches(regularExpression);
138 break;
139 }
140 return passed;
141 }
142
143 protected boolean contains(FilterPredicate filterPredicate) {
144 return filters.contains(filterPredicate);
145 }
146 }