Coverage Report - org.jbehave.core.embedder.MetaFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
MetaFilter
98%
59/60
95%
40/42
2.692
 
 1  
 package org.jbehave.core.embedder;
 2  
 
 3  
 import org.apache.commons.lang.StringUtils;
 4  
 import org.apache.commons.lang.builder.ToStringBuilder;
 5  
 import org.apache.commons.lang.builder.ToStringStyle;
 6  
 import org.jbehave.core.model.Meta;
 7  
 import org.jbehave.core.model.Meta.Property;
 8  
 
 9  
 import java.util.HashSet;
 10  
 import java.util.Properties;
 11  
 import java.util.Set;
 12  
 import java.util.regex.Matcher;
 13  
 import java.util.regex.Pattern;
 14  
 
 15  
 /**
 16  
  * <p>
 17  
  * Allows filtering on meta info.
 18  
  * </p>
 19  
  * 
 20  
  * <p>
 21  
  * Filters are represented as a sequence of any name-value properties (separated
 22  
  * by a space), prefixed by "+" for inclusion and "-" for exclusion. E.g.:
 23  
  * 
 24  
  * <pre>
 25  
  * new Filter(&quot;+author Mauro -theme smoke testing +map *API -skip&quot;)
 26  
  * </pre>
 27  
  * 
 28  
  * </p>
 29  
  */
 30  
 public class MetaFilter {
 31  
 
 32  1
     public static final MetaFilter EMPTY = new MetaFilter();
 33  
 
 34  38
     private final Properties include = new Properties();
 35  38
     private final Properties exclude = new Properties();
 36  
     private final String filterAsString;
 37  
     private final EmbedderMonitor monitor;
 38  
 
 39  
     public MetaFilter() {
 40  1
         this("");
 41  1
     }
 42  
 
 43  
     public MetaFilter(String filterAsString) {
 44  20
         this(filterAsString, new PrintStreamEmbedderMonitor());
 45  20
     }
 46  
 
 47  38
     public MetaFilter(String filterAsString, EmbedderMonitor monitor) {
 48  38
         this.filterAsString = filterAsString == null ? "" : filterAsString;
 49  38
         this.monitor = monitor;
 50  38
         parse(include, "+");
 51  38
         parse(exclude, "-");
 52  38
     }
 53  
 
 54  
     private void parse(Properties properties, String prefix) {
 55  76
         properties.clear();
 56  76
         for (String found : found(prefix)) {
 57  24
             Property property = new Property(StringUtils.removeStartIgnoreCase(found, prefix));
 58  24
             properties.setProperty(property.getName(), property.getValue());
 59  24
         }
 60  76
     }
 61  
 
 62  
     private Set<String> found(String prefix) {
 63  76
         Matcher matcher = findAllPrefixed(prefix).matcher(filterAsString);
 64  76
         Set<String> found = new HashSet<String>();
 65  100
         while (matcher.find()) {
 66  24
             found.add(matcher.group().trim());
 67  
         }
 68  76
         return found;
 69  
     }
 70  
 
 71  
     private Pattern findAllPrefixed(String prefix) {
 72  76
         return Pattern.compile("(\\" + prefix + "(\\w|\\s|\\*)*)", Pattern.DOTALL);
 73  
     }
 74  
 
 75  
     public boolean allow(Meta meta) {
 76  
         boolean allowed;
 77  48
         if (!include.isEmpty() && exclude.isEmpty()) {
 78  5
             allowed = match(include, meta);
 79  43
         } else if (include.isEmpty() && !exclude.isEmpty()) {
 80  3
             allowed = !match(exclude, meta);
 81  40
         } else if (!include.isEmpty() && !exclude.isEmpty()) {
 82  6
             allowed = match(merge(include, exclude), meta) && !match(exclude, meta);
 83  
         } else {
 84  34
             allowed = true;
 85  
         }
 86  48
         if (!allowed) {
 87  7
             monitor.metaNotAllowed(meta, this);
 88  
         }
 89  48
         return allowed;
 90  
     }
 91  
 
 92  
     private Properties merge(Properties include, Properties exclude) {
 93  6
         Set<Object> in = new HashSet<Object>(include.keySet());
 94  6
         in.addAll(exclude.keySet());
 95  6
         Properties merged = new Properties();
 96  6
         for (Object key : in) {
 97  8
             if (include.containsKey(key)) {
 98  6
                 merged.put(key, include.get(key));
 99  2
             } else if (exclude.containsKey(key)) {
 100  2
                 merged.put(key, exclude.get(key));
 101  
             }
 102  
         }
 103  6
         return merged;
 104  
     }
 105  
 
 106  
     private boolean match(Properties properties, Meta meta) {
 107  18
         for (Object key : properties.keySet()) {
 108  19
             String property = (String) properties.get(key);
 109  19
             for (String metaName : meta.getPropertyNames()) {
 110  19
                 if (key.equals(metaName)) {
 111  16
                     String value = meta.getProperty(metaName);
 112  16
                     if (StringUtils.isBlank(value)) {
 113  4
                         return true;
 114  12
                     } else if (property.contains("*")) {
 115  1
                         return value.matches(property.replace("*", ".*"));
 116  
                     }
 117  11
                     return properties.get(key).equals(value);
 118  
                 }
 119  
             }
 120  3
         }
 121  2
         return false;
 122  
     }
 123  
 
 124  
     public Properties include() {
 125  1
         return include;
 126  
     }
 127  
 
 128  
     public Properties exclude() {
 129  1
         return exclude;
 130  
     }
 131  
 
 132  
     public String asString() {
 133  8
         return filterAsString;
 134  
     }
 135  
 
 136  
     @Override
 137  
     public String toString() {
 138  0
         return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
 139  
     }
 140  
 
 141  
 }