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