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: Mar 3, 2003 / 11:43:35 AM
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum;
044:
045: import java.io.BufferedWriter;
046: import java.io.IOException;
047: import java.io.OutputStreamWriter;
048: import java.io.Writer;
049: import java.sql.Connection;
050:
051: import javax.servlet.ServletConfig;
052: import javax.servlet.ServletException;
053: import javax.servlet.http.HttpServletRequest;
054: import javax.servlet.http.HttpServletResponse;
055:
056: import net.jforum.context.JForumContext;
057: import net.jforum.context.RequestContext;
058: import net.jforum.context.ResponseContext;
059: import net.jforum.context.web.WebRequestContext;
060: import net.jforum.context.web.WebResponseContext;
061: import net.jforum.dao.MySQLVersionWorkarounder;
062: import net.jforum.entities.Banlist;
063: import net.jforum.exceptions.ExceptionWriter;
064: import net.jforum.exceptions.ForumStartupException;
065: import net.jforum.repository.BanlistRepository;
066: import net.jforum.repository.ModulesRepository;
067: import net.jforum.repository.RankingRepository;
068: import net.jforum.repository.SecurityRepository;
069: import net.jforum.repository.SmiliesRepository;
070: import net.jforum.util.I18n;
071: import net.jforum.util.preferences.ConfigKeys;
072: import net.jforum.util.preferences.SystemGlobals;
073: import freemarker.template.SimpleHash;
074: import freemarker.template.Template;
075:
076: /**
077: * Front Controller.
078: *
079: * @author Rafael Steil
080: * @version $Id: JForum.java,v 1.116 2007/10/10 04:54:20 rafaelsteil Exp $
081: */
082: public class JForum extends JForumBaseServlet {
083: private static boolean isDatabaseUp;
084:
085: /**
086: * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
087: */
088: public void init(ServletConfig config) throws ServletException {
089: super .init(config);
090: super .startApplication();
091:
092: // Start database
093: isDatabaseUp = ForumStartup.startDatabase();
094:
095: try {
096: Connection conn = DBConnection.getImplementation()
097: .getConnection();
098: conn
099: .setAutoCommit(!SystemGlobals
100: .getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS));
101:
102: // Try to fix some MySQL problems
103: MySQLVersionWorkarounder dw = new MySQLVersionWorkarounder();
104: dw.handleWorkarounds(conn);
105:
106: // Continues loading the forum
107: JForumExecutionContext ex = JForumExecutionContext.get();
108: ex.setConnection(conn);
109: JForumExecutionContext.set(ex);
110:
111: // Init general forum stuff
112: ForumStartup.startForumRepository();
113: RankingRepository.loadRanks();
114: SmiliesRepository.loadSmilies();
115: BanlistRepository.loadBanlist();
116: } catch (Throwable e) {
117: e.printStackTrace();
118: throw new ForumStartupException(
119: "Error while starting jforum", e);
120: } finally {
121: JForumExecutionContext.finish();
122: }
123: }
124:
125: /**
126: * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
127: */
128: public void service(HttpServletRequest req, HttpServletResponse res)
129: throws IOException, ServletException {
130: Writer out = null;
131: JForumContext forumContext = null;
132: RequestContext request = null;
133: ResponseContext response = null;
134: String encoding = SystemGlobals.getValue(ConfigKeys.ENCODING);
135:
136: try {
137: // Initializes the execution context
138: JForumExecutionContext ex = JForumExecutionContext.get();
139:
140: request = new WebRequestContext(req);
141: response = new WebResponseContext(res);
142:
143: this .checkDatabaseStatus();
144:
145: forumContext = new JForumContext(request.getContextPath(),
146: SystemGlobals
147: .getValue(ConfigKeys.SERVLET_EXTENSION),
148: request, response);
149: ex.setForumContext(forumContext);
150:
151: JForumExecutionContext.set(ex);
152:
153: // Setup stuff
154: SimpleHash context = JForumExecutionContext
155: .getTemplateContext();
156:
157: ControllerUtils utils = new ControllerUtils();
158: utils.refreshSession();
159:
160: context.put("logged", SessionFacade.isLogged());
161:
162: // Process security data
163: SecurityRepository.load(SessionFacade.getUserSession()
164: .getUserId());
165:
166: utils.prepareTemplateContext(context, forumContext);
167:
168: String module = request.getModule();
169:
170: // Gets the module class name
171: String moduleClass = module != null ? ModulesRepository
172: .getModuleClass(module) : null;
173:
174: if (moduleClass == null) {
175: // Module not found, send 404 not found response
176: response.sendError(HttpServletResponse.SC_NOT_FOUND);
177: } else {
178: boolean shouldBan = this .shouldBan(request
179: .getRemoteAddr());
180:
181: if (!shouldBan) {
182: context.put("moduleName", module);
183: context.put("action", request.getAction());
184: } else {
185: moduleClass = ModulesRepository
186: .getModuleClass("forums");
187: context.put("moduleName", "forums");
188: ((WebRequestContext) request)
189: .changeAction("banned");
190: }
191:
192: if (shouldBan
193: && SystemGlobals
194: .getBoolValue(ConfigKeys.BANLIST_SEND_403FORBIDDEN)) {
195: response
196: .sendError(HttpServletResponse.SC_FORBIDDEN);
197: } else {
198: context.put("language", I18n.getUserLanguage());
199: context.put("session", SessionFacade
200: .getUserSession());
201: context.put("request", req);
202: context.put("response", response);
203:
204: out = this .processCommand(out, request, response,
205: encoding, context, moduleClass);
206: }
207: }
208: } catch (Exception e) {
209: this .handleException(out, response, encoding, e, request);
210: } finally {
211: this .handleFinally(out, forumContext, response);
212: }
213: }
214:
215: private Writer processCommand(Writer out, RequestContext request,
216: ResponseContext response, String encoding,
217: SimpleHash context, String moduleClass) throws Exception {
218: // Here we go, baby
219: Command c = this .retrieveCommand(moduleClass);
220: Template template = c.process(request, response, context);
221:
222: if (JForumExecutionContext.getRedirectTo() == null) {
223: String contentType = JForumExecutionContext
224: .getContentType();
225:
226: if (contentType == null) {
227: contentType = "text/html; charset=" + encoding;
228: }
229:
230: response.setContentType(contentType);
231:
232: // Binary content are expected to be fully
233: // handled in the action, including outputstream
234: // manipulation
235: if (!JForumExecutionContext.isCustomContent()) {
236: out = new BufferedWriter(new OutputStreamWriter(
237: response.getOutputStream(), encoding));
238: template.process(JForumExecutionContext
239: .getTemplateContext(), out);
240: out.flush();
241: }
242: }
243:
244: return out;
245: }
246:
247: private void checkDatabaseStatus() {
248: if (!isDatabaseUp) {
249: synchronized (this ) {
250: if (!isDatabaseUp) {
251: isDatabaseUp = ForumStartup.startDatabase();
252: }
253: }
254: }
255: }
256:
257: private void handleFinally(Writer out, JForumContext forumContext,
258: ResponseContext response) throws IOException {
259: try {
260: if (out != null) {
261: out.close();
262: }
263: } catch (Exception e) {
264: // catch close error
265: }
266:
267: String redirectTo = JForumExecutionContext.getRedirectTo();
268: JForumExecutionContext.finish();
269:
270: if (redirectTo != null) {
271: if (forumContext != null
272: && forumContext.isEncodingDisabled()) {
273: response.sendRedirect(redirectTo);
274: } else {
275: response.sendRedirect(response
276: .encodeRedirectURL(redirectTo));
277: }
278: }
279: }
280:
281: private void handleException(Writer out, ResponseContext response,
282: String encoding, Exception e, RequestContext request)
283: throws IOException {
284: JForumExecutionContext.enableRollback();
285:
286: if (e.toString().indexOf("ClientAbortException") == -1) {
287: response.setContentType("text/html; charset=" + encoding);
288: if (out != null) {
289: new ExceptionWriter().handleExceptionData(e, out,
290: request);
291: } else {
292: new ExceptionWriter().handleExceptionData(e,
293: new BufferedWriter(new OutputStreamWriter(
294: response.getOutputStream())), request);
295: }
296: }
297: }
298:
299: private boolean shouldBan(String ip) {
300: Banlist b = new Banlist();
301:
302: b.setUserId(SessionFacade.getUserSession().getUserId());
303: b.setIp(ip);
304:
305: return BanlistRepository.shouldBan(b);
306: }
307:
308: private Command retrieveCommand(String moduleClass)
309: throws Exception {
310: return (Command) Class.forName(moduleClass).newInstance();
311: }
312:
313: /**
314: * @see javax.servlet.GenericServlet#destroy()
315: */
316: public void destroy() {
317: super .destroy();
318: System.out.println("Destroying JForum...");
319:
320: try {
321: DBConnection.getImplementation()
322: .realReleaseAllConnections();
323: ConfigLoader.stopCacheEngine();
324: } catch (Exception e) {
325: }
326: }
327: }
|