001: /*
002: * Copyright (c) JForum Team
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms,
006: * with or without modification, are permitted provided
007: * that the following conditions are met:
008: *
009: * 1) Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the
011: * following disclaimer.
012: * 2) Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and
014: * the following disclaimer in the documentation and/or
015: * other materials provided with the distribution.
016: * 3) Neither the name of "Rafael Steil" nor
017: * the names of its contributors may be used to endorse
018: * or promote products derived from this software without
019: * specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
034: * IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: *
039: * This file creation date: 29/01/2006 - 12:19:11
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum;
044:
045: import java.io.IOException;
046: import java.sql.Connection;
047:
048: import javax.servlet.http.HttpServletResponse;
049:
050: import net.jforum.context.RequestContext;
051: import net.jforum.context.ResponseContext;
052: import net.jforum.context.ForumContext;
053: import net.jforum.exceptions.ForumException;
054: import net.jforum.util.preferences.ConfigKeys;
055: import net.jforum.util.preferences.SystemGlobals;
056:
057: import org.apache.log4j.Logger;
058:
059: import freemarker.template.Configuration;
060: import freemarker.template.ObjectWrapper;
061: import freemarker.template.SimpleHash;
062:
063: /**
064: * Data execution context.
065: *
066: * @author Rafael Steil
067: * @version $Id: JForumExecutionContext.java,v 1.10 2006/10/10 01:59:55 rafaelsteil Exp $
068: */
069: public class JForumExecutionContext {
070: private static ThreadLocal userData = new ThreadLocal();
071: private static Logger logger = Logger
072: .getLogger(JForumExecutionContext.class);
073: private static Configuration templateConfig;
074:
075: private Connection conn;
076: private ForumContext forumContext;
077: private SimpleHash context = new SimpleHash(
078: ObjectWrapper.BEANS_WRAPPER);
079: private String redirectTo;
080: private String contentType;
081: private boolean isCustomContent;
082: private boolean enableRollback;
083:
084: /**
085: * Gets the execution context.
086: * @return JForumExecutionContext
087: */
088: public static JForumExecutionContext get() {
089: JForumExecutionContext ex = (JForumExecutionContext) userData
090: .get();
091:
092: if (ex == null) {
093: ex = new JForumExecutionContext();
094: userData.set(ex);
095: }
096:
097: return ex;
098: }
099:
100: /**
101: * Checks if there is an execution context already set
102: * @return <code>true</code> if there is an execution context
103: * @see #get()
104: */
105: public static boolean exists() {
106: return (userData.get() != null);
107: }
108:
109: /**
110: * Sets the default template configuration
111: * @param config The template configuration to set
112: */
113: public static void setTemplateConfig(Configuration config) {
114: templateConfig = config;
115: }
116:
117: /**
118: * Gets a reference to the default template configuration settings.
119: * @return The template configuration instance
120: */
121: public static Configuration templateConfig() {
122: return templateConfig;
123: }
124:
125: /**
126: * Sets the execution context
127: * @param ex JForumExecutionContext
128: */
129: public static void set(JForumExecutionContext ex) {
130: userData.set(ex);
131: }
132:
133: /**
134: * Sets a connection
135: * @param conn The connection to use
136: */
137: public void setConnection(Connection conn) {
138: this .conn = conn;
139: }
140:
141: /**
142: * Gets the current thread's connection
143: * @return Connection
144: */
145: public static Connection getConnection() {
146: return getConnection(true);
147: }
148:
149: public static Connection getConnection(boolean validate) {
150: JForumExecutionContext ex = get();
151: Connection c = ex.conn;
152:
153: if (validate && c == null) {
154: c = DBConnection.getImplementation().getConnection();
155:
156: try {
157: c
158: .setAutoCommit(!SystemGlobals
159: .getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS));
160: } catch (Exception e) {
161: //catch error autocommit
162: }
163:
164: ex.setConnection(c);
165: set(ex);
166: }
167:
168: return c;
169: }
170:
171: public static ForumContext getForumContext() {
172: return ((JForumExecutionContext) userData.get()).forumContext;
173: }
174:
175: public void setForumContext(ForumContext forumContext) {
176: this .forumContext = forumContext;
177: }
178:
179: /**
180: * Gets the current thread's request
181: * @return WebContextRequest
182: */
183: public static RequestContext getRequest() {
184: return getForumContext().getRequest();
185: }
186:
187: /**
188: * Gets the current thread's response
189: * @return HttpServletResponse
190: */
191: public static ResponseContext getResponse() {
192: return getForumContext().getResponse();
193: }
194:
195: /**
196: * Gets the current thread's template context
197: * @return SimpleHash
198: */
199: public static SimpleHash getTemplateContext() {
200: return ((JForumExecutionContext) userData.get()).context;
201: }
202:
203: /**
204: * Gets the current thread's <code>DataHolder</code> instance
205: * @param redirect String
206: */
207: public static void setRedirect(String redirect) {
208: ((JForumExecutionContext) userData.get()).redirectTo = redirect;
209: }
210:
211: /**
212: * Sets the content type for the current http response.
213: * @param contentType String
214: */
215: public static void setContentType(String contentType) {
216: ((JForumExecutionContext) userData.get()).contentType = contentType;
217: }
218:
219: /**
220: * Gets the content type for the current request.
221: * @return String
222: */
223: public static String getContentType() {
224: return ((JForumExecutionContext) userData.get()).contentType;
225: }
226:
227: /**
228: * Gets the URL to redirect to, if any.
229: * @return The URL to redirect, of <code>null</code> if none.
230: */
231: public static String getRedirectTo() {
232: JForumExecutionContext ex = (JForumExecutionContext) userData
233: .get();
234: return (ex != null ? ex.redirectTo : null);
235: }
236:
237: /**
238: * Marks the request to use a binary content-type.
239: * @param enable boolean
240: */
241: public static void enableCustomContent(boolean enable) {
242: ((JForumExecutionContext) userData.get()).isCustomContent = enable;
243: }
244:
245: /**
246: * Checks if the current request is binary
247: * @return <code>true</code> if the content tyee for the current request is
248: * any binary data.
249: */
250: public static boolean isCustomContent() {
251: return ((JForumExecutionContext) userData.get()).isCustomContent;
252: }
253:
254: /**
255: * Forces the request to not commit the connection.
256: */
257: public static void enableRollback() {
258: ((JForumExecutionContext) userData.get()).enableRollback = true;
259: }
260:
261: /**
262: * Check if commit is disabled or not for the current request.
263: * @return <code>true</code> if a commit should NOT be made
264: */
265: public static boolean shouldRollback() {
266: return ((JForumExecutionContext) userData.get()).enableRollback;
267: }
268:
269: /**
270: * Send UNAUTHORIZED to the browser and ask user to login via basic authentication
271: */
272: public static void requestBasicAuthentication() {
273: getResponse().addHeader("WWW-Authenticate",
274: "Basic realm=\"JForum\"");
275:
276: try {
277: getResponse()
278: .sendError(HttpServletResponse.SC_UNAUTHORIZED);
279: } catch (IOException e) {
280: throw new ForumException(e);
281: }
282:
283: enableCustomContent(true);
284: }
285:
286: /**
287: * Finishes the execution context
288: */
289: public static void finish() {
290: Connection conn = JForumExecutionContext.getConnection(false);
291:
292: if (conn != null) {
293: if (SystemGlobals
294: .getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS)) {
295: if (JForumExecutionContext.shouldRollback()) {
296: try {
297: conn.rollback();
298: } catch (Exception e) {
299: logger
300: .error(
301: "Error while rolling back a transaction",
302: e);
303: }
304: } else {
305: try {
306: conn.commit();
307: } catch (Exception e) {
308: logger.error(
309: "Error while commiting a transaction",
310: e);
311: }
312: }
313: }
314:
315: try {
316: DBConnection.getImplementation()
317: .releaseConnection(conn);
318: } catch (Exception e) {
319: logger.error("Error while releasing the connection : "
320: + e, e);
321: }
322: }
323:
324: userData.set(null);
325: }
326: }
|