1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.core.web.cache;
17
18 import org.kuali.rice.core.api.cache.CacheManagerRegistry;
19 import org.kuali.rice.core.api.util.tree.Node;
20 import org.kuali.rice.core.api.util.tree.Tree;
21 import org.kuali.rice.core.impl.services.CoreImplServiceLocator;
22 import org.kuali.rice.kim.api.KimConstants;
23 import org.kuali.rice.kim.api.identity.Person;
24 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
25 import org.kuali.rice.krad.util.GlobalVariables;
26 import org.kuali.rice.krad.util.KRADConstants;
27 import org.kuali.rice.krad.web.controller.UifControllerBase;
28 import org.kuali.rice.krad.web.form.UifFormBase;
29 import org.springframework.cache.CacheManager;
30 import org.springframework.stereotype.Controller;
31 import org.springframework.validation.BindingResult;
32 import org.springframework.web.bind.annotation.ModelAttribute;
33 import org.springframework.web.bind.annotation.RequestMapping;
34 import org.springframework.web.bind.annotation.RequestMethod;
35 import org.springframework.web.servlet.ModelAndView;
36
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39 import java.lang.reflect.InvocationTargetException;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.Comparator;
43 import java.util.List;
44
45 @Controller
46 @RequestMapping(value = "/core/admin/cache")
47 public class CacheAdminController extends UifControllerBase {
48
49 private CacheManagerRegistry registry;
50
51 public synchronized CacheManagerRegistry getRegistry() {
52 if (registry == null) {
53 registry = CoreImplServiceLocator.getCacheManagerRegistry();
54 }
55 return registry;
56 }
57
58
59
60
61 @Override
62 protected CacheAdminForm createInitialForm(HttpServletRequest request) {
63 return new CacheAdminForm();
64 }
65
66 @Override
67 @RequestMapping(params = "methodToCall=start")
68 public ModelAndView start(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
69 HttpServletRequest request, HttpServletResponse response) {
70
71 final Tree<String, String> cacheTree = new Tree<String,String>();
72
73 final Node<String,String> root = new Node<String,String>("Root", "Root");
74 final List<CacheManager> cms = new ArrayList<CacheManager>(getRegistry().getCacheManagers());
75 Collections.sort(cms, new ByName());
76
77 for (final CacheManager cm : cms) {
78 final String name = getRegistry().getCacheManagerName(cm);
79 final Node<String, String> cmNode = new Node<String, String>(name, name);
80 final List<String> names = new ArrayList<String>(cm.getCacheNames());
81 Collections.sort(names, String.CASE_INSENSITIVE_ORDER);
82
83 for (final String cn : names) {
84 String cacheSize = getCacheSize(name, cn);
85 final Node<String, String> cNode = new Node<String, String>(cn, cn + (cacheSize != null ? " - " + cacheSize : ""));
86
87
88
89 cmNode.addChild(cNode);
90 }
91
92 root.addChild(cmNode);
93 }
94
95 cacheTree.setRootElement(root);
96 ((CacheAdminForm) form).setCacheTree(cacheTree);
97
98 return super.start(form, result, request, response);
99 }
100
101 @RequestMapping(params = "methodToCall=flush", method = RequestMethod.POST)
102 public ModelAndView flush(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
103 HttpServletRequest request, HttpServletResponse response) {
104 Person user = GlobalVariables.getUserSession().getPerson();
105 boolean isAuthorized = KimApiServiceLocator.getPermissionService().isAuthorized(
106 user.getPrincipalId(),
107 KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE,
108 KRADConstants.USE_CACHE_ADMINISTRATION_SCREEN,
109 Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, user.getPrincipalId()));
110 if(isAuthorized){
111
112
113
114 for (String name : ((CacheAdminForm) form).getFlush()) {
115
116 final List<Integer> path = path(removePrefix(name));
117 final Tree<String, String> tree = ((CacheAdminForm) form).getCacheTree();
118 final Integer cmIdx = path.get(0);
119 final Node<String, String> cmNode = tree.getRootElement().getChildren().get(cmIdx);
120 final String cmName = cmNode.getData();
121 final CacheManager cm = getRegistry().getCacheManager(cmName);
122
123 if (path.size() == 1) {
124 flushAllCaches(cm);
125 GlobalVariables.getMessageMap().putInfoForSectionId("mainGroup_div","flush.all.cachemanager", cmName);
126 } else {
127 final Integer cIdx = path.get(1);
128 final Node<String, String> cNode = cmNode.getChildren().get(cIdx);
129 final String cName = cNode.getData();
130 flushSpecificCache(cm, cName);
131 GlobalVariables.getMessageMap().putInfoForSectionId("mainGroup_div",
132 "flush.single.cachemanager", cName, cmName);
133 }
134 }
135 }else{
136 GlobalVariables.getMessageMap().putError("flush","error.authorization.general",user.getPrincipalName(),"flush","cachemanager");
137 }
138 return super.start(form, result, request, response);
139 }
140
141 private static void flushSpecificCache(CacheManager cm, String cache) {
142 for (String s : cm.getCacheNames()) {
143 if (cache.equals(s)) {
144 cm.getCache(s).clear();
145 return;
146 }
147 }
148 }
149
150 private static void flushAllCaches(CacheManager cm) {
151 for (String s : cm.getCacheNames()) {
152 cm.getCache(s).clear();
153 }
154 }
155
156
157 private static String removePrefix(String s) {
158 final StringBuilder sbn = new StringBuilder(s);
159 sbn.delete(0, sbn.indexOf("_") + 1);
160 return sbn.toString();
161 }
162
163
164 private static List<Integer> path(String s) {
165 final String[] path = s.split("_parent_");
166 final List<Integer> pathIdx = new ArrayList<Integer>();
167
168 for (int i = path.length - 2; i >= 0; i--) {
169 pathIdx.add(Integer.valueOf(path[i].substring(5)));
170 }
171 return Collections.unmodifiableList(pathIdx);
172 }
173
174
175
176
177
178 private String getCacheSize(String cacheManagerName, String cacheName) {
179 Object nativeCache = getRegistry().getCacheManager(cacheManagerName).getCache(cacheName).getNativeCache();
180 try {
181 Class<?> ehcache = Class.forName("net.sf.ehcache.Cache");
182 if (ehcache.isInstance(nativeCache)) {
183 Object intSize = ehcache.getDeclaredMethod("getSize").invoke(nativeCache);
184 if (intSize != null) {
185 return intSize.toString();
186 }
187 }
188 } catch (ClassNotFoundException e) {
189
190 } catch (NoSuchMethodException e) {
191
192 } catch (InvocationTargetException e) {
193
194 } catch (IllegalAccessException e) {
195
196 }
197 return null;
198 }
199
200 private final class ByName implements Comparator<CacheManager> {
201
202 @Override
203 public int compare(CacheManager o1, CacheManager o2) {
204 return String.CASE_INSENSITIVE_ORDER.compare(getRegistry().getCacheManagerName(o1),
205 getRegistry().getCacheManagerName(o2));
206 }
207 }
208
209 }