View Javadoc

1   /**
2    * This file Copyright (c) 2013 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.rssaggregator.importhandler;
35  
36  import info.magnolia.module.rssaggregator.util.Assert;
37  
38  import java.util.Set;
39  
40  import org.apache.commons.beanutils.MethodUtils;
41  import org.apache.commons.lang.StringUtils;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  import com.sun.syndication.feed.synd.SyndEntry;
46  
47  /**
48   * Filters entries based on the criteria specified in the RSS Aggregator dialog.
49   *
50   * @author lfischer
51   */
52  public class PlanetFilter {
53  
54      private static final Logger log = LoggerFactory.getLogger(PlanetFilter.class);
55      private static final String METHOD_PREFIX = "get";
56      private final Set<FilterPredicate> filters;
57  
58      public PlanetFilter(Set<FilterPredicate> filters) {
59          Assert.notNull(filters, "'filters' must not be null");
60          this.filters = filters;
61      }
62  
63      public boolean include(SyndEntry entry) {
64          boolean includeAnd = includeByCondition(entry, FilterPredicate.Condition.AND);
65          boolean includeOr = includeByCondition(entry, FilterPredicate.Condition.OR);
66          boolean includeNot = includeByCondition(entry, FilterPredicate.Condition.NOT);
67  
68          return includeAnd && includeOr && includeNot;
69      }
70  
71      boolean includeByCondition(SyndEntry entry, FilterPredicate.Condition matchingCondition) {
72          boolean include = false;
73          boolean conditionFound = false;
74  
75          for (FilterPredicate filter : filters) {
76              Object propertyValue = getPropertyValue(entry, filter.getProperty());
77              FilterPredicate.Condition condition = filter.getCondition();
78  
79              if (propertyValue != null && condition.equals(matchingCondition)) {
80                  boolean hit;
81  
82                  hit = matchSingleString(propertyValue.toString(), filter.getRegularExpression());
83  
84                  switch (condition) {
85                  case AND:
86                      if (hit && !conditionFound) {
87                          include = true;
88                      } else {
89                          include &= hit;
90                      }
91                      conditionFound = true;
92                      break;
93                  case OR:
94                      if (hit) {
95                          include = true;
96                      }
97                      conditionFound = true;
98                      break;
99                  case NOT:
100                     if (hit) {
101                         include = false;
102                     } else {
103                         if (!conditionFound) {
104                             include = true;
105                         }
106                     }
107                     conditionFound = true;
108                     break;
109                 }
110             }
111         }
112         if (!conditionFound) {
113             include = true;
114         }
115         return include;
116     }
117 
118     protected boolean matchSingleString(String propertyValue, String regularExpression) {
119         // remove newline characters, otherwise regex will not work
120         propertyValue = StringUtils.remove(propertyValue, "\n");
121 
122         return propertyValue.matches(regularExpression);
123     }
124 
125     Object getPropertyValue(SyndEntry entry, String property) {
126         Object propertyValue = StringUtils.EMPTY;
127 
128         String getterName = getCamelCaseProperty(property);
129 
130         try {
131             propertyValue = MethodUtils.invokeExactMethod(entry, getterName, null);
132         } catch (Exception e) {
133             if (log.isWarnEnabled()) {
134                 log.warn("Property {} can't be retrieved from the feed and will be treated as if it was empty during filtering", property);
135             }
136         }
137 
138         return propertyValue;
139     }
140 
141     protected String getCamelCaseProperty(String prop) {
142         if (StringUtils.isBlank(prop)) {
143             return "";
144         }
145         return METHOD_PREFIX + StringUtils.upperCase(StringUtils.substring(prop, 0, 1)) +
146                 StringUtils.lowerCase((StringUtils.substring(prop, 1, prop.length())));
147     }
148 }