live debugging: finding a nullpointer
[mir.git] / source / Mir.java
1
2 import freemarker.template.SimpleHash;
3 import freemarker.template.SimpleScalar;
4 import mir.misc.HTMLParseException;
5 import mir.misc.HTMLTemplateProcessor;
6 import mir.misc.MirConfig;
7 import mir.misc.StringUtil;
8 import mir.servlet.*;
9 import mircoders.entity.EntityUsers;
10 import mircoders.module.ModuleMessage;
11 import mircoders.module.ModuleUsers;
12 import mircoders.storage.DatabaseMessages;
13 import mircoders.storage.DatabaseUsers;
14
15 import javax.servlet.ServletException;
16 import javax.servlet.UnavailableException;
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19 import javax.servlet.http.HttpSession;
20 import java.io.IOException;
21 import java.io.PrintWriter;
22 import java.lang.reflect.Method;
23 import java.util.GregorianCalendar;
24 import java.util.HashMap;
25 import java.util.Locale;
26
27 /**
28  *  Mir.java - main servlet, that dispatches to servletmodules
29  *
30  *  @author RK 1999-2001
31  *
32  */
33
34
35 public class Mir extends AbstractServlet {
36
37     private static ModuleUsers usersModule = null;
38     private static ModuleMessage messageModule = null;
39     private final static HashMap servletModuleInstanceHash = new HashMap();
40
41     public HttpSession session;
42
43     public void doGet(HttpServletRequest req, HttpServletResponse res)
44             throws ServletException, IOException {
45         doPost(req, res);
46     }
47
48     public void doPost(HttpServletRequest req, HttpServletResponse res)
49             throws ServletException, IOException, UnavailableException {
50
51         long startTime = System.currentTimeMillis();
52         long sessionConnectTime = 0;
53         String http = "";
54
55         // get the configration
56         if (getServletContext().getAttribute("mir.confed") == null) {
57             getConfig(req);
58         }
59         MirConfig.setServletName(getServletName());
60
61         session = req.getSession(true);
62
63         if (req.getServerPort() == 443) http = "https"; else http = "http";
64         res.setContentType("text/html");
65         String moduleName = req.getParameter("module");
66
67         checkLanguage(session, req);
68
69         /** @todo for cleanup and readability this should be moved to
70          *  method loginIfNecessary() */
71
72         // Authentifizierung
73         if (moduleName != null && moduleName.equals("login")) {
74             String user = req.getParameter("login");
75             String passwd = req.getParameter("password");
76             theLog.printDebugInfo("--login: evaluating for user: " + user);
77             EntityUsers userEntity = allowedUser(user, passwd);
78             if (userEntity == null) {
79                 // login failed: redirecting to login
80                 theLog.printWarning("--login: failed!");
81                 _sendLoginPage(res, req, res.getWriter());
82                 return;
83             }
84             else {
85                 // login successful
86
87                 theLog.printInfo("--login: successful! setting uid: " + userEntity.getId());
88                 session.setAttribute("login.uid", userEntity);
89                 theLog.printDebugInfo("--login: trying to retrieve login.target");
90                 String target = (String) session.getAttribute("login.target");
91
92                 if (target != null) {
93                     theLog.printDebugInfo("Redirect: " + target);
94                     int serverPort = req.getServerPort();
95                     String redirect = "";
96                     String redirectString = "";
97
98
99                     if (serverPort == 80) {
100                         redirect = res.encodeURL(http + "://" + req.getServerName() + target);
101                         redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
102                                 + redirect
103                                 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
104                     }
105                     else {
106                         redirect = res.encodeURL(http + "://" + req.getServerName() + ":" + req.getServerPort() + target);
107                         redirectString = "<html><head><meta http-equiv=refresh content=\"1;URL="
108                                 + redirect
109                                 + "\"></head><body>going <a href=\"" + redirect + "\">Mir</a></body></html>";
110                     }
111                     res.getWriter().println(redirectString);
112
113
114                     //res.sendRedirect(redirect);
115
116                 }
117                 else {
118                     // redirecting to default target
119                     theLog.printDebugInfo("--login: no target - redirecting to default");
120                     _sendStartPage(res, req, res.getWriter(), userEntity);
121                 }
122                 return;
123             } // if login succesful
124         } // if login
125
126         if (moduleName != null && moduleName.equals("logout")) {
127             theLog.printDebugInfo("--logout");
128             session.invalidate();
129
130             //session = req.getSession(true);
131             //checkLanguage(session, req);
132             _sendLoginPage(res, req, res.getWriter());
133             return;
134         }
135
136         // Check if authed!
137         EntityUsers userEntity = (EntityUsers) session.getAttribute("login.uid");
138         if (userEntity == null) {
139             // redirect to loginpage
140             String redirectString = req.getRequestURI();
141             String queryString = req.getQueryString();
142             if (queryString != null && !queryString.equals("")) {
143                 redirectString += "?" + req.getQueryString();
144                 theLog.printDebugInfo("STORING: " + redirectString);
145                 session.setAttribute("login.target", redirectString);
146             }
147             _sendLoginPage(res, req, res.getWriter());
148             return;
149         }
150
151         // If no module is specified goto standard startpage
152         if (moduleName == null || moduleName.equals("")) {
153             theLog.printDebugInfo("no module: redirect to standardpage");
154             _sendStartPage(res, req, res.getWriter(), userEntity);
155             return;
156         }
157         // end of auth
158
159         // From now on regular dispatching...
160         try {
161             // get servletmodule by parameter and continue with dispacher
162             ServletModule smod = getServletModuleForName(moduleName);
163             ServletModuleDispatch.dispatch(smod, req, res);
164         }
165         catch (ServletModuleException e) {
166             handleError(req, res, res.getWriter(),
167                         "ServletException in Module " + moduleName + " -- " + e.toString());
168         }
169         catch (ServletModuleUserException e) {
170             handleUserError(req, res, res.getWriter(), "User error" + e.toString());
171         }
172
173         // timing...
174         sessionConnectTime = System.currentTimeMillis() - startTime;
175         theLog.printInfo("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms");
176     }
177
178
179     /**
180      *  Private method getServletModuleForName returns ServletModule
181      *  from Cache
182      *
183      * @return ServletModule
184      *
185      */
186     private static ServletModule getServletModuleForName(String moduleName)
187             throws ServletModuleException {
188
189         // Instance in Map ?
190         if (!servletModuleInstanceHash.containsKey(moduleName)) {
191             // was not found in hash...
192             try {
193                 Class theServletModuleClass = null;
194                 try {
195                     // first we try to get ServletModule from stern.che3.servlet
196                     theServletModuleClass = Class.forName("mircoders.servlet.ServletModule" + moduleName);
197                 }
198                 catch (ClassNotFoundException e) {
199                     // on failure, we try to get it from lib-layer
200                     theServletModuleClass = Class.forName("mir.servlet.ServletModule" + moduleName);
201                 }
202                 Method m = theServletModuleClass.getMethod("getInstance", null);
203                 ServletModule smod = (ServletModule) m.invoke(null, null);
204                 // we put it into map for further reference
205                 servletModuleInstanceHash.put(moduleName, smod);
206                 return smod;
207             }
208             catch (Exception e) {
209                 throw new ServletModuleException("*** error resolving classname for " +
210                                                  moduleName + " -- " + e.toString());
211             }
212         }
213         else
214             return (ServletModule) servletModuleInstanceHash.get(moduleName);
215     }
216
217
218     private void handleError(HttpServletRequest req, HttpServletResponse res,
219                              PrintWriter out, String errorString) {
220
221         try {
222             theLog.printError(errorString);
223             SimpleHash modelRoot = new SimpleHash();
224             modelRoot.put("errorstring", new SimpleScalar(errorString));
225             modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
226             HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.ErrorTemplate"), modelRoot, out, getLocale(req));
227             out.close();
228         }
229         catch (Exception e) {
230             System.err.println("Error in ErrorTemplate");
231         }
232     }
233
234     private void handleUserError(HttpServletRequest req, HttpServletResponse res,
235                                  PrintWriter out, String errorString) {
236         try {
237             theLog.printError(errorString);
238             SimpleHash modelRoot = new SimpleHash();
239             modelRoot.put("errorstring", new SimpleScalar(errorString));
240             modelRoot.put("date", new SimpleScalar(StringUtil.date2readableDateTime(new GregorianCalendar())));
241             HTMLTemplateProcessor.process(res, MirConfig.getProp("Mir.UserErrorTemplate"),
242                                           modelRoot, out, getLocale(req));
243             out.close();
244         }
245         catch (Exception e) {
246             System.err.println("Fehler in UserErrorTemplate");
247         }
248
249     }
250
251     /**
252      *  evaluate login for user / password
253      */
254     protected EntityUsers allowedUser(String user, String password) {
255         try {
256             if (usersModule == null) usersModule = new ModuleUsers(DatabaseUsers.getInstance());
257             return usersModule.getUserForLogin(user, password);
258         }
259         catch (Exception e) {
260             theLog.printDebugInfo(e.toString());
261             e.printStackTrace();
262             return null;
263         }
264     }
265
266     // Redirect-methods
267     private void _sendLoginPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out) {
268         String loginTemplate = MirConfig.getProp("Mir.LoginTemplate");//"login.template";
269         //  theLog.printDebugInfo("login template: "+loginTemplate);
270         String sessionUrl = res.encodeURL("");
271         //session = req.getSession(true);
272         try {
273             //theLog.printDebugInfo("login: "+lang);
274             //if(lang==null){
275             //  lang=getAcceptLanguage(req);
276             //}
277             SimpleHash mergeData = new SimpleHash();
278             mergeData.put("session", sessionUrl);
279             HTMLTemplateProcessor.process(res, loginTemplate, mergeData, out, getLocale(req));
280         }
281         catch (HTMLParseException e) {
282             handleError(req, res, out, "Error in logintemplate.");
283         }
284     }
285
286     private void _sendStartPage(HttpServletResponse res, HttpServletRequest req, PrintWriter out, EntityUsers userEntity) {
287         String startTemplate = "admin/start_admin.template";
288         String sessionUrl = res.encodeURL("");
289         try {
290             // merge with logged in user and messages
291             SimpleHash mergeData = new SimpleHash();
292             mergeData.put("session", sessionUrl);
293             mergeData.put("login_user", userEntity);
294             if (messageModule == null) messageModule = new ModuleMessage(DatabaseMessages.getInstance());
295             mergeData.put("messages", messageModule.getByWhereClause(null, "webdb_create desc", 0, 10));
296             HTMLTemplateProcessor.process(res, startTemplate, mergeData, out, getLocale(req));
297         }
298         catch (Exception e) {
299             handleError(req, res, out, "error while trying to send startpage. " + e.toString());
300         }
301     }
302
303     public String getServletInfo() {
304         return "Mir 1.0 rev02 multilanguage";
305     }
306
307     private void checkLanguage(HttpSession session, HttpServletRequest req) {
308
309         // a lang parameter always sets the language
310         String lang = req.getParameter("lang");
311         if (lang != null) {
312             theLog.printInfo("selected language "+lang+" overrides accept-language");
313             setLanguage(session, lang);
314             setLocale(session, new Locale(lang, ""));
315         }
316         // otherwise store language from accept header in session
317         else if (session.getAttribute("Language") == null) {
318             theLog.printInfo("accept-language is "+req.getLocale().getLanguage());
319             setLanguage(session, req.getLocale().getLanguage());
320             setLocale(session, req.getLocale());
321         }
322     }
323 }
324