View Javadoc

1   package com.atlassian.plugins.rest.common.expand.parameter;
2   
3   import com.atlassian.plugins.rest.common.expand.Expandable;
4   import com.google.common.base.Preconditions;
5   import com.google.common.collect.Maps;
6   import com.google.common.collect.Sets;
7   import org.apache.commons.lang.StringUtils;
8   
9   import java.util.Collection;
10  import java.util.Collections;
11  import java.util.HashSet;
12  import java.util.Map;
13  import java.util.regex.Matcher;
14  import java.util.regex.Pattern;
15  
16  /**
17   * Parses and allow easy retrieval of information of expansion parameter.
18   */
19  public final class DefaultExpandParameter implements ExpandParameter {
20      private static final String DOT = ".";
21      private static final String COMMA = ",";
22      private static final String WILDCARD = "*";
23  
24      private static final ExpandParameter EMPTY_EXPAND_PARAMETER = new DefaultExpandParameter((String) null);
25  
26      private final Map<String, ExpandInformation> parameters;
27  
28      private DefaultExpandParameter(String expand) {
29          this(StringUtils.isNotBlank(expand) ? Collections.singleton(expand) : Collections.<String>emptyList());
30      }
31  
32      public DefaultExpandParameter(Collection<String> expands) {
33          parameters = parse(expands != null ? expands : Collections.<String>emptyList());
34      }
35  
36      public boolean shouldExpand(Expandable expandable) {
37          return parameters.containsKey(WILDCARD) || parameters.containsKey(Preconditions.checkNotNull(expandable).value());
38      }
39  
40      public Indexes getIndexes(Expandable expandable) {
41          final ExpandInformation expandInformation = parameters.get(Preconditions.checkNotNull(expandable).value());
42          return expandInformation != null ? expandInformation.getIndexes() : IndexParser.EMPTY;
43      }
44  
45      public ExpandParameter getExpandParameter(Expandable expandable) {
46          final ExpandInformation wildcardExpandInformation = parameters.get(WILDCARD);
47          final ExpandInformation valueExpandInformation = parameters.get(Preconditions.checkNotNull(expandable).value());
48  
49          return new ChainingExpandParameter(
50                  wildcardExpandInformation != null ? wildcardExpandInformation.getExpandParameter() : EMPTY_EXPAND_PARAMETER,
51                  valueExpandInformation != null ? valueExpandInformation.getExpandParameter() : EMPTY_EXPAND_PARAMETER);
52      }
53  
54      public boolean isEmpty() {
55          return parameters.isEmpty();
56      }
57  
58      private static Map<String, ExpandInformation> parse(Collection<String> expands) {
59          final Map<String, ExpandInformation> parameters = Maps.newHashMap();
60          for (String expand : preProcess(expands)) {
61              if (StringUtils.isNotEmpty(expand)) {
62                  final ExpandKey key = ExpandKey.from(StringUtils.substringBefore(expand, DOT));
63  
64                  DefaultExpandParameter newParameter = new DefaultExpandParameter(StringUtils.substringAfter(expand, DOT));
65                  if (parameters.containsKey(key.getName())) {
66                      DefaultExpandParameter existingParameter = parameters.get(key.getName()).getExpandParameter();
67                      newParameter.parameters.putAll(existingParameter.parameters);
68                  }
69                  parameters.put(key.getName(), new ExpandInformation(key.getIndexes(), newParameter));
70              }
71          }
72          return parameters;
73      }
74  
75      private static Collection<String> preProcess(Collection<String> expands) {
76          final Collection<String> preProcessed = new HashSet<String>();
77          for (String expand : expands) {
78              preProcessed.addAll(Sets.newHashSet(expand.split(COMMA)));
79          }
80          return preProcessed;
81      }
82  
83      private static class ExpandKey {
84          private static final Pattern KEY_PATTERN = Pattern.compile("(\\w+|\\*)(?:\\[([\\d:\\-\\|]+)\\])?");
85  
86          private final String name;
87          private final Indexes indexes;
88  
89          ExpandKey(String name, Indexes indexes) {
90              this.name = name;
91              this.indexes = indexes;
92          }
93  
94          public String getName() {
95              return name;
96          }
97  
98          public Indexes getIndexes() {
99              return indexes;
100         }
101 
102         private static ExpandKey from(String key) {
103             final Matcher keyMatcher = KEY_PATTERN.matcher(key);
104             if (!keyMatcher.matches()) {
105                 throw new RuntimeException("key <" + key + "> doesn't match pattern");
106             }
107 
108             final String name = keyMatcher.group(1);
109             final String indexesString = keyMatcher.group(2);
110             return new ExpandKey(name, IndexParser.parse(indexesString));
111         }
112     }
113 
114     private static class ExpandInformation {
115         private final Indexes indexes;
116         private final DefaultExpandParameter expandParameter;
117 
118         public ExpandInformation(Indexes indexes, DefaultExpandParameter expandParameter) {
119             this.indexes = Preconditions.checkNotNull(indexes);
120             this.expandParameter = Preconditions.checkNotNull(expandParameter);
121         }
122 
123         public Indexes getIndexes() {
124             return indexes;
125         }
126 
127         public DefaultExpandParameter getExpandParameter() {
128             return expandParameter;
129         }
130     }
131 }