2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
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.
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.
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
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.
31 package mircoders.servlet;
33 import java.util.GregorianCalendar;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Locale;
39 import java.util.Vector;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
44 import mir.entity.adapter.EntityAdapterModel;
45 import mir.entity.adapter.EntityIteratorAdapter;
46 import mir.entity.adapter.EntityAdapter;
47 import mir.log.LoggerWrapper;
48 import mir.misc.StringUtil;
49 import mir.servlet.ServletModule;
50 import mir.servlet.ServletModuleExc;
51 import mir.servlet.ServletModuleFailure;
52 import mir.util.CachingRewindableIterator;
53 import mir.util.HTTPRequestParser;
54 import mir.util.JDBCStringRoutines;
55 import mir.util.SQLQueryBuilder;
56 import mir.util.StringRoutines;
57 import mir.util.URLBuilder;
58 import mir.generator.Generator;
59 import mircoders.entity.*;
60 import mircoders.global.MirGlobal;
61 import mircoders.module.ModuleContent;
62 import mircoders.storage.DatabaseContent;
63 import mircoders.storage.DatabaseContentToTopics;
66 * Article admin interface code
69 public class ServletModuleContent extends ServletModule
71 private static ServletModuleContent instance = new ServletModuleContent();
72 public static ServletModule getInstance() { return instance; }
73 private static ModuleContent contentModule;
75 private ServletModuleContent() {
78 logger = new LoggerWrapper("ServletModule.Content");
81 contentModule = new ModuleContent();
82 mainModule = contentModule;
85 logger.fatal("ServletModuleContent could not be initialized: " + e.toString());
89 public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
91 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
93 String where = requestParser.getParameter("where");
94 String order = requestParser.getParameterWithDefault("order", "webdb_create desc");
95 int offset = requestParser.getIntegerWithDefault("offset", 0);
96 String selectArticleUrl = requestParser.getParameter("selectarticleurl");
98 returnList(aRequest, aResponse, where, order, offset, selectArticleUrl);
101 public void search(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleFailure {
103 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
104 SQLQueryBuilder queryBuilder = new SQLQueryBuilder();
105 String searchField = requestParser.getParameterWithDefault("searchfield", "");
106 String searchValue = requestParser.getParameterWithDefault("searchvalue", "").trim();
107 String searchOrder = requestParser.getParameterWithDefault("searchorder", "");
108 String searchispublished = requestParser.getParameterWithDefault("searchispublished", "");
109 String searchArticleType = requestParser.getParameterWithDefault("searcharticletype", "");
110 String selectArticleUrl = requestParser.getParameter("selectarticleurl");
112 if (searchValue.length()>0) {
113 if (searchField.equals("id"))
114 queryBuilder.appendAndCondition(
115 "id='"+JDBCStringRoutines.escapeStringLiteral(searchValue)+"'");
116 else if (searchField.equals("contents"))
117 queryBuilder.appendAndCondition(
118 "(lower(content_data) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')"+
119 " or (lower(description) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')");
121 queryBuilder.appendAndCondition(
122 "lower("+ searchField + ") like " +
123 "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%'");
126 if (searchispublished.length()>0) {
127 if (searchispublished.equals("0"))
128 queryBuilder.appendAndCondition("is_published='f'");
130 queryBuilder.appendAndCondition("is_published='t'");
133 if (searchArticleType.length()>0) {
134 queryBuilder.appendAndCondition("to_article_type="+Integer.parseInt(searchArticleType));
137 if (searchOrder.length()>0) {
138 if (searchOrder.equals("datedesc"))
139 queryBuilder.appendDescendingOrder("webdb_create");
140 else if (searchOrder.equals("dateasc"))
141 queryBuilder.appendAscendingOrder("webdb_create");
142 else if (searchOrder.equals("title"))
143 queryBuilder.appendAscendingOrder("title");
144 else if (searchOrder.equals("creator"))
145 queryBuilder.appendAscendingOrder("creator");
148 returnList(aRequest, aResponse, queryBuilder.getWhereClause(), queryBuilder.getOrderByClause(), 0, selectArticleUrl);
150 catch (Throwable e) {
151 throw new ServletModuleFailure(e);
155 public void add(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
156 editObject(aRequest, aResponse, null);
159 public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
161 Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
163 String now = StringUtil.date2webdbDate(new GregorianCalendar());
164 withValues.put("date", now);
165 withValues.put("publish_path", StringUtil.webdbDate2path(now));
166 withValues.put("to_publisher", ServletHelper.getUser(aRequest).getId());
167 withValues.put("is_produced", "0");
168 if (!withValues.containsKey("is_published"))
169 withValues.put("is_published","0");
170 if (!withValues.containsKey("is_html"))
171 withValues.put("is_html","0");
173 String webdbCreate = (String) withValues.get("webdb_create");
174 if (webdbCreate==null || webdbCreate.trim().length()==0)
175 withValues.remove("webdb_create");
177 String id = mainModule.add(withValues);
178 logAdminUsage(aRequest, id, "object added");
180 DatabaseContentToTopics.getInstance().setTopics(id, aRequest.getParameterValues("to_topic"));
182 editObject(aRequest, aResponse, id);
184 catch (Throwable e) {
185 throw new ServletModuleFailure(e);
189 public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
190 String idParam = aRequest.getParameter("id");
192 throw new ServletModuleExc("Invalid call: id not supplied ");
193 editObject(aRequest, aResponse, idParam);
197 * Attaches media to an article
200 public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
201 String mediaIdParam = aRequest.getParameter("mid");
202 String articleId = aRequest.getParameter("articleid");
204 if (articleId == null || mediaIdParam==null)
205 throw new ServletModuleExc("smod content :: attach :: articleid/mid missing");
207 if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
208 throw new ServletModuleExc("Article has been locked");
211 EntityContent entContent = (EntityContent) mainModule.getById(articleId);
212 entContent.attach(mediaIdParam);
215 throw new ServletModuleFailure(e);
218 logAdminUsage(aRequest, articleId, "media " + mediaIdParam + " attached");
220 editObject(aRequest, aResponse, articleId);
224 * Deattaches media from an article
226 public void dettach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
228 String articleId = aRequest.getParameter("articleid");
229 String midParam = aRequest.getParameter("mid");
230 if (articleId == null)
231 throw new ServletModuleExc("smod content :: dettach :: articleid missing");
232 if (midParam == null)
233 throw new ServletModuleExc("smod content :: dettach :: mid missing");
235 if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
236 throw new ServletModuleExc("Article has been locked");
239 EntityContent entContent = (EntityContent)mainModule.getById(articleId);
240 entContent.dettach(articleId, midParam);
243 throw new ServletModuleFailure(e);
246 logAdminUsage(aRequest, articleId, "media " + midParam + " deattached");
248 editObject(aRequest, aResponse, articleId);
254 public void lock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
256 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
258 String idParam = requestParser.getParameter("id");
260 throw new ServletModuleExc("Wrong call: (id) is missing");
262 EntityUsers user = ServletHelper.getUser(aRequest);
264 if (!MirGlobal.accessControl().article().mayLockArticle(user, idParam))
265 throw new ServletModuleExc("Unable to lock");
267 contentModule.lockArticle(idParam, user.getId(), false);
269 editObject(aRequest, aResponse, idParam);
275 public void unlock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
277 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
279 String idParam = requestParser.getParameter("id");
281 throw new ServletModuleExc("Wrong call: (id) is missing");
283 EntityUsers user = ServletHelper.getUser(aRequest);
285 if (!MirGlobal.accessControl().article().mayUnlockArticle(user, idParam))
286 throw new ServletModuleExc("Unable to unlock");
288 contentModule.unlockArticle(idParam, user.getId(), false);
290 editObject(aRequest, aResponse, idParam);
294 * Forcelocks an article
296 public void forcelock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
298 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
300 String idParam = requestParser.getParameter("id");
302 throw new ServletModuleExc("Wrong call: (id) is missing");
304 EntityUsers user = ServletHelper.getUser(aRequest);
306 if (!MirGlobal.accessControl().article().mayForceLockArticle(user, idParam))
307 throw new ServletModuleExc("Unable to force lock");
309 contentModule.lockArticle(idParam, user.getId(), true);
311 editObject(aRequest, aResponse, idParam);
317 public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
320 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
322 String idParam = requestParser.getParameter("id");
324 throw new ServletModuleExc("Wrong call: (id) is missing");
326 if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), idParam))
327 throw new ServletModuleExc("Article has been locked");
329 Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
331 withValues.put("is_produced", "0");
332 if (!withValues.containsKey("is_published"))
333 withValues.put("is_published","0");
334 if (!withValues.containsKey("is_html"))
335 withValues.put("is_html","0");
337 String webdbCreate = (String) withValues.get("webdb_create");
338 if (webdbCreate==null || webdbCreate.trim().length()==0)
339 withValues.remove("webdb_create");
341 String id = mainModule.set(withValues);
343 logAdminUsage(aRequest, id, "object modified");
345 DatabaseContentToTopics.getInstance().setTopics(aRequest.getParameter("id"), aRequest.getParameterValues("to_topic"));
347 if (MirGlobal.accessControl().article().mayUnlockArticle(ServletHelper.getUser(aRequest), idParam) &&
348 (requestParser.getParameterWithDefault("unlock", "0").equals("1"))) {
349 contentModule.unlockArticle(id, ServletHelper.getUser(aRequest).getId(), false);
352 editObject(aRequest, aResponse, idParam);
354 catch (Throwable e) {
355 throw new ServletModuleFailure(e);
361 * Returns the basic article editing form.
363 * @param id identifier of the article. <code>null</code>, means show an
364 * empty form to add a new article.
366 public void editObject(HttpServletRequest aRequest, HttpServletResponse aResponse, String id)
367 throws ServletModuleExc {
369 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
370 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
371 EntityAdapterModel model = MirGlobal.localizer().dataModel().adapterModel();
373 URLBuilder urlBuilder = new URLBuilder();
375 urlBuilder.setValue("module", "Content");
376 urlBuilder.setValue("do", "edit");
377 urlBuilder.setValue("id", id);
378 urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
381 responseData.put("new", Boolean.FALSE);
382 article = model.makeEntityAdapter("content", mainModule.getById(id));
384 EntityUsers user = ServletHelper.getUser(aRequest);
386 responseData.put("mayEdit", new Boolean(MirGlobal.accessControl().article().mayEditArticle(user, id)));
387 responseData.put("mayLock", new Boolean(MirGlobal.accessControl().article().mayLockArticle(user, id)));
388 responseData.put("mayForceLock", new Boolean(MirGlobal.accessControl().article().mayForceLockArticle(user, id)));
389 responseData.put("mayUnlock", new Boolean(MirGlobal.accessControl().article().mayUnlockArticle(user, id)));
392 List fields = DatabaseContent.getInstance().getFieldNames();
393 responseData.put("new", Boolean.TRUE);
394 article = new HashMap();
395 Iterator i = fields.iterator();
396 while (i.hasNext()) {
397 article.put(i.next(), null);
400 article.put("to_topics", null);
402 MirGlobal.localizer().adminInterface().initializeArticle(article);
404 responseData.put("mayEdit", Boolean.TRUE);
405 responseData.put("mayLock", Boolean.FALSE);
406 responseData.put("mayForceLock", Boolean.FALSE);
407 responseData.put("mayUnlock", Boolean.FALSE);
409 responseData.put("article", article);
411 List topicsList = new Vector();
413 String[] topicCategories = configuration.getStringArray("Mir.Localizer.Admin.TopicLists");
415 if (topicCategories.length==0 ) {
416 Map categoryMap = new HashMap();
417 categoryMap.put("key", "topic");
418 categoryMap.put("listtype", "0");
419 categoryMap.put("listparameter", "3");
420 categoryMap.put("items",
421 new EntityIteratorAdapter("", "title",
422 20, MirGlobal.localizer().dataModel().adapterModel(), "topic"));
423 topicsList.add(categoryMap);
428 for (int i = 0; i < topicCategories.length; i++) {
430 Map categoryMap = new HashMap();
431 List parts = StringRoutines.splitString(topicCategories[i], ":");
433 String listtype = "0";
434 String listparameter = "5";
438 if (parts.size() > 0)
439 key = (String) parts.get(0);
440 if (parts.size() > 1)
441 listtype = (String) parts.get(1);
442 if (parts.size() > 2)
443 listparameter = (String) parts.get(2);
444 if (parts.size() > 3)
445 where = (String) parts.get(3);
446 if (parts.size() > 4)
447 order = (String) parts.get(4);
450 categoryMap.put("key", key);
451 categoryMap.put("listtype", listtype);
452 categoryMap.put("listparameter", listparameter);
453 categoryMap.put("items",
454 new EntityIteratorAdapter(where, order,
455 20, MirGlobal.localizer().dataModel().adapterModel(), "topic"));
456 topicsList.add(categoryMap);
459 catch (Throwable t) {
460 logger.error("error while preparing topics: " + t.toString());
465 responseData.put("topics", topicsList);
467 responseData.put("returnurl", requestParser.getParameter("returnurl"));
468 responseData.put("thisurl", urlBuilder.getQuery());
470 ServletHelper.generateResponse(aResponse.getWriter(), responseData, editGenerator);
472 catch (Throwable e) {
473 throw new ServletModuleFailure(e);
477 public void returnList(HttpServletRequest aRequest, HttpServletResponse aResponse,
478 String aWhereClause, String anOrderByClause, int anOffset) throws ServletModuleExc {
479 this.returnList(aRequest, aResponse, aWhereClause, anOrderByClause, anOffset, null);
482 public void returnList(
483 HttpServletRequest aRequest,
484 HttpServletResponse aResponse,
486 String anOrderByClause,
488 String aSelectArticleUrl) throws ServletModuleExc {
490 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
491 URLBuilder urlBuilder = new URLBuilder();
495 Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
497 new CachingRewindableIterator(
498 new EntityIteratorAdapter( aWhereClause, anOrderByClause, nrEntitiesPerListPage,
499 MirGlobal.localizer().dataModel().adapterModel(), "content", nrEntitiesPerListPage, anOffset)
502 responseData.put("nexturl", null);
503 responseData.put("prevurl", null);
505 count=mainModule.getSize(aWhereClause);
507 urlBuilder.setValue("module", "Content");
508 urlBuilder.setValue("do", "list");
509 urlBuilder.setValue("where", aWhereClause);
510 urlBuilder.setValue("order", anOrderByClause);
513 urlBuilder.setValue("searchfield", requestParser.getParameter("searchfield"));
514 urlBuilder.setValue("searchvalue", requestParser.getParameter("searchvalue"));
515 urlBuilder.setValue("searchispublished", requestParser.getParameter("searchispublished"));
516 urlBuilder.setValue("searchorder", requestParser.getParameter("searchorder"));
517 urlBuilder.setValue("searcharticletype", requestParser.getParameter("searcharticletype"));
518 urlBuilder.setValue("selectarticleurl", aSelectArticleUrl);
520 responseData.put("searchfield", requestParser.getParameter("searchfield"));
521 responseData.put("searchvalue", requestParser.getParameter("searchvalue"));
522 responseData.put("searchispublished", requestParser.getParameter("searchispublished"));
523 responseData.put("searchorder", requestParser.getParameter("searchorder"));
524 responseData.put("searcharticletype", requestParser.getParameter("searcharticletype"));
525 responseData.put("selectarticleurl", aSelectArticleUrl);
527 urlBuilder.setValue("offset", anOffset);
528 responseData.put("offset" , new Integer(anOffset).toString());
529 responseData.put("thisurl" , urlBuilder.getQuery());
531 if (count>=anOffset+nrEntitiesPerListPage) {
532 urlBuilder.setValue("offset", (anOffset + nrEntitiesPerListPage));
533 responseData.put("nexturl" , urlBuilder.getQuery());
537 urlBuilder.setValue("offset", Math.max(anOffset - nrEntitiesPerListPage, 0));
538 responseData.put("prevurl" , urlBuilder.getQuery());
541 responseData.put("articles", articleList);
543 responseData.put("from" , Integer.toString(anOffset+1));
544 responseData.put("count", Integer.toString(count));
545 responseData.put("to", Integer.toString(Math.min(anOffset+nrEntitiesPerListPage, count)));
546 responseData.put("offset" , Integer.toString(anOffset));
547 responseData.put("order", anOrderByClause);
548 responseData.put("where" , aWhereClause);
550 ServletHelper.generateResponse(aResponse.getWriter(), responseData, listGenerator);
552 catch (Throwable e) {
553 throw new ServletModuleFailure(e);
557 public void selectparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
560 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
561 URLBuilder urlBuilder = new URLBuilder();
563 urlBuilder.setValue("module", "Content");
564 urlBuilder.setValue("do", "setparent");
565 urlBuilder.setValue("childid", requestParser.getParameter("id"));
566 urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
568 returnList(aRequest, aResponse, "", "", 0, urlBuilder.getQuery());
570 catch (Throwable e) {
571 throw new ServletModuleFailure(e);
575 public void listchildren(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
577 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
578 String articleId = requestParser.getParameter("article_id");
580 if (articleId == null)
581 throw new ServletModuleExc("ServletModuleContent.listchildren: article_id not set!");
583 returnList(aRequest, aResponse, "to_content = " + articleId, "webdb_create desc", 0, null);
585 catch (Throwable e) {
586 throw new ServletModuleFailure(e);
590 public void setparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
592 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
593 String articleId = requestParser.getParameter("childid");
594 String parentId = requestParser.getParameter("id");
595 String returnUrl = requestParser.getParameter("returnurl");
597 if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
598 throw new ServletModuleExc("Article has been locked");
601 EntityContent article = (EntityContent) mainModule.getById(articleId);
602 article.setFieldValue("to_content", parentId);
603 article.setProduced(false);
605 logAdminUsage(aRequest, articleId, "parent set to " + parentId);
608 logger.error("ServletModuleContent.setparent: " + e.getMessage());
609 throw new ServletModuleFailure(e);
612 ServletHelper.redirect(aResponse, returnUrl);
615 public void clearparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
617 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
618 String articleId = requestParser.getParameter("id");
619 String returnUrl = requestParser.getParameter("returnurl");
622 EntityContent article = (EntityContent) mainModule.getById(articleId);
623 article.setFieldValue("to_content", "");
624 article.setProduced(false);
626 logAdminUsage(aRequest, articleId, "parent cleared");
629 e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
630 logger.error("ServletModuleContent.clearparent: " + e.getMessage());
632 throw new ServletModuleFailure("ServletModuleContent.clearparent: " + e.getMessage(), e);
635 ServletHelper.redirect(aResponse, returnUrl);
638 public void showPreview(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
640 HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
641 String articleId = requestParser.getParameter("id");
642 EntityAdapter article = model.makeEntityAdapter("content", mainModule.getById(articleId));
643 String preview = requestParser.getParameterWithDefault("preview", "default");
645 Map generationValues = new HashMap();
646 Generator generator =
647 MirGlobal.localizer().adminInterface().prepareArticlePreview(preview, article, generationValues);
649 generator.generate(aResponse.getWriter(), generationValues, logger);
651 catch (Exception e) {
652 throw new ServletModuleFailure(e);