bug in view children fixed
[mir.git] / source / mircoders / servlet / ServletModuleContent.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30
31 package mircoders.servlet;
32
33 import mir.entity.adapter.EntityAdapter;
34 import mir.entity.adapter.EntityAdapterEngine;
35 import mir.entity.adapter.EntityAdapterModel;
36 import mir.generator.Generator;
37 import mir.log.LoggerWrapper;
38 import mir.misc.StringUtil;
39 import mir.servlet.ServletModule;
40 import mir.servlet.ServletModuleExc;
41 import mir.servlet.ServletModuleFailure;
42 import mir.util.*;
43 import mircoders.entity.EntityContent;
44 import mircoders.entity.EntityUsers;
45 import mircoders.global.MirGlobal;
46 import mircoders.module.ModuleContent;
47 import mircoders.storage.DatabaseContent;
48 import mircoders.storage.DatabaseContentToTopics;
49
50 import javax.servlet.http.HttpServletRequest;
51 import javax.servlet.http.HttpServletResponse;
52 import java.util.*;
53
54 /**
55  * Article admin interface code
56  */
57
58 public class ServletModuleContent extends ServletModule {
59   private static ServletModuleContent instance = new ServletModuleContent();
60   public static ServletModule getInstance() { return instance; }
61   private static ModuleContent contentModule;
62
63   private ServletModuleContent() {
64     super();
65     propagatedParameters.add("selectarticleurl");
66
67     logger = new LoggerWrapper("ServletModule.Content");
68
69     try {
70       definition = "content";
71       contentModule = new ModuleContent();
72       mainModule = contentModule;
73     }
74     catch (Throwable e) {
75       logger.fatal("ServletModuleContent could not be initialized: " + e.toString());
76     }
77   }
78
79   public void search(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleFailure {
80     try {
81       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
82       SQLQueryBuilder queryBuilder = new SQLQueryBuilder();
83       String searchField = requestParser.getParameterWithDefault("searchfield", "");
84       String searchValue = requestParser.getParameterWithDefault("searchvalue", "").trim();
85       String searchOrder = requestParser.getParameterWithDefault("searchorder", "");
86       String searchispublished = requestParser.getParameterWithDefault("searchispublished", "");
87       String searchArticleType = requestParser.getParameterWithDefault("searcharticletype", "");
88
89       if (searchValue.length()>0) {
90         if (searchField.equals("id"))
91           queryBuilder.appendAndCondition(
92             "id='"+JDBCStringRoutines.escapeStringLiteral(searchValue)+"'");
93         else if (searchField.equals("contents"))
94           queryBuilder.appendAndCondition(
95             "(lower(content_data) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')"+
96             " or (lower(description) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')");
97         else
98           queryBuilder.appendAndCondition(
99             "lower("+ searchField + ") like " +
100             "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%'");
101       }
102
103       if (searchispublished.length()>0) {
104         if (searchispublished.equals("0"))
105           queryBuilder.appendAndCondition("is_published='f'");
106         else
107           queryBuilder.appendAndCondition("is_published='t'");
108       }
109
110       if (searchArticleType.length()>0) {
111         queryBuilder.appendAndCondition("to_article_type="+Integer.parseInt(searchArticleType));
112       }
113
114       if (searchOrder.length()>0) {
115         if (searchOrder.equals("datedesc"))
116           queryBuilder.appendDescendingOrder("webdb_create");
117         else if (searchOrder.equals("dateasc"))
118           queryBuilder.appendAscendingOrder("webdb_create");
119         else if (searchOrder.equals("title"))
120           queryBuilder.appendAscendingOrder("title");
121         else if (searchOrder.equals("creator"))
122           queryBuilder.appendAscendingOrder("creator");
123       }
124
125       returnList(aRequest, aResponse, queryBuilder.getWhereClause(), queryBuilder.getOrderByClause(), 0);
126     }
127     catch (Throwable e) {
128       throw new ServletModuleFailure(e);
129     }
130   }
131
132   public void add(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
133     editObject(aRequest, aResponse, null);
134   }
135
136   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
137     try {
138       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
139
140       String now = StringUtil.date2webdbDate(new GregorianCalendar());
141       withValues.put("date", now);
142       withValues.put("publish_path", StringUtil.webdbDate2path(now));
143       withValues.put("to_publisher", ServletHelper.getUser(aRequest).getId());
144       withValues.put("is_produced", "0");
145       if (!withValues.containsKey("is_published"))
146         withValues.put("is_published","0");
147       if (!withValues.containsKey("is_html"))
148         withValues.put("is_html","0");
149
150       String webdbCreate = (String) withValues.get("webdb_create");
151       if (webdbCreate==null || webdbCreate.trim().length()==0)
152         withValues.remove("webdb_create");
153
154       String id = mainModule.add(withValues);
155       logAdminUsage(aRequest, id, "object added");
156
157       DatabaseContentToTopics.getInstance().setTopics(id, aRequest.getParameterValues("to_topic"));
158
159       editObject(aRequest, aResponse, id);
160     }
161     catch (Throwable e) {
162       throw new ServletModuleFailure(e);
163     }
164   }
165
166   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
167     String idParam = aRequest.getParameter("id");
168     if (idParam == null)
169       throw new ServletModuleExc("Invalid call: id not supplied ");
170     editObject(aRequest, aResponse, idParam);
171   }
172
173   /**
174    * Attaches media to an article
175    */
176   public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
177     String  mediaIdParam = aRequest.getParameter("mid");
178     String  articleId = aRequest.getParameter("articleid");
179
180     if (articleId == null || mediaIdParam==null)
181       throw new ServletModuleExc("smod content :: attach :: articleid/mid missing");
182
183     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
184       throw new ServletModuleExc("Article has been locked");
185
186     try {
187       EntityContent entContent = (EntityContent) mainModule.getById(articleId);
188       entContent.attach(mediaIdParam);
189     }
190     catch(Throwable e) {
191       throw new ServletModuleFailure(e);
192     }
193
194     logAdminUsage(aRequest, articleId, "media " + mediaIdParam + " attached");
195
196     editObject(aRequest, aResponse, articleId);
197   }
198
199   /**
200    * Deattaches media from an article
201    */
202   public void dettach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
203   {
204     String  articleId = aRequest.getParameter("articleid");
205     String  midParam = aRequest.getParameter("mid");
206     if (articleId == null)
207       throw new ServletModuleExc("smod content :: dettach :: articleid missing");
208     if (midParam == null)
209       throw new ServletModuleExc("smod content :: dettach :: mid missing");
210
211     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
212       throw new ServletModuleExc("Article has been locked");
213
214     try {
215       EntityContent entContent = (EntityContent)mainModule.getById(articleId);
216       entContent.dettach(articleId, midParam);
217     }
218     catch(Throwable e) {
219       throw new ServletModuleFailure(e);
220     }
221
222     logAdminUsage(aRequest, articleId, "media " + midParam + " deattached");
223
224     editObject(aRequest, aResponse, articleId);
225   }
226
227   /**
228    * Locks an article
229    */
230   public void lock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
231   {
232     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
233
234     String idParam = requestParser.getParameter("id");
235     if (idParam == null)
236       throw new ServletModuleExc("Wrong call: (id) is missing");
237
238     EntityUsers user = ServletHelper.getUser(aRequest);
239
240     if (!MirGlobal.accessControl().article().mayLockArticle(user, idParam))
241       throw new ServletModuleExc("Unable to lock");
242
243     contentModule.lockArticle(idParam, user.getId(), false);
244
245     editObject(aRequest, aResponse, idParam);
246   }
247
248   /**
249    * Unlocks an article
250    */
251   public void unlock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
252   {
253     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
254
255     String idParam = requestParser.getParameter("id");
256     if (idParam == null)
257       throw new ServletModuleExc("Wrong call: (id) is missing");
258
259     EntityUsers user = ServletHelper.getUser(aRequest);
260
261     if (!MirGlobal.accessControl().article().mayUnlockArticle(user, idParam))
262       throw new ServletModuleExc("Unable to unlock");
263
264     contentModule.unlockArticle(idParam, user.getId(), false);
265
266     editObject(aRequest, aResponse, idParam);
267   }
268
269   /**
270    * Forcelocks an article
271    */
272   public void forcelock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
273   {
274     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
275
276     String idParam = requestParser.getParameter("id");
277     if (idParam == null)
278       throw new ServletModuleExc("Wrong call: (id) is missing");
279
280     EntityUsers user = ServletHelper.getUser(aRequest);
281
282     if (!MirGlobal.accessControl().article().mayForceLockArticle(user, idParam))
283       throw new ServletModuleExc("Unable to force lock");
284
285     contentModule.lockArticle(idParam, user.getId(), true);
286
287     editObject(aRequest, aResponse, idParam);
288   }
289
290   /**
291    * Stores an article
292    */
293   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
294   {
295     try {
296       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
297
298       String idParam = requestParser.getParameter("id");
299       if (idParam == null)
300         throw new ServletModuleExc("Wrong call: (id) is missing");
301
302       if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), idParam))
303         throw new ServletModuleExc("Article has been locked");
304
305       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
306
307       withValues.put("is_produced", "0");
308       if (!withValues.containsKey("is_published"))
309         withValues.put("is_published","0");
310       if (!withValues.containsKey("is_html"))
311         withValues.put("is_html","0");
312
313       String webdbCreate = (String) withValues.get("webdb_create");
314       if (webdbCreate==null || webdbCreate.trim().length()==0)
315         withValues.remove("webdb_create");
316
317       String id = mainModule.set(withValues);
318
319       logAdminUsage(aRequest, id, "object modified");
320
321       DatabaseContentToTopics.getInstance().setTopics(aRequest.getParameter("id"), aRequest.getParameterValues("to_topic"));
322
323       if (MirGlobal.accessControl().article().mayUnlockArticle(ServletHelper.getUser(aRequest), idParam) &&
324          (requestParser.getParameterWithDefault("unlock", "0").equals("1"))) {
325         contentModule.unlockArticle(id, ServletHelper.getUser(aRequest).getId(), false);
326       }
327
328       editObject(aRequest, aResponse, idParam);
329     }
330     catch (Throwable e) {
331       throw new ServletModuleFailure(e);
332     }
333   }
334
335
336   /**
337    * Returns the basic article editing form.
338    *
339    * @param id identifier of the article. <code>null</code>, means show an
340    *     empty form to add a new article.
341    */
342   public void editObject(HttpServletRequest aRequest, HttpServletResponse aResponse, String id)
343       throws ServletModuleExc {
344     try {
345       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
346       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
347       EntityAdapterModel model = MirGlobal.localizer().dataModel().adapterModel();
348       Map article;
349       URLBuilder urlBuilder = new URLBuilder();
350
351       urlBuilder.setValue("module", "Content");
352       urlBuilder.setValue("do", "edit");
353       urlBuilder.setValue("id", id);
354       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
355
356       if (id!=null) {
357         responseData.put("new", Boolean.FALSE);
358         article = model.makeEntityAdapter("content", mainModule.getById(id));
359
360         EntityUsers user = ServletHelper.getUser(aRequest);
361
362         responseData.put("mayEdit", new Boolean(MirGlobal.accessControl().article().mayEditArticle(user, id)));
363         responseData.put("mayLock", new Boolean(MirGlobal.accessControl().article().mayLockArticle(user, id)));
364         responseData.put("mayForceLock", new Boolean(MirGlobal.accessControl().article().mayForceLockArticle(user, id)));
365         responseData.put("mayUnlock", new Boolean(MirGlobal.accessControl().article().mayUnlockArticle(user, id)));
366       }
367       else {
368         List fields = DatabaseContent.getInstance().getFieldNames();
369         responseData.put("new", Boolean.TRUE);
370         article = new HashMap();
371         Iterator i = fields.iterator();
372         while (i.hasNext()) {
373           article.put(i.next(), null);
374         }
375
376         article.put("to_topics", null);
377
378         MirGlobal.localizer().adminInterface().initializeArticle(article);
379
380         responseData.put("mayEdit", Boolean.TRUE);
381         responseData.put("mayLock", Boolean.FALSE);
382         responseData.put("mayForceLock", Boolean.FALSE);
383         responseData.put("mayUnlock", Boolean.FALSE);
384       }
385       responseData.put("article", article);
386
387       List topicsList = new ArrayList();
388
389       String[] topicCategories = configuration.getStringArray("Mir.Localizer.Admin.TopicLists");
390
391       if (topicCategories.length==0 ) {
392         Map categoryMap = new HashMap();
393         categoryMap.put("key", "topic");
394         categoryMap.put("listtype", "0");
395         categoryMap.put("listparameter", "3");
396         categoryMap.put("items", EntityAdapterEngine.retrieveAdapterList(model, "topic", "", "title", -1, 0));
397         topicsList.add(categoryMap);
398       }
399       else {
400         for (int i = 0; i < topicCategories.length; i++) {
401           try {
402             Map categoryMap = new HashMap();
403             List parts = StringRoutines.splitString(topicCategories[i], ":");
404
405             String key = null;
406             String listtype = "0";
407             String listparameter = "5";
408             String where = "";
409             String order = "";
410
411             if (parts.size() > 0)
412               key = (String) parts.get(0);
413             if (parts.size() > 1)
414               listtype = (String) parts.get(1);
415             if (parts.size() > 2)
416               listparameter = (String) parts.get(2);
417             if (parts.size() > 3)
418               where = (String) parts.get(3);
419             if (parts.size() > 4)
420               order = (String) parts.get(4);
421
422             if (key != null) {
423               categoryMap.put("key", key);
424               categoryMap.put("listtype", listtype);
425               categoryMap.put("listparameter", listparameter);
426               categoryMap.put("items", EntityAdapterEngine.retrieveAdapterList(model, "topic", where, order, -1, 0));
427               topicsList.add(categoryMap);
428             }
429           }
430           catch (Throwable t) {
431             logger.error("error while preparing topics: " + t.toString());
432           }
433         }
434       }
435
436       responseData.put("topics", topicsList);
437
438       responseData.put("returnurl", requestParser.getParameter("returnurl"));
439       responseData.put("thisurl", urlBuilder.getQuery());
440
441       ServletHelper.generateResponse(aResponse.getWriter(), responseData, editGenerator);
442     }
443     catch (Throwable e) {
444       throw new ServletModuleFailure(e);
445     }
446   }
447
448   public void selectparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
449     try {
450       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
451       URLBuilder urlBuilder = new URLBuilder();
452
453       urlBuilder.setValue("module", "Content");
454       urlBuilder.setValue("do", "setparent");
455       urlBuilder.setValue("childid", requestParser.getParameter("id"));
456       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
457
458       returnList(aRequest, aResponse, "", "", 0,
459           Collections.singletonMap("selectarticleurl", urlBuilder.getQuery()));
460     }
461     catch (Throwable e) {
462       throw new ServletModuleFailure(e);
463     }
464   }
465
466   public void listchildren(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
467     try {
468       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
469       String articleId = requestParser.getParameter("article_id");
470
471       if (articleId == null)
472         throw new ServletModuleExc("ServletModuleContent.listchildren: article_id not set!");
473
474       returnList(aRequest, aResponse, "to_content = " + articleId, "webdb_create desc", 0);
475     }
476     catch (Throwable e) {
477       throw new ServletModuleFailure(e);
478     }
479   }
480
481   public void setparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
482   {
483     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
484     String articleId = requestParser.getParameter("childid");
485     String parentId  = requestParser.getParameter("id");
486     String returnUrl = requestParser.getParameter("returnurl");
487
488     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
489       throw new ServletModuleExc("Article has been locked");
490
491     try {
492       EntityContent article = (EntityContent) mainModule.getById(articleId);
493       article.setFieldValue("to_content", parentId);
494       article.setProduced(false);
495       article.update();
496       logAdminUsage(aRequest, articleId, "parent set to " + parentId);
497     }
498     catch(Throwable e) {
499       logger.error("ServletModuleContent.setparent: " + e.getMessage());
500       throw new ServletModuleFailure(e);
501     }
502
503     ServletHelper.redirect(aResponse, returnUrl);
504   }
505
506   public void clearparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
507   {
508     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
509     String articleId = requestParser.getParameter("id");
510     String returnUrl = requestParser.getParameter("returnurl");
511
512     try {
513       EntityContent article = (EntityContent) mainModule.getById(articleId);
514       article.setFieldValue("to_content", "");
515       article.setProduced(false);
516       article.update();
517       logAdminUsage(aRequest, articleId, "parent cleared");
518     }
519     catch(Throwable e) {
520       e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
521       logger.error("ServletModuleContent.clearparent: " + e.getMessage());
522
523       throw new ServletModuleFailure("ServletModuleContent.clearparent: " + e.getMessage(), e);
524     }
525
526     ServletHelper.redirect(aResponse, returnUrl);
527   }
528
529   public void showPreview(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
530     try {
531       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
532       String articleId = requestParser.getParameter("id");
533       EntityAdapter article = model.makeEntityAdapter("content", mainModule.getById(articleId));
534       String preview = requestParser.getParameterWithDefault("preview", "default");
535
536       Map generationValues = new HashMap();
537       Generator generator =
538           MirGlobal.localizer().adminInterface().prepareArticlePreview(preview, article, generationValues);
539
540       generator.generate(aResponse.getWriter(), generationValues, logger);
541     }
542     catch (Exception e) {
543       throw new ServletModuleFailure(e);
544     }
545   }
546 }