001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket; 018 019import org.apache.wicket.request.cycle.RequestCycle; 020 021/** 022 * Holds thread local state for Wicket data. 023 * 024 * @author Matej Knopp 025 */ 026public class ThreadContext 027{ 028 private Application application; 029 030 private RequestCycle requestCycle; 031 032 private Session session; 033 034 private static final ThreadLocal<ThreadContext> threadLocal = new ThreadLocal<ThreadContext>(); 035 036 /** 037 * INTERNAL METHOD 038 * 039 * @param createIfDoesNotExist 040 * @return ThreadContext 041 */ 042 public static ThreadContext get(boolean createIfDoesNotExist) 043 { 044 ThreadContext context = threadLocal.get(); 045 if (context == null) 046 { 047 if (createIfDoesNotExist) 048 { 049 context = new ThreadContext(); 050 threadLocal.set(context); 051 } 052 else 053 { 054 /* 055 * There is no ThreadContext set, but the threadLocal.get() operation has registered 056 * the threadLocal in this Thread's ThreadLocal map. We must now remove it. 057 */ 058 threadLocal.remove(); 059 } 060 } 061 return context; 062 } 063 064 /** 065 * Checks if {@link ThreadContext} exists for the current thread 066 * 067 * @return {@code true} if {@link ThreadContext} exists for the current thread 068 */ 069 public static boolean exists() 070 { 071 return get(false) != null; 072 } 073 074 /** 075 * @return {@link Application} bound to current thread 076 */ 077 public static Application getApplication() 078 { 079 ThreadContext context = get(false); 080 return context != null ? context.application : null; 081 } 082 083 /** 084 * Binds the specified application to current thread. 085 * 086 * @param application 087 */ 088 public static void setApplication(Application application) 089 { 090 ThreadContext context = get(true); 091 context.application = application; 092 } 093 094 /** 095 * @return {@link RequestCycle} bound to current thrad 096 */ 097 public static RequestCycle getRequestCycle() 098 { 099 ThreadContext context = get(false); 100 return context != null ? context.requestCycle : null; 101 } 102 103 /** 104 * Binds the {@link RequestCycle} to current thread. 105 * 106 * @param requestCycle 107 */ 108 public static void setRequestCycle(RequestCycle requestCycle) 109 { 110 ThreadContext context = get(true); 111 context.requestCycle = requestCycle; 112 } 113 114 /** 115 * @return {@link Session} bound to current thread 116 */ 117 public static Session getSession() 118 { 119 ThreadContext context = get(false); 120 return context != null ? context.session : null; 121 } 122 123 /** 124 * Binds the session to current thread. 125 * 126 * @param session 127 */ 128 public static void setSession(Session session) 129 { 130 ThreadContext context = get(true); 131 context.session = session; 132 } 133 134 /** 135 * Cleans the {@link ThreadContext} and returns previous context. 136 * 137 * @return old {@link ThreadContext} 138 */ 139 public static ThreadContext detach() 140 { 141 ThreadContext value = threadLocal.get(); 142 threadLocal.remove(); 143 return value; 144 } 145 146 /** 147 * Restores the context 148 * 149 * @param threadContext 150 * @see #detach() 151 */ 152 public static void restore(ThreadContext threadContext) 153 { 154 if (threadContext == null) 155 { 156 threadLocal.remove(); 157 } 158 else 159 { 160 threadLocal.set(threadContext); 161 } 162 } 163 164 /** 165 * Construct. 166 */ 167 private ThreadContext() 168 { 169 } 170}