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 any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
31 import java.io.IOException;
32 import java.lang.reflect.Method;
33 import java.util.GregorianCalendar;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Locale;
39 import java.util.Vector;
41 import javax.servlet.ServletConfig;
42 import javax.servlet.ServletException;
43 import javax.servlet.UnavailableException;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46 import javax.servlet.http.HttpSession;
47 import javax.servlet.http.HttpSessionBindingEvent;
48 import javax.servlet.http.HttpSessionBindingListener;
50 import mir.config.MirPropertiesConfiguration;
51 import mir.servlet.AbstractServlet;
52 import mir.servlet.ServletModule;
53 import mir.servlet.ServletModuleDispatch;
54 import mir.servlet.ServletModuleExc;
55 import mir.servlet.ServletModuleUserExc;
56 import mir.util.ExceptionFunctions;
57 import mir.util.StringRoutines;
58 import mircoders.entity.EntityUsers;
59 import mircoders.global.MirGlobal;
60 import mircoders.module.ModuleUsers;
61 import mircoders.servlet.ServletHelper;
62 import mircoders.storage.DatabaseUsers;
64 import org.apache.struts.util.MessageResources;
70 * Mir.java - main servlet, that dispatches to servletmodules
72 * @author $Author: zapata $
73 * @version $Id: Mir.java,v 1.49.2.11 2004/01/18 17:30:56 zapata Exp $
76 public class Mir extends AbstractServlet {
77 private static ModuleUsers usersModule = null;
78 private final static Map servletModuleInstanceHash = new HashMap();
79 private static Locale fallbackLocale = null;
81 private static List loginLanguages = null;
83 protected List getLoginLanguages() throws ServletException {
84 synchronized (Mir.class) {
86 if (loginLanguages == null) {
87 MessageResources messageResources =
88 MessageResources.getMessageResources("bundles.adminlocal");
89 MessageResources messageResources2 =
90 MessageResources.getMessageResources("bundles.admin");
93 StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";");
95 loginLanguages = new Vector();
97 Iterator i = languages.iterator();
100 String code = (String) i.next();
101 Locale locale = new Locale(code, "");
102 String name = messageResources.getMessage(locale, "languagename");
105 name = messageResources2.getMessage(locale, "languagename");
112 Map record = new HashMap();
113 record.put("name", name);
114 record.put("code", code);
115 loginLanguages.add(record);
119 return loginLanguages;
121 catch (Throwable t) {
122 throw new ServletException(t.getMessage());
127 public void init(ServletConfig config) throws ServletException {
130 usersModule = new ModuleUsers(DatabaseUsers.getInstance());
133 protected String getDefaultLanguage(HttpServletRequest aRequest) {
134 String defaultlanguage =
135 MirGlobal.config().getString("Mir.Login.DefaultLanguage", "");
137 if (defaultlanguage.length() == 0) {
138 Locale locale = aRequest.getLocale();
139 defaultlanguage = locale.getLanguage();
142 return defaultlanguage;
145 protected synchronized Locale getFallbackLocale() throws ServletException {
147 if (fallbackLocale == null) {
148 fallbackLocale = new Locale(MirPropertiesConfiguration.instance().getString("Mir.Admin.FallbackLanguage", "en"), "");
151 catch (Throwable t) {
152 throw new ServletException(t.getMessage());
155 return fallbackLocale;
158 public EntityUsers checkCredentials(HttpServletRequest aRequest) throws ServletException {
160 EntityUsers user = ServletHelper.getUser(aRequest);
162 String username = aRequest.getParameter("login");
163 String password = aRequest.getParameter("password");
165 if (username != null && password != null) {
166 user = usersModule.getUserForLogin(username, password);
169 ServletHelper.setUser(aRequest, user);
170 usersModule.recordLogin(user);
171 aRequest.getSession().setAttribute("sessiontracker", new SessionTracker(username, user.getId()));
177 catch (Throwable t) {
180 throw new ServletException(t.toString());
184 public void process(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException, UnavailableException {
186 long startTime = System.currentTimeMillis();
187 long sessionConnectTime = 0;
189 HttpSession session = aRequest.getSession(true);
190 setNoCaching(aResponse);
191 aResponse.setContentType("text/html; charset=" +
193 getString("Mir.DefaultHTMLCharset", "UTF-8"));
195 EntityUsers userEntity = checkCredentials(aRequest);
197 if (userEntity == null) {
198 String queryString = aRequest.getQueryString();
200 if ( (queryString != null) && (queryString.length() != 0) && session.getAttribute("login.target") == null &&
201 (aRequest.getParameter("module")==null ||
202 (!aRequest.getParameter("module").equals("login") && !aRequest.getParameter("module").equals("logout")))) {
203 session.setAttribute("login.target", queryString);
206 _sendLoginPage(aResponse, aRequest);
209 String moduleName = aRequest.getParameter("module");
210 checkLanguage(session, aRequest);
212 if ( ( (moduleName == null) || moduleName.equals(""))) {
217 if (moduleName.equals("login")) {
218 String target = (String) session.getAttribute("login.target");
220 if (target != null) {
221 ServletHelper.redirect(aResponse, target);
224 ServletHelper.redirect(aResponse, "");
227 else if (moduleName.equals("logout")) {
228 logger.info(userEntity.getFieldValue("login") + " has logged out");
229 session.invalidate();
230 _sendLoginPage(aResponse, aRequest);
235 ServletModule servletModule = getServletModuleForName(moduleName);
236 ServletModuleDispatch.dispatch(servletModule, aRequest, aResponse);
238 sessionConnectTime = System.currentTimeMillis() - startTime;
239 logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
241 catch (Throwable e) {
242 Throwable cause = ExceptionFunctions.traceCauseException(e);
244 if (cause instanceof ServletModuleUserExc)
245 handleUserError(aRequest, aResponse, (ServletModuleUserExc) cause);
247 handleError(aRequest, aResponse, cause);
250 if (aRequest.getParameter("killsession")!=null)
251 aRequest.getSession().invalidate();
255 catch (Throwable t) {
258 throw new ServletException(t.toString());
263 * caching routine to get a module for a module name
265 * @param moduleName the module name
266 * @return the requested module
267 * @throws ServletModuleExc
270 private static ServletModule getServletModuleForName(String moduleName) throws ServletModuleExc {
272 if (!servletModuleInstanceHash.containsKey(moduleName)) {
273 // was not found in hash...
275 Class theServletModuleClass = null;
278 // first we try to get ServletModule from stern.che3.servlet
279 theServletModuleClass =
280 Class.forName("mircoders.servlet.ServletModule" + moduleName);
282 catch (ClassNotFoundException e) {
283 // on failure, we try to get it from lib-layer
284 theServletModuleClass =
285 Class.forName("mir.servlet.ServletModule" + moduleName);
288 Method m = theServletModuleClass.getMethod("getInstance", null);
289 ServletModule smod = (ServletModule) m.invoke(null, null);
291 // we put it into map for further reference
292 servletModuleInstanceHash.put(moduleName, smod);
296 catch (Exception e) {
297 throw new ServletModuleExc("*** error resolving classname for " + moduleName + " -- " + e.getMessage());
301 return (ServletModule) servletModuleInstanceHash.get(moduleName);
305 private void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse, ServletModuleUserExc anException) {
307 logger.info("user error: " + anException.getMessage());
309 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()});
311 MessageResources messages = MessageResources.getMessageResources("bundles.admin");
312 responseData.put("errorstring", messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters()));
313 responseData.put("date", new GregorianCalendar().getTime());
315 ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate"));
317 catch (Throwable e) {
318 logger.error("Error handling user error" + e.toString());
322 private void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse, Throwable anException) {
324 logger.error("error: " + anException);
326 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()});
328 responseData.put("errorstring", anException.toString());
329 responseData.put("date", new GregorianCalendar().getTime());
331 ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate"));
333 catch (Throwable e) {
334 logger.error("Error handling error: " + e.toString());
339 private void _sendLoginPage(HttpServletResponse aResponse, HttpServletRequest aRequest) {
340 String loginTemplate = configuration.getString("Mir.LoginTemplate");
343 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()});
345 responseData.put("defaultlanguage", getDefaultLanguage(aRequest));
346 responseData.put("languages", getLoginLanguages());
348 ServletHelper.generateResponse(aResponse.getWriter(), responseData, loginTemplate);
350 catch (Throwable e) {
351 handleError(aRequest, aResponse, e);
355 public String getServletInfo() {
356 return "Mir " + configuration.getString("Mir.Version");
359 private class SessionTracker implements HttpSessionBindingListener {
363 public SessionTracker(String aUserName, String anId) {
368 public void valueBound(HttpSessionBindingEvent anEvent) {
369 MirGlobal.registerLogin(name, id);
372 public void valueUnbound(HttpSessionBindingEvent anEvent) {
373 MirGlobal.registerLogout(name, id);