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