2 * Copyright (C) 2001, 2002 The Mir-coders group
\r
4 * This file is part of Mir.
\r
6 * Mir is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Mir is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with Mir; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 * In addition, as a special exception, The Mir-coders gives permission to link
\r
21 * the code of this program with any library licensed under the Apache Software License,
\r
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
\r
23 * (or with modified versions of the above that use the same license as the above),
\r
24 * and distribute linked combinations including the two. You must obey the
\r
25 * GNU General Public License in all respects for all of the code used other than
\r
26 * the above mentioned libraries. If you modify this file, you may extend this
\r
27 * exception to your version of the file, but you are not obligated to do so.
\r
28 * If you do not wish to do so, delete this exception statement from your version.
\r
31 import java.io.IOException;
\r
32 import java.io.PrintWriter;
\r
33 import java.lang.reflect.Method;
\r
34 import java.util.GregorianCalendar;
\r
35 import java.util.HashMap;
\r
36 import java.util.Iterator;
\r
37 import java.util.List;
\r
38 import java.util.Locale;
\r
39 import java.util.Map;
\r
40 import java.util.Vector;
\r
41 import javax.servlet.ServletConfig;
\r
42 import javax.servlet.ServletException;
\r
43 import javax.servlet.UnavailableException;
\r
44 import javax.servlet.http.HttpServletRequest;
\r
45 import javax.servlet.http.HttpServletResponse;
\r
46 import javax.servlet.http.HttpSession;
\r
48 import org.apache.struts.util.MessageResources;
\r
49 import freemarker.template.SimpleHash;
\r
50 import freemarker.template.SimpleList;
\r
51 import freemarker.template.SimpleScalar;
\r
52 import freemarker.template.TemplateModel;
\r
53 import mir.config.MirPropertiesConfiguration;
\r
54 import mir.entity.adapter.EntityIteratorAdapter;
\r
55 import mir.generator.FreemarkerGenerator;
\r
56 import mir.log.LoggerWrapper;
\r
57 import mir.misc.HTMLTemplateProcessor;
\r
58 import mir.misc.StringUtil;
\r
59 import mir.servlet.AbstractServlet;
\r
60 import mir.servlet.ServletModule;
\r
61 import mir.servlet.ServletModuleDispatch;
\r
62 import mir.servlet.ServletModuleExc;
\r
63 import mir.servlet.ServletModuleUserExc;
\r
64 import mir.util.CachingRewindableIterator;
\r
65 import mir.util.ExceptionFunctions;
\r
66 import mir.util.StringRoutines;
\r
67 import mircoders.entity.EntityUsers;
\r
68 import mircoders.global.MirGlobal;
\r
69 import mircoders.module.ModuleMessage;
\r
70 import mircoders.module.ModuleUsers;
\r
71 import mircoders.servlet.ServletHelper;
\r
72 import mircoders.servlet.ServletModuleFileEdit;
\r
73 import mircoders.servlet.ServletModuleLocalizer;
\r
74 import mircoders.storage.DatabaseUsers;
\r
80 * Mir.java - main servlet, that dispatches to servletmodules
\r
82 * @author $Author: zapata $
\r
83 * @version $Id: Mir.java,v 1.49.2.5 2003/07/20 05:49:47 zapata Exp $
\r
86 public class Mir extends AbstractServlet {
\r
87 private static ModuleUsers usersModule = null;
\r
88 private static ModuleMessage messageModule = null;
\r
89 private final static Map servletModuleInstanceHash = new HashMap();
\r
90 private static Locale fallbackLocale = null;
\r
92 private static List loginLanguages = null;
\r
94 protected TemplateModel getLoginLanguages() throws ServletException {
\r
95 synchronized (Mir.class) {
\r
97 if (loginLanguages == null) {
\r
98 MessageResources messageResources =
\r
99 MessageResources.getMessageResources("bundles.adminlocal");
\r
100 MessageResources messageResources2 =
\r
101 MessageResources.getMessageResources("bundles.admin");
\r
104 StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";");
\r
106 loginLanguages = new Vector();
\r
108 Iterator i = languages.iterator();
\r
110 while (i.hasNext()) {
\r
111 String code = (String) i.next();
\r
112 Locale locale = new Locale(code, "");
\r
113 String name = messageResources.getMessage(locale, "languagename");
\r
115 if (name == null) {
\r
116 name = messageResources2.getMessage(locale, "languagename");
\r
119 if (name == null) {
\r
123 Map record = new HashMap();
\r
124 record.put("name", name);
\r
125 record.put("code", code);
\r
126 loginLanguages.add(record);
\r
130 return FreemarkerGenerator.makeAdapter(loginLanguages);
\r
132 catch (Throwable t) {
\r
133 throw new ServletException(t.getMessage());
\r
138 public void init(ServletConfig config) throws ServletException {
\r
139 super.init(config);
\r
141 usersModule = new ModuleUsers(DatabaseUsers.getInstance());
\r
144 protected String getDefaultLanguage(HttpServletRequest aRequest) {
\r
145 String defaultlanguage =
\r
146 MirGlobal.config().getString("Mir.Login.DefaultLanguage", "");
\r
148 if (defaultlanguage.length() == 0) {
\r
149 Locale locale = aRequest.getLocale();
\r
150 defaultlanguage = locale.getLanguage();
\r
153 return defaultlanguage;
\r
156 protected synchronized Locale getFallbackLocale() throws ServletException {
\r
158 if (fallbackLocale == null) {
\r
159 fallbackLocale = new Locale(MirPropertiesConfiguration.instance().getString("Mir.Admin.FallbackLanguage", "en"), "");
\r
162 catch (Throwable t) {
\r
163 throw new ServletException(t.getMessage());
\r
166 return fallbackLocale;
\r
169 public EntityUsers checkCredentials(HttpServletRequest aRequest) throws ServletException {
\r
171 EntityUsers user = ServletHelper.getUser(aRequest);
\r
173 String username = aRequest.getParameter("login");
\r
174 String password = aRequest.getParameter("password");
\r
176 if (username != null && password != null) {
\r
177 user = usersModule.getUserForLogin(username, password);
\r
180 ServletHelper.setUser(aRequest, user);
\r
185 catch (Throwable t) {
\r
186 t.printStackTrace();
\r
188 throw new ServletException(t.toString());
\r
192 public void process(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException, UnavailableException {
\r
194 long startTime = System.currentTimeMillis();
\r
195 long sessionConnectTime = 0;
\r
197 HttpSession session = aRequest.getSession(true);
\r
198 setNoCaching(aResponse);
\r
199 Locale locale = new Locale(getDefaultLanguage(aRequest), "");
\r
200 aResponse.setContentType("text/html; charset=" +
\r
202 getString("Mir.DefaultHTMLCharset", "UTF-8"));
\r
204 EntityUsers userEntity = checkCredentials(aRequest);
\r
206 if (userEntity == null) {
\r
207 String queryString = aRequest.getQueryString();
\r
209 if ( (queryString != null) && (queryString.length() != 0) && session.getAttribute("login.target") == null &&
\r
210 (aRequest.getParameter("module")==null ||
\r
211 (!aRequest.getParameter("module").equals("login") && !aRequest.getParameter("module").equals("logout")))) {
\r
212 session.setAttribute("login.target", queryString);
\r
215 _sendLoginPage(aResponse, aRequest, aResponse.getWriter());
\r
218 String moduleName = aRequest.getParameter("module");
\r
219 checkLanguage(session, aRequest);
\r
221 if ( ( (moduleName == null) || moduleName.equals(""))) {
\r
222 _sendStartPage(aResponse, aRequest, aResponse.getWriter(),
\r
225 else if (moduleName.equals("login")) {
\r
226 String target = (String) session.getAttribute("login.target");
\r
228 if (target != null) {
\r
229 ServletHelper.redirect(aResponse, target);
\r
232 _sendStartPage(aResponse, aRequest, aResponse.getWriter(), userEntity);
\r
235 else if (moduleName.equals("logout")) {
\r
236 logger.info(userEntity.get("login") + " has logged out");
\r
237 session.invalidate();
\r
238 _sendLoginPage(aResponse, aRequest, aResponse.getWriter());
\r
243 ServletModule servletModule = getServletModuleForName(moduleName);
\r
244 ServletModuleDispatch.dispatch(servletModule, aRequest, aResponse);
\r
246 sessionConnectTime = System.currentTimeMillis() - startTime;
\r
247 logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
\r
249 catch (Throwable e) {
\r
250 Throwable cause = ExceptionFunctions.traceCauseException(e);
\r
252 if (cause instanceof ServletModuleUserExc)
\r
253 handleUserError(aRequest, aResponse, aResponse.getWriter(),
\r
254 (ServletModuleUserExc) cause);
\r
256 handleError(aRequest, aResponse, aResponse.getWriter(), cause);
\r
259 if (aRequest.getParameter("killsession")!=null)
\r
260 aRequest.getSession().invalidate();
\r
264 catch (Throwable t) {
\r
265 t.printStackTrace();
\r
267 throw new ServletException(t.toString());
\r
272 * Private method getServletModuleForName returns ServletModule
\r
275 * @param moduleName
\r
276 * @return ServletModule
\r
279 private static ServletModule getServletModuleForName(String moduleName) throws ServletModuleExc {
\r
280 // Instance in Map ?
\r
281 if (!servletModuleInstanceHash.containsKey(moduleName)) {
\r
282 // was not found in hash...
\r
284 Class theServletModuleClass = null;
\r
287 // first we try to get ServletModule from stern.che3.servlet
\r
288 theServletModuleClass =
\r
289 Class.forName("mircoders.servlet.ServletModule" + moduleName);
\r
291 catch (ClassNotFoundException e) {
\r
292 // on failure, we try to get it from lib-layer
\r
293 theServletModuleClass =
\r
294 Class.forName("mir.servlet.ServletModule" + moduleName);
\r
297 Method m = theServletModuleClass.getMethod("getInstance", null);
\r
298 ServletModule smod = (ServletModule) m.invoke(null, null);
\r
300 // we put it into map for further reference
\r
301 servletModuleInstanceHash.put(moduleName, smod);
\r
305 catch (Exception e) {
\r
306 throw new ServletModuleExc("*** error resolving classname for " + moduleName + " -- " + e.getMessage());
\r
310 return (ServletModule) servletModuleInstanceHash.get(moduleName);
\r
314 private void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse,
\r
315 PrintWriter out, ServletModuleUserExc anException) {
\r
317 logger.info("user error: " + anException.getMessage());
\r
318 SimpleHash modelRoot = new SimpleHash();
\r
319 MessageResources messages = MessageResources.getMessageResources("bundles.admin");
\r
320 modelRoot.put("errorstring",
\r
322 messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())
\r
324 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
\r
325 HTMLTemplateProcessor.process(
\r
327 MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate"),
\r
331 getLocale(aRequest),
\r
335 catch (Throwable e) {
\r
336 logger.error("Error handling user error" + e.toString());
\r
340 private void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse,PrintWriter out, Throwable anException) {
\r
342 logger.error("error: " + anException);
\r
343 SimpleHash modelRoot = new SimpleHash();
\r
344 modelRoot.put("errorstring", new SimpleScalar(anException.getMessage()));
\r
345 modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(
\r
346 new GregorianCalendar())));
\r
347 HTMLTemplateProcessor.process(
\r
348 aResponse,MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate"),
\r
349 modelRoot,null,out, getLocale(aRequest), getFallbackLocale());
\r
352 catch (Throwable e) {
\r
353 logger.error("Error handling error: " + e.toString());
\r
357 // Redirect-methods
\r
358 private void _sendLoginPage(HttpServletResponse aResponse, HttpServletRequest aRequest,
\r
360 String loginTemplate = configuration.getString("Mir.LoginTemplate");
\r
361 String sessionUrl = aResponse.encodeURL("");
\r
364 SimpleHash mergeData = new SimpleHash();
\r
365 SimpleList languages = new SimpleList();
\r
367 mergeData.put("session", sessionUrl);
\r
369 mergeData.put("defaultlanguage", getDefaultLanguage(aRequest));
\r
370 mergeData.put("languages", getLoginLanguages());
\r
372 HTMLTemplateProcessor.process(aResponse, loginTemplate, mergeData, null, out, getLocale(aRequest), getFallbackLocale());
\r
374 catch (Throwable e) {
\r
375 handleError(aRequest, aResponse, out, e);
\r
379 private void _sendStartPage(HttpServletResponse aResponse, HttpServletRequest aRequest,
\r
380 PrintWriter out, EntityUsers userEntity) {
\r
381 String startTemplate = configuration.getString("Mir.StartTemplate");
\r
382 String sessionUrl = aResponse.encodeURL("");
\r
385 Map mergeData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}, "bundles.admin", "bundles.adminlocal");
\r
386 mergeData.put("messages",
\r
387 new CachingRewindableIterator(
\r
388 new EntityIteratorAdapter( "", "webdb_create desc", 10,
\r
389 MirGlobal.localizer().dataModel().adapterModel(), "internalMessage", 10, 0)));
\r
391 mergeData.put("fileeditentries", ((ServletModuleFileEdit) ServletModuleFileEdit.getInstance()).getEntries());
\r
392 mergeData.put("administeroperations", ((ServletModuleLocalizer) ServletModuleLocalizer.getInstance()).getAdministerOperations());
\r
394 mergeData.put("searchvalue", null);
\r
395 mergeData.put("searchfield", null);
\r
396 mergeData.put("searchispublished", null);
\r
397 mergeData.put("searcharticletype", null);
\r
398 mergeData.put("searchorder", null);
\r
399 mergeData.put("selectarticleurl", null);
\r
401 ServletHelper.generateResponse(out, mergeData, startTemplate);
\r
403 catch (Exception e) {
\r
404 e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
\r
405 handleError(aRequest, aResponse, out, e);
\r
409 public String getServletInfo() {
\r
410 return "Mir " + configuration.getString("Mir.Version");
\r