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