View Javadoc
1   package com.exsoinn.util.epf;
2   
3   
4   import java.util.*;
5   import java.util.stream.Collectors;
6   
7   /**
8    * Unmodifiable class to encapsulate a {@code Filter} used when searching an element off of a {@link Context} object. The
9    * sole factory method used to build a {@code Filter} instance accepts a filter {@link String} that follows the following
10   * format only:
11   *
12   * key1=val1;key2=val2;key3=val3
13   *
14   * If the filter {@link String} can't be successfully parsed for whatever reason, {@link IllegalArgumentException}
15   * gets thrown.
16   *
17   * This class is a specialized implementation of {@link Map} interface, backed by a {@link Map} instance to which
18   * all {@link Map} operations are forwarded (composition design pattern). It will throw {@link UnsupportedOperationException}
19   * on any method invocation of {@link Map} that would otherwise modify the underlying {@link Map}, because instances of
20   * this class aremeant to be read-ony.
21   *
22   * Created by QuijadaJ on 5/3/2017.
23   */
24  public final class Filter implements Map<String, String> {
25      private static final String sampleFormat = "key1=val1;key2=val2;key3=val3";
26      private final Map<String, String> m = new HashMap<>();
27      private static final String BLANK = "__BLANK__";
28  
29      private Filter(String pFilterStr) {
30          parseFilter(pFilterStr);
31      }
32  
33  
34      public static Filter valueOf(String pFilter)
35              throws IllegalArgumentException {
36          if (null == pFilter
37                  || pFilter.equalsIgnoreCase("")
38                  || pFilter.equalsIgnoreCase(SelectionCriteria.SEARCH_CRITERIA_NULL)) {
39              return null;
40          }
41  
42          return new Filter(pFilter);
43      }
44  
45  
46      public static Filter fromMap(Map<String, String> pFilterMap) {
47          if (null == pFilterMap) {
48              return null;
49          }
50  
51          StringBuilder sb = new StringBuilder();
52          sb.append(pFilterMap.entrySet().parallelStream().map(Map.Entry::toString)
53                  .collect(Collectors.joining(";", "", "")));
54  
55          return Filter.valueOf(sb.toString());
56      }
57  
58      @Override
59      public int size() {
60          return m.size();
61      }
62  
63      @Override
64      public boolean isEmpty() {
65          return m.isEmpty();
66      }
67  
68      @Override
69      public boolean containsKey(Object pKey) {
70          return m.containsKey(pKey);
71      }
72  
73      @Override
74      public boolean containsValue(Object pValue) {
75          return m.containsValue(pValue);
76      }
77  
78      @Override
79      public String get(Object pKey) {
80          return m.get(pKey);
81      }
82  
83      @Override
84      public String put(String pKey, String pValue) {
85          throw new UnsupportedOperationException();
86      }
87  
88      @Override
89      public String remove(Object pKey) {
90          throw new UnsupportedOperationException();
91      }
92  
93      @Override
94      public void putAll(Map<? extends String, ? extends String> pMap) {
95          throw new UnsupportedOperationException();
96      }
97  
98      @Override
99      public void clear() {
100         throw new UnsupportedOperationException();
101     }
102 
103     @Override
104     public Set<String> keySet() {
105         return new HashSet<>(m.keySet());
106     }
107 
108     @Override
109     public Collection<String> values() {
110         return new ArrayList<>(m.values());
111     }
112 
113     @Override
114     public Set<Entry<String, String>> entrySet() {
115         return new HashSet<>(m.entrySet());
116     }
117 
118     @Override
119     public String toString() {
120         return m.entrySet().stream().map(Map.Entry::toString).collect(Collectors.joining(";"));
121     }
122 
123 
124     private void parseFilter(String pFilter)
125             throws IllegalArgumentException {
126         String[] tokens = pFilter.split(";");
127 
128         if (tokens.length == 0) {
129             throw new IllegalArgumentException("Filter string " + pFilter
130                     + " could not be parsed, check format and try again. Sample format is " + sampleFormat);
131         }
132 
133         try {
134             Arrays.stream(tokens).forEach(t -> {
135                 String[] vals = t.split("=");
136                 m.put(vals[0], vals.length == 1 ? BLANK : vals[1]);
137             });
138         } catch (Exception e) {
139             throw new IllegalArgumentException("Filter string " + pFilter
140                     + " could not be parsed, check format and try again. Sample format is " + sampleFormat, e);
141         }
142     }
143 }