View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.core.api.cache;
17  
18  
19  
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.SortedMap;
26  import java.util.TreeMap;
27  
28  /**
29   * A utility class that can be used to generate cache keys for more complex method signatures.  Currently, the utilities
30   * on this class focus on generating cache keys for collections of objects.  Since the caching infrastructure only
31   * supports a single @{code String} value as a key for cache entries, this utility helps to provide a standard way to
32   * generate such compound caching keys.
33   *
34   * <p>It is possible to use this utility class when specifying keys for cached objects using Spring's caching
35   * abstraction (which is what the Rice caching infrastructure is built on).  This is possible using the Spring
36   * Expression Language (SPEL).  An example might look something like the following:</p>
37   *
38   * <pre>
39   * {@code @Cacheable(value = "StuffCache", key="'ids=' + T(org.kuali.rice.core.api.cache.CacheKeyUtils).key(#p0)")
40   * List<Stuff> getStuff(List<String> stuffIds); }
41   * </pre>
42   *
43   * @author Kuali Rice Team (rice.collab@kuali.org)
44   * @since 2.0
45   */
46  public final class CacheKeyUtils {
47  
48      private CacheKeyUtils() {
49          throw new UnsupportedOperationException();
50      }
51  
52      /**
53       * Create a String key value out of a Collection.  It accomplishes this by first sorting the given collection
54       * (entries in the collection must implement Comparable) and then construct a key based on the {@code .toString()}
55       * values of each item in the sorted collection.
56       *
57       * <p>The sorting of the given list happens on a copy of the list, so this method does not side-affect the given
58       * list.</p>
59       *
60       * @param col the collection.  if null will return "", if empty, will return "[]"
61       * @param <K> the col type
62       * 
63       * @return the collection as a string value
64       */
65      public static <K extends Comparable<K>> String key(Collection<K> col) {
66          if (col == null) {
67              return "";
68          }
69  
70          final List<K> sorted = new ArrayList<K>(col);
71  
72          if (col.size() > 1) {
73              Collections.sort(sorted);
74          }
75  
76          final StringBuilder b = new StringBuilder("[");
77          for (K entry : sorted) {
78              if (entry != null) {
79                  b.append(entry);
80                  b.append(",");
81              }
82          }
83          b.append("]");
84          return b.toString();
85      }
86  
87      /**
88       * Create a String key value out of a Map.  It accomplishes this by first sorting the given map on it's keys
89       * (keys in the map must implement Comparable) and then construct a key based on the {@code .toString()}
90       * values of each item in the sorted collection.
91       *
92       * <p>The sorting of the given map happens on a copy of the map, so this method does not side-affect the given
93       * map.</p>
94       *
95       * @param col the map.  if null will return "", if empty, will return "[]"
96       * @param <K> the col type
97       *
98       * @return the map as a string value
99       */
100     public static <K extends Comparable<K>> String mapKey(Map<K, ?> col) {
101         if (col == null) {
102             return "";
103         }
104 
105         final List<K> sorted = new ArrayList<K>(col.keySet());
106 
107         if (col.size() > 1) {
108             Collections.sort(sorted);
109         }
110 
111         final StringBuilder b = new StringBuilder("[");
112         for (K entry : sorted) {
113             if (entry != null) {
114                 b.append(entry);
115                 b.append("|");
116                 b.append(col.get(entry));
117                 b.append(",");
118             }
119         }
120         b.append("]");
121         return b.toString();
122     }
123 
124 }