2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with the com.oreilly.servlet library, any library
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24 * the above that use the same license as the above), and distribute linked
25 * combinations including the two. You must obey the GNU General Public
26 * License in all respects for all of the code used other than the above
27 * mentioned libraries. If you modify this file, you may extend this exception
28 * to your version of the file, but you are not obligated to do so. If you do
29 * not wish to do so, delete this exception statement from your version.
32 import freemarker.template.SimpleList;
33 import freemarker.template.SimpleHash;
34 import freemarker.template.SimpleScalar;
35 import mir.misc.HTMLParseException;
36 import mir.misc.HTMLTemplateProcessor;
37 import mir.misc.MirConfig;
38 import mir.misc.StringUtil;
40 import mir.producer.*;
42 import mircoders.global.*;
43 import mircoders.localizer.*;
44 import mircoders.entity.EntityUsers;
45 import mircoders.module.ModuleMessage;
46 import mircoders.module.ModuleUsers;
47 import mircoders.storage.DatabaseArticleType;
48 import mircoders.storage.DatabaseMessages;
49 import mircoders.storage.DatabaseUsers;
51 import javax.servlet.ServletException;
52 import javax.servlet.UnavailableException;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55 import javax.servlet.http.HttpSession;
56 import java.io.IOException;
57 import java.io.PrintWriter;
58 import java.lang.reflect.Method;
59 import java.util.GregorianCalendar;
60 import java.util.HashMap;
61 import java.util.Locale;
67 * Mir.java - main servlet, that dispatches to servletmodules
69 * @author $Author: mh $
70 * @version $Id: Mir.java,v 1.23 2002/12/06 08:12:42 mh Exp $
75 public class Mir extends AbstractServlet {
77 private static ModuleUsers usersModule = null;
78 private static ModuleMessage messageModule = null;
79 private final static HashMap servletModuleInstanceHash = new HashMap();
81 public HttpSession session;
83 public void doGet(HttpServletRequest req, HttpServletResponse res)
84 throws ServletException, IOException {
88 public void doPost(HttpServletRequest req, HttpServletResponse res)
89 throws ServletException, IOException, UnavailableException {
93 long startTime = System.currentTimeMillis();
94 long sessionConnectTime = 0;
95 EntityUsers userEntity;
98 if (getServletContext().getAttribute("mir.confed") == null) {
102 MirConfig.setServletName(getServletName());
105 // Log.info(this, "blalalala");
107 session = req.getSession(true);
108 userEntity = (EntityUsers) session.getAttribute("login.uid");
110 if (req.getServerPort() == 443) http = "https"; else http = "http";
112 //nothing in Mir can or should be cached as it's all dynamic...
114 //this needs to be done here and not per page (via meta tags) as some
115 //browsers have problems w/ it per-page -mh
116 res.setHeader("Pragma", "no-cache");
117 res.setDateHeader("Expires", 0);
118 res.setHeader("Cache-Control", "no-cache");
119 res.setContentType("text/html; charset="
120 +MirConfig.getProp("Mir.DefaultEncoding"));
121 String moduleName = req.getParameter("module");
123 checkLanguage(session, req);
125 /** @todo for cleanup and readability this should be moved to
126 * method loginIfNecessary() */
128 if (moduleName!=null && moduleName.equals("direct")) {
133 if ((moduleName != null && moduleName.equals("login")) || (userEntity==null)) {
134 String user = req.getParameter("login");
135 String passwd = req.getParameter("password");
136 theLog.printDebugInfo("--login: evaluating for user: " + user);
137 userEntity = allowedUser(user, passwd);
138 if (userEntity == null) {
139 // login failed: redirecting to login
140 theLog.printWarning("--login: failed!");
141 _sendLoginPage(res, req, res.getWriter());
144 else if (moduleName!=null && moduleName.equals("login")) {
147 theLog.printInfo("--login: successful! setting uid: " + userEntity.getId());
148 session.setAttribute("login.uid", userEntity);
149 theLog.printDebugInfo("--login: trying to retrieve login.target");
150 String target = (String) session.getAttribute("login.target");
152 if (target != null) {
153 theLog.printDebugInfo("Redirect: " + target);
154 int serverPort = req.getServerPort();
155 String redirect = "";
156 String redirectString = "";
159 if (serverPort == 80) {
160 redirect = res.encodeURL(http + "://" + req.getServerName() + target);
161 redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
163 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
166 redirect = res.encodeURL(http + "://" + req.getServerName() + ":" + req.getServerPort() + target);
167 redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
169 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
171 res.getWriter().println(redirectString);
174 //res.sendRedirect(redirect);
178 // redirecting to default target
179 theLog.printDebugInfo("--login: no target - redirecting to default");
180 _sendStartPage(res, req, res.getWriter(), userEntity);
183 } // if login succesful
186 if (moduleName != null && moduleName.equals("logout")) {
187 theLog.printDebugInfo("--logout");
188 session.invalidate();
190 //session = req.getSession(true);
191 //checkLanguage(session, req);
192 _sendLoginPage(res, req, res.getWriter());
197 if (userEntity == null) {
198 // redirect to loginpage
199 String redirectString = req.getRequestURI();
200 String queryString = req.getQueryString();
201 if (queryString != null && !queryString.equals("")) {
202 redirectString += "?" + req.getQueryString();
203 theLog.printDebugInfo("STORING: " + redirectString);
204 session.setAttribute("login.target", redirectString);
206 _sendLoginPage(res, req, res.getWriter());
210 // If no module is specified goto standard startpage
211 if (moduleName == null || moduleName.equals("")) {
212 theLog.printDebugInfo("no module: redirect to standardpage");
213 _sendStartPage(res, req, res.getWriter(), userEntity);
218 // From now on regular dispatching...
220 // get servletmodule by parameter and continue with dispacher
221 ServletModule smod = getServletModuleForName(moduleName);
222 ServletModuleDispatch.dispatch(smod, req, res);
224 catch (ServletModuleException e) {
225 handleError(req, res, res.getWriter(),
226 "ServletException in Module " + moduleName + " -- " + e.getMessage());
228 catch (ServletModuleUserException e) {
229 handleUserError(req, res, res.getWriter(), e.getMessage());
233 sessionConnectTime = System.currentTimeMillis() - startTime;
234 theLog.printInfo("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
239 * Private method getServletModuleForName returns ServletModule
242 * @return ServletModule
245 private static ServletModule getServletModuleForName(String moduleName)
246 throws ServletModuleException {
249 if (!servletModuleInstanceHash.containsKey(moduleName)) {
250 // was not found in hash...
252 Class theServletModuleClass = null;
254 // first we try to get ServletModule from stern.che3.servlet
255 theServletModuleClass = Class.forName("mircoders.servlet.ServletModule" + moduleName);
257 catch (ClassNotFoundException e) {
258 // on failure, we try to get it from lib-layer
259 theServletModuleClass = Class.forName("mir.servlet.ServletModule" + moduleName);
261 Method m = theServletModuleClass.getMethod("getInstance", null);
262 ServletModule smod = (ServletModule) m.invoke(null, null);
263 // we put it into map for further reference
264 servletModuleInstanceHash.put(moduleName, smod);
267 catch (Exception e) {
268 throw new ServletModuleException("*** error resolving classname for " +
269 moduleName + " -- " + e.getMessage());
273 return (ServletModule) servletModuleInstanceHash.get(moduleName);
277 private void handleError(HttpServletRequest req, HttpServletResponse res,
278 PrintWriter out, String errorString) {
281 theLog.printError(errorString);
282 SimpleHash modelRoot = new SimpleHash();
283 modelRoot.put("errorstring", new SimpleScalar(errorString));
284 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
285 HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.ErrorTemplate"), modelRoot, out, getLocale(req));
288 catch (Exception e) {
289 e.printStackTrace(System.out);
290 System.err.println("Error in ErrorTemplate: " + e.getMessage());
294 private void handleUserError(HttpServletRequest req, HttpServletResponse res,
295 PrintWriter out, String errorString) {
297 theLog.printError(errorString);
298 SimpleHash modelRoot = new SimpleHash();
299 modelRoot.put("errorstring", new SimpleScalar(errorString));
300 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
301 HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.UserErrorTemplate"),
302 modelRoot, out, getLocale(req));
305 catch (Exception e) {
306 System.err.println("Error in UserErrorTemplate");
312 * evaluate login for user / password
314 protected EntityUsers allowedUser(String user, String password) {
316 if (usersModule == null) usersModule = new ModuleUsers(DatabaseUsers.getInstance());
317 return usersModule.getUserForLogin(user, password);
319 catch (Exception e) {
320 theLog.printDebugInfo(e.getMessage());
327 private void _sendLoginPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out) {
328 String loginTemplate = MirConfig.getProp("Mir.LoginTemplate");//"login.template";
329 // theLog.printDebugInfo("login template: "+loginTemplate);
330 String sessionUrl = res.encodeURL("");
331 //session = req.getSession(true);
333 //theLog.printDebugInfo("login: "+lang);
335 // lang=getAcceptLanguage(req);
337 SimpleHash mergeData = new SimpleHash();
338 mergeData.put("session", sessionUrl);
339 HTMLTemplateProcessor.process(res, loginTemplate, mergeData, out, getLocale(req));
341 catch (HTMLParseException e) {
342 handleError(req, res, out, "Error in logintemplate.");
346 private void _sendStartPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out, EntityUsers userEntity) {
347 String startTemplate = "templates/admin/start_admin.template";
348 String sessionUrl = res.encodeURL("");
350 // merge with logged in user and messages
351 SimpleHash mergeData = new SimpleHash();
352 mergeData.put("session", sessionUrl);
353 mergeData.put("login_user", userEntity);
354 if (messageModule == null) messageModule = new ModuleMessage(DatabaseMessages.getInstance());
355 mergeData.put("messages", messageModule.getByWhereClause(null, "webdb_create desc", 0, 10));
357 mergeData.put("articletypes", DatabaseArticleType.getInstance().selectByWhereClause("", "id", 0, 20));
360 SimpleList producersData = new SimpleList();
361 Iterator i = MirGlobal.localizer().producers().factories().entrySet().iterator();
362 while (i.hasNext()) {
363 Map.Entry entry = (Map.Entry) i.next();
365 SimpleList producerVerbs = new SimpleList();
366 Iterator j = ((ProducerFactory) entry.getValue()).verbs();
367 while (j.hasNext()) {
368 producerVerbs.add((String) j.next());
371 SimpleHash producerData = new SimpleHash();
372 producerData.put("key", (String) entry.getKey());
373 producerData.put("verbs", producerVerbs);
375 producersData.add(producerData);
377 mergeData.put("producers", producersData);
381 HTMLTemplateProcessor.process(res, startTemplate, mergeData, out, getLocale(req));
383 catch (Exception e) {
384 e.printStackTrace(System.out);
385 handleError(req, res, out, "error while trying to send startpage. " + e.getMessage());
389 public String getServletInfo() {
390 return "Mir "+MirConfig.getProp("Mir.Version");
393 private void checkLanguage(HttpSession session, HttpServletRequest req) {
395 // a lang parameter always sets the language
396 String lang = req.getParameter("lang");
398 theLog.printInfo("selected language "+lang+" overrides accept-language");
399 setLanguage(session, lang);
400 setLocale(session, new Locale(lang, ""));
402 // otherwise store language from accept header in session
403 else if (session.getAttribute("Language") == null) {
404 theLog.printInfo("accept-language is "+req.getLocale().getLanguage());
405 setLanguage(session, req.getLocale().getLanguage());
406 setLocale(session, req.getLocale());