X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=source%2FMir.java;h=91be32de1f460388b90c869d812d828da6df6589;hb=63e0ee1fb8038eb6d8f0190cf38c3b3ab2727216;hp=d4fca0c46d2c693cecdf6f0e41f53be15213fc5e;hpb=86b6f499b413c722acc895346ac5186405b0c44c;p=mir.git diff --git a/source/Mir.java b/source/Mir.java index d4fca0c4..91be32de 100755 --- a/source/Mir.java +++ b/source/Mir.java @@ -1,237 +1,385 @@ -import java.io.*; -import java.util.*; -import java.net.*; -import java.lang.reflect.*; -import javax.servlet.*; -import javax.servlet.http.*; -import java.sql.*; - -import freemarker.template.*; +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ -import mir.misc.*; +import mir.bundle.Bundle; +import mir.config.MirPropertiesConfiguration; import mir.servlet.*; +import mir.util.ExceptionFunctions; +import mir.util.StringRoutines; +import mir.log.LoggerWrapper; +import mircoders.entity.EntityUsers; +import mircoders.global.MirGlobal; +import mircoders.module.ModuleUsers; +import mircoders.servlet.ServletHelper; -import mircoders.servlet.*; -import mircoders.module.*; -import mircoders.entity.*; -import mircoders.storage.*; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.*; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.util.*; + +import multex.Failure; /** - * Mir.java - main servlet, that dispatches to servletmodules - * - * @author RK 1999-2001 - * + * Mir.java - main servlet, that dispatches to servletmodules */ +public class Mir extends AbstractServlet { + private static ModuleUsers usersModule = null; + private final static Map servletModuleInstanceHash = new HashMap(); + private static Locale fallbackLocale = null; + private static List loginLanguages = null; -public class Mir extends AbstractServlet -{ + private List getLoginLanguages() throws Failure { + synchronized (Mir.class) { + try { + if (loginLanguages == null) { + List languages = + StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";"); - private static ModuleUsers usersModule=null; - private static ModuleMessage messageModule=null; - private static boolean confed=false; - public HttpSession session; + loginLanguages = new ArrayList(); + Iterator i = languages.iterator(); - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - doPost(req,res); - } + while (i.hasNext()) { + String code = (String) i.next(); - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - - long startTime = (new java.util.Date()).getTime(); - Class theServletModule; - ServletModule smod; - long sessionConnectTime=0; - String http=""; - - // get the configration - if (!confed){ - confed = getConfig(req); - } - - session = req.getSession(true); - - if (req.getServerPort() == 443) http="https"; else http="http"; - res.setContentType("text/html"); - String moduleName = req.getParameter("module"); - - if(session.getAttribute("Language")==null){ - setLanguage(session,getAcceptLanguage(req)); - } - - // Authentifizierung - if (moduleName!=null && moduleName.equals("login")) { - String user=req.getParameter("login"); - String passwd= req.getParameter("password"); - String lang = req.getParameter("lang"); - theLog.printDebugInfo("--login: evaluating for user: "+user); - EntityUsers userEntity = allowedUser(user,passwd); - if (userEntity==null) { - // login failed: redirecting to login - theLog.printWarning("--login: failed!"); - _sendLoginPage(res,req,res.getWriter()); - return; - } else { - // login successful - - //if accept-language!=selected language change language - if(!getLanguage(req,session).equals(lang)){ - setLanguage(session,lang); - } + Bundle bundle = + MirGlobal.getBundleFactory().getBundle("etc/bundles/adminlocal", new String[] { code }); + Bundle defaultBundle = + MirGlobal.getBundleFactory().getBundle("bundles/admin", new String[] { code }); + + String name = bundle.getValue("languagename", Collections.EMPTY_LIST); - theLog.printInfo("--login: successful! setting uid: " + userEntity.getId()); - session.setAttribute("login.uid", userEntity); - theLog.printDebugInfo("--login: trying to retrieve login.target"); - String target = (String)session.getAttribute("login.target"); - - if (target != null) { - theLog.printDebugInfo("Redirect: "+target); - int serverPort = req.getServerPort(); - String redirect = ""; - String redirectString =""; - - - if(serverPort==80){ - redirect=res.encodeURL(http + "://" + req.getServerName() + target); - redirectString = "going Mir"; - } else { - redirect=res.encodeURL(http + "://" + req.getServerName() + ":" +req.getServerPort() + target); - redirectString = "going Mir"; + if (name == null) { + name = defaultBundle.getValue("languagename", Collections.EMPTY_LIST); + } + + if (name == null) { + name = code; + } + + Map record = new HashMap(); + record.put("name", name); + record.put("code", code); + loginLanguages.add(record); } - res.getWriter().println(redirectString); - - - //res.sendRedirect(redirect); - - } else { - // redirecting to default target - theLog.printDebugInfo("--login: no target - redirecting to default"); - _sendStartPage(res,req,res.getWriter(),userEntity); } - return; - } // if login succesful - } // if login - if (moduleName!=null && moduleName.equals("logout")) { - theLog.printDebugInfo("--logout"); - session.invalidate(); - _sendLoginPage(res,req,res.getWriter()); - return; + return loginLanguages; + } + catch (Throwable t) { + throw new Failure("Error while retrieving the available login languages", t); + } } + } - // Check if authed! - EntityUsers userEntity = (EntityUsers)session.getAttribute("login.uid"); - if (userEntity == null) { - // redirect to loginpage - String redirectString = req.getRequestURI(); - if (req.getQueryString()!=null) redirectString += "?" + req.getQueryString(); - theLog.printDebugInfo("STORING: " + redirectString); - session.setAttribute("login.target", redirectString); - _sendLoginPage(res,req,res.getWriter()); - return; + public void init(ServletConfig config) throws ServletException { + super.init(config); + + usersModule = new ModuleUsers(); + } + + protected String getDefaultLanguage(HttpServletRequest aRequest) { + String defaultlanguage = + MirGlobal.config().getString("Mir.Login.DefaultLanguage", ""); + + if (defaultlanguage.length() == 0) { + Locale locale = aRequest.getLocale(); + defaultlanguage = locale.getLanguage(); } - // Bei blossem Serveltaufruf redirect auf Standardstarttemplate - if (moduleName == null || moduleName.equals("")) { - theLog.printDebugInfo("no module: redirect to standardpage"); - _sendStartPage(res,req, res.getWriter(),userEntity); - return; + return defaultlanguage; + } + + protected synchronized Locale getFallbackLocale() throws ServletException { + try { + if (fallbackLocale == null) { + fallbackLocale = new Locale(MirPropertiesConfiguration.instance().getString("Mir.Admin.FallbackLanguage", "en"), ""); + } + } + catch (Throwable t) { + throw new ServletException(t.getMessage()); } - //From now on normal Dispatching... + return fallbackLocale; + } + + public EntityUsers checkCredentials(HttpServletRequest aRequest) throws ServletException { try { - try { - theServletModule = Class.forName("mircoders.servlet.ServletModule" + moduleName); - } catch (ClassNotFoundException e) { - // searching Servlet webdb.servlet-classes - theServletModule = Class.forName("mir.servlet.ServletModule" + moduleName); + EntityUsers user = ServletHelper.getUser(aRequest); + + String username = aRequest.getParameter("login"); + String password = aRequest.getParameter("password"); + + if (username != null && password != null) { + user = usersModule.getUserForLogin(username, password); + + if (user!=null) { + ServletHelper.setUser(aRequest, user); + usersModule.recordLogin(user); + aRequest.getSession().setAttribute("sessiontracker", new SessionTracker(username, user.getId())); + } } - //Instanciate the ServletModule - Method m = theServletModule.getMethod("getInstance",null); - smod = (ServletModule)m.invoke(null,null); - ServletModuleDispatch.dispatch(smod,req,res); - } - catch (NoSuchMethodException e) { handleError( res,res.getWriter(), "ServletModule" + moduleName + " getInstance() nicht gefunden."); } - catch (InvocationTargetException e) { handleError( res,res.getWriter(), "ServletModule" + moduleName + " target nicht gefunden."); } - catch (ClassNotFoundException e) { handleError(res, res.getWriter(), "ServletModule" + moduleName + " nicht gefunden."); } - catch (IllegalArgumentException e) { handleError( res,res.getWriter(), "ServletModule" + moduleName + " nicht gefunden."); } - catch (ServletModuleException e){ handleError(res,res.getWriter(), "ServletException in Module ServletModule" + moduleName + " -- " + e.toString()); } - catch (IllegalAccessException e){ - handleError(res,res.getWriter(), "Kein Zugriff auf Klasse ServletModule" + moduleName + " -- " + e.toString()); } - - // timing... - sessionConnectTime = new java.util.Date().getTime() - startTime; - theLog.printInfo("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms"); + + return user; + } + catch (Throwable t) { + t.printStackTrace(); + + throw new ServletException(t.toString()); + } } - private void handleError(HttpServletResponse res, PrintWriter out, String errorString) { + public void process(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException, UnavailableException { try { - theLog.printError(errorString); - SimpleHash modelRoot = new SimpleHash(); - modelRoot.put("errorstring", new SimpleScalar(errorString)); - modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar()))); - HTMLTemplateProcessor.process(res,MirConfig.getProp("Mir.ErrorTemplate"),modelRoot,out); - out.close(); + long startTime = System.currentTimeMillis(); + long sessionConnectTime = 0; + + HttpSession session = aRequest.getSession(true); + setNoCaching(aResponse); + aResponse.setContentType("text/html; charset=" + + configuration. + getString("Mir.DefaultHTMLCharset", "UTF-8")); + + EntityUsers userEntity = checkCredentials(aRequest); + + if (userEntity == null) { + String queryString = aRequest.getQueryString(); + + if ( (queryString != null) && (queryString.length() != 0) && session.getAttribute("login.target") == null && + (aRequest.getParameter("module")==null || + (!aRequest.getParameter("module").equals("login") && !aRequest.getParameter("module").equals("logout")))) { + session.setAttribute("login.target", queryString); + } + + _sendLoginPage(aResponse, aRequest); + } + else { + String moduleName = aRequest.getParameter("module"); + checkLanguage(session, aRequest); + + if ( ( (moduleName == null) || moduleName.equals(""))) { + moduleName="Admin"; + } + + + if (moduleName.equals("login")) { + String target = (String) session.getAttribute("login.target"); + + if (target != null) { + ServletHelper.redirect(aResponse, target); + } + else { + ServletHelper.redirect(aResponse, ""); + } + } + else if (moduleName.equals("logout")) { + logger.info(userEntity.getFieldValue("login") + " has logged out"); + session.invalidate(); + _sendLoginPage(aResponse, aRequest); + return; + } + else { + try { + ServletModule servletModule = getServletModuleForName(moduleName); + ServletModuleDispatch.dispatch(servletModule, aRequest, aResponse); + + sessionConnectTime = System.currentTimeMillis() - startTime; + logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms"); + } + catch (Throwable e) { + Throwable cause = ExceptionFunctions.traceCauseException(e); + + if (cause instanceof ServletModuleUserExc) + handleUserError(aRequest, aResponse, (ServletModuleUserExc) cause); + else + handleError(aRequest, aResponse, cause); + } + + if (aRequest.getParameter("killsession")!=null) + aRequest.getSession().invalidate(); + } + } } - catch (Exception e) { - System.err.println("Fehler in ErrorTemplate"); + catch (Throwable t) { + t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE)); + + throw new ServletException(t.toString()); } } /** - * evaluate login for user / password + * caching routine to get a module for a module name + * + * @param moduleName the module name + * @return the requested module + * @throws ServletModuleExc */ - protected EntityUsers allowedUser(String user, String password) { + + private static ServletModule getServletModuleForName(String moduleName) throws ServletModuleExc { + // Instance in Map ? + if (!servletModuleInstanceHash.containsKey(moduleName)) { + // was not found in hash... + try { + Class theServletModuleClass = null; + + try { + // first we try to get ServletModule from stern.che3.servlet + theServletModuleClass = + Class.forName("mircoders.servlet.ServletModule" + moduleName); + } + catch (ClassNotFoundException e) { + // on failure, we try to get it from lib-layer + theServletModuleClass = + Class.forName("mir.servlet.ServletModule" + moduleName); + } + + Method m = theServletModuleClass.getMethod("getInstance", null); + ServletModule smod = (ServletModule) m.invoke(null, null); + + // we put it into map for further reference + servletModuleInstanceHash.put(moduleName, smod); + + return smod; + } + catch (Exception e) { + throw new ServletModuleExc("*** error resolving classname for " + moduleName + " -- " + e.getMessage()); + } + } + else { + return (ServletModule) servletModuleInstanceHash.get(moduleName); + } + } + + private void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse, ServletModuleUserExc anException) { try { - if (usersModule == null) usersModule = new ModuleUsers(DatabaseUsers.getInstance()); - return usersModule.getUserForLogin(user, password); + logger.info("user error: " + anException.getMessage()); + + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); + + Bundle bundle = + MirGlobal.getBundleFactory().getBundle("etc/bundles/adminlocal", new + String[] { getLocale(aRequest).getLanguage() }); + Bundle defaultBundle = + MirGlobal.getBundleFactory().getBundle("bundles/admin", new + String[] { getLocale(aRequest).getLanguage() }); + String message = + bundle.getValue(anException.getMessage(), Arrays.asList(anException.getParameters())); + + if (message==null) { + message = + defaultBundle.getValue(anException.getMessage(), Arrays.asList(anException.getParameters())); + } + + responseData.put("errorstring", message); + responseData.put("date", new GregorianCalendar().getTime()); + + ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate")); + } + catch (Throwable e) { + logger.error("Error handling user error" + e.toString()); } - catch(Exception e) { theLog.printDebugInfo(e.toString()); return null; } } - // Redirect-methods - private void _sendLoginPage(HttpServletResponse res,HttpServletRequest req, PrintWriter out) { - String loginTemplate = "login.template"; - String sessionUrl=res.encodeURL(""); - //session = req.getSession(true); + private void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse, Throwable anException) { try { - theLog.printDebugInfo("login: "+lang); - if(lang==null){ - lang=getAcceptLanguage(req); + logger.error("error: " + anException); + + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); + + responseData.put("errorstring", anException.toString()); + responseData.put("date", new GregorianCalendar().getTime()); + + ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate")); + } + catch (Throwable e) { + logger.error("Error handling error: " + e.toString()); + + try { + Throwable rootException = ExceptionFunctions.traceCauseException(anException); + + PrintWriter writer = aResponse.getWriter(); + writer.println("FATAL Error"); + writer.println("

" + rootException.toString()+"

"); + writer.println(""); + rootException.printStackTrace(writer); + writer.println(""); + writer.println(""); + writer.close(); + } + catch (Throwable t) { + } - SimpleHash mergeData = new SimpleHash(); - mergeData.put("session",sessionUrl); - HTMLTemplateProcessor.process(res,lang+"/"+loginTemplate, mergeData, out); - } catch(HTMLParseException e) { - handleError(res, out, "fehler in logintemplate."); } } - private void _sendStartPage(HttpServletResponse res, HttpServletRequest req,PrintWriter out, EntityUsers userEntity) { - String startTemplate = "start_admin.template"; - String sessionUrl=res.encodeURL(""); + // Redirect-methods + private void _sendLoginPage(HttpServletResponse aResponse, HttpServletRequest aRequest) { + String loginTemplate = configuration.getString("Mir.LoginTemplate"); + try { - // merge with logged in user and messages - SimpleHash mergeData = new SimpleHash(); - mergeData.put("session",sessionUrl); - mergeData.put("login_user", HTMLTemplateProcessor.makeSimpleHash(userEntity)); - if (messageModule == null) messageModule = new ModuleMessage(DatabaseMessages.getInstance()); - mergeData.put("messages", HTMLTemplateProcessor.makeSimpleList(messageModule.getByWhereClause(null, "webdb_create desc",0,10))); - HTMLTemplateProcessor.process(res,getLanguage(req,session)+"/"+startTemplate, mergeData,out); + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); + + responseData.put("defaultlanguage", getDefaultLanguage(aRequest)); + responseData.put("languages", getLoginLanguages()); + + ServletHelper.generateResponse(aResponse.getWriter(), responseData, loginTemplate); } - catch(Exception e) { - handleError( res,out, "error while trying to send startpage. " + e.toString()); + catch (Throwable e) { + handleError(aRequest, aResponse, e); } } - public String getServletInfo(){ return "Mir 1.0 rev02 multilanguage"; } + public String getServletInfo() { + return "Mir " + configuration.getString("Mir.Version"); + } -} + private class SessionTracker implements HttpSessionBindingListener { + private String name; + private String id; + public SessionTracker(String aUserName, String anId) { + name = aUserName; + id = anId; + } + + public void valueBound(HttpSessionBindingEvent anEvent) { + MirGlobal.registerLogin(name, id); + } + + public void valueUnbound(HttpSessionBindingEvent anEvent) { + MirGlobal.registerLogout(name, id); + } + } +}