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.io.PrintWriter;
33 import java.lang.reflect.Method;
34 import java.util.GregorianCalendar;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Locale;
40 import java.util.Vector;
41 import javax.servlet.ServletException;
42 import javax.servlet.UnavailableException;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import javax.servlet.http.HttpSession;
47 import org.apache.struts.util.MessageResources;
48 import freemarker.template.SimpleHash;
49 import freemarker.template.SimpleList;
50 import freemarker.template.SimpleScalar;
51 import freemarker.template.TemplateModel;
53 import mir.config.MirPropertiesConfiguration;
54 import mir.entity.adapter.EntityIteratorAdapter;
55 import mir.generator.FreemarkerGenerator;
56 import mir.log.LoggerWrapper;
57 import mir.misc.HTMLTemplateProcessor;
58 import mir.misc.StringUtil;
59 import mir.servlet.AbstractServlet;
60 import mir.servlet.ServletModule;
61 import mir.servlet.ServletModuleDispatch;
62 import mir.servlet.ServletModuleExc;
63 import mir.servlet.ServletModuleUserExc;
64 import mir.util.CachingRewindableIterator;
65 import mir.util.ExceptionFunctions;
66 import mir.util.StringRoutines;
67 import mircoders.entity.EntityUsers;
68 import mircoders.global.MirGlobal;
69 import mircoders.module.ModuleMessage;
70 import mircoders.module.ModuleUsers;
71 import mircoders.servlet.ServletHelper;
72 import mircoders.servlet.ServletModuleFileEdit;
73 import mircoders.servlet.ServletModuleLocalizer;
74 import mircoders.storage.DatabaseUsers;
80 * Mir.java - main servlet, that dispatches to servletmodules
82 * @author $Author: zapata $
83 * @version $Id: Mir.java,v 1.49.2.2 2003/06/19 02:24:12 zapata Exp $
86 public class Mir extends AbstractServlet {
87 private static ModuleUsers usersModule = null;
88 private static ModuleMessage messageModule = null;
89 private final static Map servletModuleInstanceHash = new HashMap();
90 private static Locale fallbackLocale = null;
92 //I don't know about making this static cause it removes the
93 //possibility to change the config on the fly.. -mh
94 private static List loginLanguages = null;
96 protected TemplateModel getLoginLanguages() throws ServletException {
97 synchronized (Mir.class) {
99 if (loginLanguages == null) {
100 MessageResources messageResources =
101 MessageResources.getMessageResources("bundles.adminlocal");
102 MessageResources messageResources2 =
103 MessageResources.getMessageResources("bundles.admin");
106 StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";");
108 loginLanguages = new Vector();
110 Iterator i = languages.iterator();
112 while (i.hasNext()) {
113 String code = (String) i.next();
114 Locale locale = new Locale(code, "");
115 String name = messageResources.getMessage(locale, "languagename");
118 name = messageResources2.getMessage(locale, "languagename");
125 Map record = new HashMap();
126 record.put("name", name);
127 record.put("code", code);
128 loginLanguages.add(record);
132 return FreemarkerGenerator.makeAdapter(loginLanguages);
134 catch (Throwable t) {
135 throw new ServletException(t.getMessage());
140 protected String getDefaultLanguage(HttpServletRequest aRequest) {
141 String defaultlanguage =
142 MirGlobal.config().getString("Mir.Login.DefaultLanguage", "");
144 if (defaultlanguage.length() == 0) {
145 Locale locale = aRequest.getLocale();
146 defaultlanguage = locale.getLanguage();
149 return defaultlanguage;
152 protected synchronized Locale getFallbackLocale() throws ServletException {
154 if (fallbackLocale == null) {
155 fallbackLocale = new Locale(MirPropertiesConfiguration.instance().getString("Mir.Admin.FallbackLanguage", "en"), "");
158 catch (Throwable t) {
159 throw new ServletException(t.getMessage());
162 return fallbackLocale;
165 public void process(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException, UnavailableException {
167 long startTime = System.currentTimeMillis();
168 long sessionConnectTime = 0;
169 EntityUsers userEntity;
172 configuration.addProperty("ServletName", getServletName());
174 session = aRequest.getSession(true);
175 userEntity = ServletHelper.getUser(aRequest);
177 setNoCaching(aResponse);
179 Locale locale = new Locale(getDefaultLanguage(aRequest), "");
181 aResponse.setContentType("text/html; charset=" +
182 configuration.getString("Mir.DefaultHTMLCharset", "UTF-8"));
184 String moduleName = aRequest.getParameter("module");
185 checkLanguage(session, aRequest);
188 if ( ( (moduleName != null) && moduleName.equals("login")) || (userEntity == null)) {
189 String user = aRequest.getParameter("login");
190 String passwd = aRequest.getParameter("password");
191 logger.debug("--login: evaluating for user: " + user);
192 userEntity = allowedUser(user, passwd);
194 if (userEntity == null) {
195 // login failed: redirecting to login
196 logger.warn("--login: failed!");
197 _sendLoginPage(aResponse, aRequest, aResponse.getWriter());
201 else if ( (moduleName != null) && moduleName.equals("login")) {
203 logger.info("--login: successful! setting uid: " + userEntity.getId());
204 ServletHelper.setUser(aRequest, userEntity);
206 logger.debug("--login: trying to retrieve login.target");
207 String target = (String) session.getAttribute("login.target");
209 if (target != null) {
210 logger.debug("Redirect: " + target);
212 aResponse.sendRedirect(
213 MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?" + target);
217 logger.debug("--login: no target - redirecting to default");
218 _sendStartPage(aResponse, aRequest, aResponse.getWriter(), userEntity);
223 // if login succesful
227 if ( (moduleName != null) && moduleName.equals("logout")) {
228 logger.info("--logout");
229 session.invalidate();
231 _sendLoginPage(aResponse, aRequest, aResponse.getWriter());
237 if (userEntity == null) {
238 // redirect to loginpage
239 String redirectString = aRequest.getRequestURI();
240 String queryString = aRequest.getQueryString();
242 if ( (queryString != null) && queryString.length() != 0) {
243 redirectString += ("?" + aRequest.getQueryString());
244 session.setAttribute("login.target", redirectString);
247 _sendLoginPage(aResponse, aRequest, aResponse.getWriter());
252 // If no module is specified goto standard startpage
253 if ( (moduleName == null) || moduleName.equals("")) {
254 _sendStartPage(aResponse, aRequest, aResponse.getWriter(), userEntity);
260 // get servletmodule by parameter and continue with dispacher
261 ServletModule smod = getServletModuleForName(moduleName);
262 ServletModuleDispatch.dispatch(smod, aRequest, aResponse);
264 catch (Throwable e) {
265 Throwable cause = ExceptionFunctions.traceCauseException(e);
267 if (cause instanceof ServletModuleUserExc)
268 handleUserError(aRequest, aResponse, aResponse.getWriter(), (ServletModuleUserExc) cause);
270 handleError(aRequest, aResponse, aResponse.getWriter(), cause);
275 sessionConnectTime = System.currentTimeMillis() - startTime;
276 logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
278 catch (Throwable t) {
279 throw new ServletException(t.toString());
284 * Private method getServletModuleForName returns ServletModule
288 * @return ServletModule
291 private static ServletModule getServletModuleForName(String moduleName) throws ServletModuleExc {
293 if (!servletModuleInstanceHash.containsKey(moduleName)) {
294 // was not found in hash...
296 Class theServletModuleClass = null;
299 // first we try to get ServletModule from stern.che3.servlet
300 theServletModuleClass =
301 Class.forName("mircoders.servlet.ServletModule" + moduleName);
302 } catch (ClassNotFoundException e) {
303 // on failure, we try to get it from lib-layer
304 theServletModuleClass =
305 Class.forName("mir.servlet.ServletModule" + moduleName);
308 Method m = theServletModuleClass.getMethod("getInstance", null);
309 ServletModule smod = (ServletModule) m.invoke(null, null);
311 // we put it into map for further reference
312 servletModuleInstanceHash.put(moduleName, smod);
316 catch (Exception e) {
317 throw new ServletModuleExc("*** error resolving classname for " + moduleName + " -- " + e.getMessage());
321 return (ServletModule) servletModuleInstanceHash.get(moduleName);
325 private void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse,
326 PrintWriter out, ServletModuleUserExc anException) {
328 logger.info("user error: " + anException.getMessage());
329 SimpleHash modelRoot = new SimpleHash();
330 MessageResources messages = MessageResources.getMessageResources("bundles.admin");
331 modelRoot.put("errorstring",
333 messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())
335 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
336 HTMLTemplateProcessor.process(
338 MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate"),
346 catch (Throwable e) {
347 logger.error("Error handling user error" + e.toString());
352 private void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse,PrintWriter out, Throwable anException) {
355 logger.error("error: " + anException);
356 SimpleHash modelRoot = new SimpleHash();
357 modelRoot.put("errorstring", new SimpleScalar(anException.getMessage()));
358 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(
359 new GregorianCalendar())));
360 HTMLTemplateProcessor.process(
361 aResponse,MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate"),
362 modelRoot,null,out, getLocale(aRequest), getFallbackLocale());
365 catch (Throwable e) {
366 logger.error("Error handling error: " + e.toString());
371 * evaluate login for user / password
373 protected EntityUsers allowedUser(String user, String password) {
375 if (usersModule == null) {
376 usersModule = new ModuleUsers(DatabaseUsers.getInstance());
379 return usersModule.getUserForLogin(user, password);
381 catch (Exception e) {
382 logger.debug(e.getMessage());
383 e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
390 private void _sendLoginPage(HttpServletResponse aResponse, HttpServletRequest aRequest,
392 String loginTemplate = configuration.getString("Mir.LoginTemplate");
393 String sessionUrl = aResponse.encodeURL("");
396 SimpleHash mergeData = new SimpleHash();
397 SimpleList languages = new SimpleList();
399 mergeData.put("session", sessionUrl);
401 mergeData.put("defaultlanguage", getDefaultLanguage(aRequest));
402 mergeData.put("languages", getLoginLanguages());
404 HTMLTemplateProcessor.process(aResponse, loginTemplate, mergeData, null, out, getLocale(aRequest), getFallbackLocale());
406 catch (Throwable e) {
407 handleError(aRequest, aResponse, out, e);
411 private void _sendStartPage(HttpServletResponse aResponse, HttpServletRequest aRequest,
412 PrintWriter out, EntityUsers userEntity) {
413 String startTemplate = configuration.getString("Mir.StartTemplate");
414 String sessionUrl = aResponse.encodeURL("");
417 Map mergeData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}, "bundles.admin", "bundles.adminlocal");
418 mergeData.put("messages",
419 new CachingRewindableIterator(
420 new EntityIteratorAdapter( "", "webdb_create desc", 10,
421 MirGlobal.localizer().dataModel().adapterModel(), "internalMessage", 10, 0)));
423 mergeData.put("fileeditentries", ((ServletModuleFileEdit) ServletModuleFileEdit.getInstance()).getEntries());
424 mergeData.put("administeroperations", ((ServletModuleLocalizer) ServletModuleLocalizer.getInstance()).getAdministerOperations());
426 mergeData.put("searchvalue", null);
427 mergeData.put("searchfield", null);
428 mergeData.put("searchispublished", null);
429 mergeData.put("searcharticletype", null);
430 mergeData.put("searchorder", null);
431 mergeData.put("selectarticleurl", null);
433 ServletHelper.generateResponse(out, mergeData, startTemplate);
435 catch (Exception e) {
436 e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
437 handleError(aRequest, aResponse, out, e);
441 public String getServletInfo() {
442 return "Mir " + configuration.getString("Mir.Version");