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.SimpleHash;
33 import freemarker.template.SimpleScalar;
34 import mir.misc.HTMLParseException;
35 import mir.misc.HTMLTemplateProcessor;
36 import mir.misc.MirConfig;
37 import mir.misc.StringUtil;
39 import mircoders.entity.EntityUsers;
40 import mircoders.module.ModuleMessage;
41 import mircoders.module.ModuleUsers;
42 import mircoders.storage.DatabaseMessages;
43 import mircoders.storage.DatabaseUsers;
45 import javax.servlet.ServletException;
46 import javax.servlet.UnavailableException;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.servlet.http.HttpSession;
50 import java.io.IOException;
51 import java.io.PrintWriter;
52 import java.lang.reflect.Method;
53 import java.util.GregorianCalendar;
54 import java.util.HashMap;
55 import java.util.Locale;
58 * Mir.java - main servlet, that dispatches to servletmodules
60 * @author $Author: mh $
61 * @version $Revision: 1.17.2.2 $ $Date: 2002/11/25 21:59:47 $
64 * Revision 1.17.2.2 2002/11/25 21:59:47 mh
65 * use req.getContextPath to find the RootUri.. much more robust. 4.0 and 4.1 compatible due to new web.xml mapping
67 * Revision 1.17.2.1 2002/09/01 21:31:39 mh
70 * Revision 1.17 2002/07/21 22:27:39 mh
71 * make the user error msg look nicer
76 public class Mir extends AbstractServlet {
78 private static ModuleUsers usersModule = null;
79 private static ModuleMessage messageModule = null;
80 private final static HashMap servletModuleInstanceHash = new HashMap();
82 private static boolean nameSet = false;
84 public HttpSession session;
86 public void doGet(HttpServletRequest req, HttpServletResponse res)
87 throws ServletException, IOException {
91 public void doPost(HttpServletRequest req, HttpServletResponse res)
92 throws ServletException, IOException, UnavailableException {
94 long startTime = System.currentTimeMillis();
95 long sessionConnectTime = 0;
98 // get the configration - this could conflict if 2 mirs are in the
99 // VM maybe? to be checked. -mh
100 if (getServletContext().getAttribute("mir.confed") == null) {
105 MirConfig.setAdminServletName(getServletName());
109 session = req.getSession(true);
111 if (req.getServerPort() == 443) http = "https"; else http = "http";
112 res.setContentType("text/html; charset="
113 +MirConfig.getProp("Mir.DefaultEncoding"));
114 String moduleName = req.getParameter("module");
116 checkLanguage(session, req);
118 /** @todo for cleanup and readability this should be moved to
119 * method loginIfNecessary() */
122 if (moduleName != null && moduleName.equals("login")) {
123 String user = req.getParameter("login");
124 String passwd = req.getParameter("password");
125 theLog.printDebugInfo("--login: evaluating for user: " + user);
126 EntityUsers userEntity = allowedUser(user, passwd);
127 if (userEntity == null) {
128 // login failed: redirecting to login
129 theLog.printWarning("--login: failed!");
130 _sendLoginPage(res, req, res.getWriter());
136 theLog.printInfo("--login: successful! setting uid: " + userEntity.getId());
137 session.setAttribute("login.uid", userEntity);
138 theLog.printDebugInfo("--login: trying to retrieve login.target");
139 String target = (String) session.getAttribute("login.target");
141 if (target != null) {
142 theLog.printDebugInfo("Redirect: " + target);
143 int serverPort = req.getServerPort();
144 String redirect = "";
145 String redirectString = "";
148 if (serverPort == 80) {
149 redirect = res.encodeURL(http + "://" + req.getServerName() + target);
150 redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
152 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
155 redirect = res.encodeURL(http + "://" + req.getServerName() + ":" + req.getServerPort() + target);
156 redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
158 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
160 res.getWriter().println(redirectString);
163 //res.sendRedirect(redirect);
167 // redirecting to default target
168 theLog.printDebugInfo("--login: no target - redirecting to default");
169 _sendStartPage(res, req, res.getWriter(), userEntity);
172 } // if login succesful
175 if (moduleName != null && moduleName.equals("logout")) {
176 theLog.printDebugInfo("--logout");
177 session.invalidate();
179 //session = req.getSession(true);
180 //checkLanguage(session, req);
181 _sendLoginPage(res, req, res.getWriter());
186 EntityUsers userEntity = (EntityUsers) session.getAttribute("login.uid");
187 if (userEntity == null) {
188 // redirect to loginpage
189 String redirectString = req.getRequestURI();
190 String queryString = req.getQueryString();
191 if (queryString != null && !queryString.equals("")) {
192 redirectString += "?" + req.getQueryString();
193 theLog.printDebugInfo("STORING: " + redirectString);
194 session.setAttribute("login.target", redirectString);
196 _sendLoginPage(res, req, res.getWriter());
200 // If no module is specified goto standard startpage
201 if (moduleName == null || moduleName.equals("")) {
202 theLog.printDebugInfo("no module: redirect to standardpage");
203 _sendStartPage(res, req, res.getWriter(), userEntity);
208 // From now on regular dispatching...
210 // get servletmodule by parameter and continue with dispacher
211 ServletModule smod = getServletModuleForName(moduleName);
212 ServletModuleDispatch.dispatch(smod, req, res);
214 catch (ServletModuleException e) {
215 handleError(req, res, res.getWriter(),
216 "ServletException in Module " + moduleName + " -- " + e.toString());
218 catch (ServletModuleUserException e) {
219 handleUserError(req, res, res.getWriter(), e.getMsg());
223 sessionConnectTime = System.currentTimeMillis() - startTime;
224 theLog.printInfo("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
229 * Private method getServletModuleForName returns ServletModule
232 * @return ServletModule
235 private static ServletModule getServletModuleForName(String moduleName)
236 throws ServletModuleException {
239 if (!servletModuleInstanceHash.containsKey(moduleName)) {
240 // was not found in hash...
242 Class theServletModuleClass = null;
244 // first we try to get ServletModule from stern.che3.servlet
245 theServletModuleClass = Class.forName("mircoders.servlet.ServletModule" + moduleName);
247 catch (ClassNotFoundException e) {
248 // on failure, we try to get it from lib-layer
249 theServletModuleClass = Class.forName("mir.servlet.ServletModule" + moduleName);
251 Method m = theServletModuleClass.getMethod("getInstance", null);
252 ServletModule smod = (ServletModule) m.invoke(null, null);
253 // we put it into map for further reference
254 servletModuleInstanceHash.put(moduleName, smod);
257 catch (Exception e) {
258 throw new ServletModuleException("*** error resolving classname for " +
259 moduleName + " -- " + e.toString());
263 return (ServletModule) servletModuleInstanceHash.get(moduleName);
267 private void handleError(HttpServletRequest req, HttpServletResponse res,
268 PrintWriter out, String errorString) {
271 theLog.printError(errorString);
272 SimpleHash modelRoot = new SimpleHash();
273 modelRoot.put("errorstring", new SimpleScalar(errorString));
274 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
275 HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.ErrorTemplate"), modelRoot, out, getLocale(req));
278 catch (Exception e) {
279 System.err.println("Error in ErrorTemplate");
283 private void handleUserError(HttpServletRequest req, HttpServletResponse res,
284 PrintWriter out, String errorString) {
286 theLog.printError(errorString);
287 SimpleHash modelRoot = new SimpleHash();
288 modelRoot.put("errorstring", new SimpleScalar(errorString));
289 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
290 HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.UserErrorTemplate"),
291 modelRoot, out, getLocale(req));
294 catch (Exception e) {
295 System.err.println("Fehler in UserErrorTemplate");
301 * evaluate login for user / password
303 protected EntityUsers allowedUser(String user, String password) {
305 if (usersModule == null) usersModule = new ModuleUsers(DatabaseUsers.getInstance());
306 return usersModule.getUserForLogin(user, password);
308 catch (Exception e) {
309 theLog.printDebugInfo(e.toString());
316 private void _sendLoginPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out) {
317 String loginTemplate = MirConfig.getProp("Mir.LoginTemplate");//"login.template";
318 // theLog.printDebugInfo("login template: "+loginTemplate);
319 String sessionUrl = res.encodeURL("");
320 //session = req.getSession(true);
322 //theLog.printDebugInfo("login: "+lang);
324 // lang=getAcceptLanguage(req);
326 SimpleHash mergeData = new SimpleHash();
327 mergeData.put("session", sessionUrl);
328 HTMLTemplateProcessor.process(res, loginTemplate, mergeData, out, getLocale(req));
330 catch (HTMLParseException e) {
331 handleError(req, res, out, "Error in logintemplate.");
335 private void _sendStartPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out, EntityUsers userEntity) {
336 String startTemplate = "admin/start_admin.template";
337 String sessionUrl = res.encodeURL("");
339 // merge with logged in user and messages
340 SimpleHash mergeData = new SimpleHash();
341 mergeData.put("session", sessionUrl);
342 mergeData.put("login_user", userEntity);
343 if (messageModule == null) messageModule = new ModuleMessage(DatabaseMessages.getInstance());
344 mergeData.put("messages", messageModule.getByWhereClause(null, "webdb_create desc", 0, 10));
345 HTMLTemplateProcessor.process(res, startTemplate, mergeData, out, getLocale(req));
347 catch (Exception e) {
348 handleError(req, res, out, "error while trying to send startpage. " + e.toString());
352 public String getServletInfo() {
353 return "Mir "+MirConfig.getProp("Mir.Version");
356 private void checkLanguage(HttpSession session, HttpServletRequest req) {
358 // a lang parameter always sets the language
359 String lang = req.getParameter("lang");
361 theLog.printInfo("selected language "+lang+" overrides accept-language");
362 setLanguage(session, lang);
363 setLocale(session, new Locale(lang, ""));
365 // otherwise store language from accept header in session
366 else if (session.getAttribute("Language") == null) {
367 theLog.printInfo("accept-language is "+req.getLocale().getLanguage());
368 setLanguage(session, req.getLocale().getLanguage());
369 setLocale(session, req.getLocale());