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