001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.util; 017 018import org.kuali.rice.krad.UserSession; 019import org.kuali.rice.krad.uif.util.UifFormManager; 020import org.kuali.rice.core.framework.util.ApplicationThreadLocal; 021 022import java.util.HashMap; 023import java.util.LinkedList; 024import java.util.Map; 025import java.util.concurrent.Callable; 026 027/** 028 * Holds all of our thread local variables and accessors for those 029 * 030 * @author Kuali Rice Team (rice.collab@kuali.org) 031 */ 032public final class GlobalVariables { 033 034 private static ThreadLocal<LinkedList<GlobalVariables>> GLOBAL_VARIABLES_STACK = new ApplicationThreadLocal<LinkedList<GlobalVariables>>() { 035 protected LinkedList<GlobalVariables> initialValue() { 036 LinkedList<GlobalVariables> globalVariablesStack = new LinkedList<GlobalVariables>(); 037 globalVariablesStack.add(new GlobalVariables()); 038 return globalVariablesStack; 039 } 040 }; 041 042 private static GlobalVariables getCurrentGlobalVariables() { 043 return GLOBAL_VARIABLES_STACK.get().getLast(); 044 } 045 046 static GlobalVariables pushGlobalVariables() { 047 GlobalVariables vars = new GlobalVariables(); 048 GLOBAL_VARIABLES_STACK.get().add(vars); 049 return vars; 050 } 051 052 static GlobalVariables popGlobalVariables() { 053 return GLOBAL_VARIABLES_STACK.get().removeLast(); 054 } 055 056 static void reset() { 057 LinkedList<GlobalVariables> stack = GLOBAL_VARIABLES_STACK.get(); 058 stack.clear(); 059 stack.add(new GlobalVariables()); 060 } 061 062 private UserSession userSession = null; 063 private String hideSessionFromTestsMessage = null; 064 private MessageMap messageMap = new MessageMap(); 065 private Map<String,Object> requestCache = new HashMap<String, Object>(); 066 private UifFormManager uifFormManager = null; 067 068 private GlobalVariables() {} 069 070 /** 071 * @return the UserSession that has been assigned to this thread of execution it is important that this not be called by 072 * anything that lives outside 073 */ 074 public static UserSession getUserSession() { 075 GlobalVariables vars = getCurrentGlobalVariables(); 076 String message = vars.hideSessionFromTestsMessage; 077 if (message != null) { 078 throw new RuntimeException(message); 079 } 080 return vars.userSession; 081 } 082 083 /** 084 * Sets an error message for tests that try to use the session without declaring it. 085 * This method should be use by only KualiTestBase, not by other test code and especially not by production code. 086 * 087 * @param message the detail to throw, or null to allow access to the session 088 */ 089 public static void setHideSessionFromTestsMessage(String message) { 090 GlobalVariables vars = getCurrentGlobalVariables(); 091 vars.hideSessionFromTestsMessage = message; 092 } 093 094 /** 095 * sets the userSession object into the global variable for this thread 096 * 097 * @param userSession 098 */ 099 public static void setUserSession(UserSession userSession) { 100 GlobalVariables vars = getCurrentGlobalVariables(); 101 vars.userSession = userSession; 102 } 103 104 public static MessageMap getMessageMap() { 105 GlobalVariables vars = getCurrentGlobalVariables(); 106 return vars.messageMap; 107 } 108 109 /** 110 * Merges a message map into the global variables error map 111 * @param messageMap 112 */ 113 public static void mergeErrorMap(MessageMap messageMap) { 114 getMessageMap().getErrorMessages().putAll(messageMap.getErrorMessages()); 115 getMessageMap().getWarningMessages().putAll(messageMap.getWarningMessages()); 116 getMessageMap().getInfoMessages().putAll(messageMap.getInfoMessages()); 117 } 118 119 /** 120 * Sets a new (clean) MessageMap 121 * 122 * @param messageMap 123 */ 124 public static void setMessageMap(MessageMap messageMap) { 125 GlobalVariables vars = getCurrentGlobalVariables(); 126 vars.messageMap = messageMap; 127 } 128 129 public static Object getRequestCache(String cacheName) { 130 GlobalVariables vars = getCurrentGlobalVariables(); 131 return vars.requestCache.get(cacheName); 132 } 133 134 public static void setRequestCache(String cacheName, Object cacheObject) { 135 GlobalVariables vars = getCurrentGlobalVariables(); 136 vars.requestCache.put(cacheName, cacheObject); 137 } 138 139 /** 140 * Retrieves the {@link org.kuali.rice.krad.uif.util.UifFormManager} which can be used to store and remove forms 141 * from the session 142 * 143 * @return UifFormManager 144 */ 145 public static UifFormManager getUifFormManager() { 146 GlobalVariables vars = getCurrentGlobalVariables(); 147 return vars.uifFormManager; 148 } 149 150 /** 151 * Sets a {@link org.kuali.rice.krad.uif.util.UifFormManager} for the current thread 152 * 153 * @param uifFormManager 154 */ 155 public static void setUifFormManager(UifFormManager uifFormManager) { 156 GlobalVariables vars = getCurrentGlobalVariables(); 157 vars.uifFormManager = uifFormManager; 158 } 159 160 /** 161 * Clears out GlobalVariable objects with the exception of the UserSession 162 */ 163 public static void clear() { 164 GlobalVariables vars = getCurrentGlobalVariables(); 165 vars.messageMap = new MessageMap(); 166 vars.requestCache = new HashMap<String,Object>(); 167 } 168 169 /** 170 * Pushes a new GlobalVariables object onto the ThreadLocal GlobalVariables stack, invokes the runnable, 171 * and pops the GlobalVariables off in a finally clause 172 * @param callable the code to run under a new set of GlobalVariables 173 */ 174 public static <T> T doInNewGlobalVariables(Callable<T> callable) throws Exception { 175 return doInNewGlobalVariables(null, callable); 176 } 177 178 /** 179 * Convenience method that creates a new GlobalVariables stack frame, initialized with the provided 180 * UserSession (which may be the previous UserSession). 181 * @param userSession the UserSession to initialize the new frame with (may be null) 182 * @param callable the code to run under a new set of GlobalVariables 183 * @throws Exception 184 */ 185 public static <T> T doInNewGlobalVariables(UserSession userSession, Callable<T> callable) throws Exception { 186 try { 187 GlobalVariables vars = pushGlobalVariables(); 188 if (userSession != null) { 189 vars.userSession = userSession; 190 } 191 return callable.call(); 192 } finally { 193 popGlobalVariables(); 194 } 195 } 196}