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.lang.StringUtils;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.sun.syndication.feed.synd.SyndContent;
49 import com.sun.syndication.feed.synd.SyndEntry;
50
51
52
53
54
55
56
57 public class AggregateFilter {
58
59 private static final Logger log = LoggerFactory.getLogger(AggregateFilter.class);
60
61 private final Set<FilterPredicate> filters;
62
63 public AggregateFilter(Set<FilterPredicate> filters) {
64 Assert.notNull(filters, "'filters' must not be null");
65 this.filters = filters;
66 }
67
68 public boolean include(SyndEntry entry) {
69 boolean include = true;
70 boolean firstPass = true;
71
72 for (FilterPredicate filter : filters) {
73 String property = filter.getProperty();
74 String getterName = format("get%s", StringUtils.capitalize(property));
75 Object propertyValue = "";
76 try {
77 propertyValue = MethodUtils.invokeExactMethod(entry, getterName, null);
78 } catch (Exception e) {
79 log.warn("Property {} can't be retrieved from the feed and will be treated as if it was empty during filtering", property);
80 }
81
82 String regularExpression = filter.getRegularExpression();
83 FilterPredicate.Condition condition = filter.getCondition();
84 if (propertyValue instanceof Collection) {
85 Collection<Object> propertyValues = (Collection<Object>) propertyValue;
86 boolean hit = getHit(propertyValues, regularExpression);
87 switch (condition) {
88 case AND:
89 include &= hit;
90 break;
91 case OR:
92 include &= !firstPass;
93 include |= hit;
94 break;
95 case NOT:
96 include &= !hit;
97 break;
98 }
99 } else if (propertyValue instanceof SyndContent) {
100 include = matchSingleString(include, ((SyndContent) propertyValue).getValue(), regularExpression, condition, firstPass);
101 } else if (propertyValue != null) {
102 include = matchSingleString(include, propertyValue.toString(), regularExpression, condition, firstPass);
103 } else {
104 include = false;
105 }
106 firstPass = false;
107 }
108 return include;
109 }
110
111
112 protected boolean getHit(Collection<Object> propertyValues, String regularExpression) {
113 boolean hit = false;
114 for (Object valueWrapper : propertyValues) {
115 String single;
116 try {
117 single = (String) MethodUtils.invokeExactMethod(valueWrapper, "getName", null);
118 } catch (Exception e) {
119 single = valueWrapper.toString();
120 }
121 if (single.matches(regularExpression)) {
122 hit = true;
123 break;
124 }
125 }
126 return hit;
127 }
128
129 protected boolean matchSingleString(boolean passed, String propValue, String regularExpression, FilterPredicate.Condition condition, boolean firstPass) {
130 switch (condition) {
131 case AND:
132 passed &= propValue.matches(regularExpression);
133 break;
134 case OR:
135 passed &= !firstPass;
136 passed |= propValue.matches(regularExpression);
137 break;
138 case NOT:
139 passed &= !propValue.matches(regularExpression);
140 break;
141 }
142 return passed;
143 }
144
145 protected boolean contains(FilterPredicate filterPredicate) {
146 return filters.contains(filterPredicate);
147 }
148 }