View Javadoc

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