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