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