View Javadoc
1   /**
2    * Copyright 2005-2014 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.krad.util;
17  
18  import org.kuali.rice.krad.UserSession;
19  import org.kuali.rice.krad.web.form.UifFormManager;
20  import org.kuali.rice.core.framework.util.ApplicationThreadLocal;
21  
22  import java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.Map;
25  import java.util.concurrent.Callable;
26  
27  /**
28   * Holds all of our thread local variables and accessors for those
29   *
30   * @author Kuali Rice Team (rice.collab@kuali.org)
31   */
32  public final class GlobalVariables {
33  
34      private static ThreadLocal<LinkedList<GlobalVariables>> GLOBAL_VARIABLES_STACK = new ApplicationThreadLocal<LinkedList<GlobalVariables>>() {
35          protected LinkedList<GlobalVariables> initialValue() {
36              LinkedList<GlobalVariables> globalVariablesStack = new LinkedList<GlobalVariables>();
37              globalVariablesStack.add(new GlobalVariables());
38              return globalVariablesStack;
39          }
40      };
41  
42      public static GlobalVariables getCurrentGlobalVariables() {
43          return GLOBAL_VARIABLES_STACK.get().getLast();
44      }
45  
46      public static void injectGlobalVariables(GlobalVariables globalVariables) {
47          GLOBAL_VARIABLES_STACK.get().add(globalVariables);
48      }
49  
50      public static GlobalVariables popGlobalVariables() {
51          return GLOBAL_VARIABLES_STACK.get().removeLast();
52      }
53  
54      static GlobalVariables pushGlobalVariables() {
55          GlobalVariables vars = new GlobalVariables();
56          GLOBAL_VARIABLES_STACK.get().add(vars);
57          return vars;
58      }
59  
60      static void reset() {
61          LinkedList<GlobalVariables> stack = GLOBAL_VARIABLES_STACK.get();
62          stack.clear();
63          stack.add(new GlobalVariables());
64      }
65  
66      private UserSession userSession = null;
67      private String hideSessionFromTestsMessage = null;
68      private MessageMap messageMap = new MessageMap();
69      private Map<String,Object> requestCache = new HashMap<String, Object>();
70      private UifFormManager uifFormManager = null;
71  
72      private GlobalVariables() {}
73  
74      /**
75       * @return the UserSession that has been assigned to this thread of execution it is important that this not be called by
76       *         anything that lives outside
77       */
78      public static UserSession getUserSession() {
79          GlobalVariables vars = getCurrentGlobalVariables();
80          String message = vars.hideSessionFromTestsMessage;
81          if (message != null) {
82              throw new RuntimeException(message);
83          }
84          return vars.userSession;
85      }
86  
87      /**
88       * Sets an error message for tests that try to use the session without declaring it.
89       * This method should be use by only KualiTestBase, not by other test code and especially not by production code.
90       *
91       * @param message the detail to throw, or null to allow access to the session
92       */
93      public static void setHideSessionFromTestsMessage(String message) {
94          GlobalVariables vars = getCurrentGlobalVariables();
95          vars.hideSessionFromTestsMessage = message;
96      }
97  
98      /**
99       * sets the userSession object into the global variable for this thread
100      *
101      * @param userSession
102      */
103     public static void setUserSession(UserSession userSession) {
104         GlobalVariables vars = getCurrentGlobalVariables();
105         vars.userSession = userSession;
106     }
107 
108     public static MessageMap getMessageMap() {
109         GlobalVariables vars = getCurrentGlobalVariables();
110         return vars.messageMap;
111     }
112 
113     /**
114      * Merges a message map into the global variables error map
115      * @param messageMap
116      */
117     public static void mergeErrorMap(MessageMap messageMap) {
118         getMessageMap().getErrorMessages().putAll(messageMap.getErrorMessages());
119         getMessageMap().getWarningMessages().putAll(messageMap.getWarningMessages());
120         getMessageMap().getInfoMessages().putAll(messageMap.getInfoMessages());
121     }
122 
123     /**
124      * Sets a new (clean) MessageMap
125      *
126      * @param messageMap
127      */
128     public static void setMessageMap(MessageMap messageMap) {
129         GlobalVariables vars = getCurrentGlobalVariables();
130         vars.messageMap = messageMap;
131     }
132 
133     public static Object getRequestCache(String cacheName) {
134         GlobalVariables vars = getCurrentGlobalVariables();
135         return vars.requestCache.get(cacheName);
136     }
137 
138     public static void setRequestCache(String cacheName, Object cacheObject) {
139         GlobalVariables vars = getCurrentGlobalVariables();
140         synchronized (vars.requestCache) {
141             vars.requestCache.put(cacheName, cacheObject);
142         }
143     }
144 
145     /**
146      * Retrieves the {@link org.kuali.rice.krad.web.form.UifFormManager} which can be used to store and remove forms
147      * from the session
148      *
149      * @return UifFormManager
150      */
151     public static UifFormManager getUifFormManager() {
152         GlobalVariables vars = getCurrentGlobalVariables();
153         return vars.uifFormManager;
154     }
155 
156     /**
157      * Sets a {@link org.kuali.rice.krad.web.form.UifFormManager} for the current thread
158      *
159      * @param uifFormManager
160      */
161     public static void setUifFormManager(UifFormManager uifFormManager) {
162         GlobalVariables vars = getCurrentGlobalVariables();
163         vars.uifFormManager = uifFormManager;
164     }
165 
166     /**
167      * Clears out GlobalVariable objects with the exception of the UserSession
168      */
169     public static void clear() {
170         GlobalVariables vars = getCurrentGlobalVariables();
171         vars.messageMap = new MessageMap();
172         vars.requestCache = new HashMap<String,Object>();
173     }
174 
175     /**
176      * Pushes a new GlobalVariables object onto the ThreadLocal GlobalVariables stack, invokes the runnable,
177      * and pops the GlobalVariables off in a finally clause
178      * 
179      * @param <T> callable return type
180      * @param callable the code to run under a new set of GlobalVariables
181      * @return return value from callable
182      * @throws Exception from {@link Callable#call()}
183      */
184     public static <T> T doInNewGlobalVariables(Callable<T> callable) throws Exception {
185         return doInNewGlobalVariables(null, callable);
186     }
187 
188     /**
189      * Convenience method that creates a new GlobalVariables stack frame, initialized with the provided
190      * UserSession (which may be the previous UserSession).
191      *
192      * @param <T> callable return type
193      * @param userSession the UserSession to initialize the new frame with (may be null)
194      * @param callable the code to run under a new set of GlobalVariables
195      * @return return value from callable
196      * @throws Exception from {@link Callable#call()}
197      */
198     public static <T> T doInNewGlobalVariables(UserSession userSession, Callable<T> callable) throws Exception {
199         try {
200             GlobalVariables vars = pushGlobalVariables();
201             if (userSession != null) {
202                 vars.userSession = userSession;
203             }
204             return callable.call();
205         } finally {
206             popGlobalVariables();
207         }
208     }
209 }