fixed / clean ups
[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 java.util.GregorianCalendar;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.Vector;
40
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44 import mir.entity.adapter.EntityAdapterModel;
45 import mir.entity.adapter.EntityIteratorAdapter;
46 import mir.log.LoggerWrapper;
47 import mir.misc.StringUtil;
48 import mir.servlet.ServletModule;
49 import mir.servlet.ServletModuleExc;
50 import mir.servlet.ServletModuleFailure;
51 import mir.util.CachingRewindableIterator;
52 import mir.util.HTTPRequestParser;
53 import mir.util.JDBCStringRoutines;
54 import mir.util.SQLQueryBuilder;
55 import mir.util.StringRoutines;
56 import mir.util.URLBuilder;
57 import mircoders.entity.*;
58 import mircoders.global.MirGlobal;
59 import mircoders.module.ModuleContent;
60 import mircoders.storage.DatabaseContent;
61 import mircoders.storage.DatabaseContentToTopics;
62
63 /*
64  *  ServletModuleContent -
65  *  deliver html for the article admin form.
66  *
67  * @version $Id: ServletModuleContent.java,v 1.52.2.14 2004/01/18 17:31:00 zapata Exp $
68  * @author rk, mir-coders
69  *
70  */
71
72 public class ServletModuleContent extends ServletModule
73 {
74   private static ServletModuleContent instance = new ServletModuleContent();
75   public static ServletModule getInstance() { return instance; }
76   private static ModuleContent contentModule;
77
78   private ServletModuleContent() {
79     super();
80
81     logger = new LoggerWrapper("ServletModule.Content");
82
83     try {
84       contentModule = new ModuleContent(DatabaseContent.getInstance());
85       mainModule = contentModule;
86     }
87     catch (Throwable e) {
88       logger.fatal("ServletModuleContent could not be initialized: " + e.toString());
89     }
90   }
91
92   public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
93   {
94     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
95
96     String where = requestParser.getParameter("where");
97     String order = requestParser.getParameterWithDefault("order", "webdb_create desc");
98     int offset = requestParser.getIntegerWithDefault("offset", 0);
99     String selectArticleUrl = requestParser.getParameter("selectarticleurl");
100
101     returnList(aRequest, aResponse, where, order, offset, selectArticleUrl);
102   }
103
104   public void search(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleFailure {
105     try {
106       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
107       SQLQueryBuilder queryBuilder = new SQLQueryBuilder();
108       String searchField = requestParser.getParameterWithDefault("searchfield", "");
109       String searchValue = requestParser.getParameterWithDefault("searchvalue", "").trim();
110       String searchOrder = requestParser.getParameterWithDefault("searchorder", "");
111       String searchispublished = requestParser.getParameterWithDefault("searchispublished", "");
112       String searchArticleType = requestParser.getParameterWithDefault("searcharticletype", "");
113       String selectArticleUrl = requestParser.getParameter("selectarticleurl");
114
115       if (searchValue.length()>0) {
116         if (searchField.equals("id"))
117           queryBuilder.appendAndCondition(
118             "id='"+JDBCStringRoutines.escapeStringLiteral(searchValue)+"'");
119         else if (searchField.equals("contents"))
120           queryBuilder.appendAndCondition(
121             "(lower(content_data) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')"+
122             " or (lower(description) like " + "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%')");
123         else
124           queryBuilder.appendAndCondition(
125             "lower("+ searchField + ") like " +
126             "'%" + JDBCStringRoutines.escapeStringLiteral(searchValue.toLowerCase()) + "%'");
127       }
128
129       if (searchispublished.length()>0) {
130         if (searchispublished.equals("0"))
131           queryBuilder.appendAndCondition("is_published='f'");
132         else
133           queryBuilder.appendAndCondition("is_published='t'");
134       }
135
136       if (searchArticleType.length()>0) {
137         queryBuilder.appendAndCondition("to_article_type="+Integer.parseInt(searchArticleType));
138       }
139
140       if (searchOrder.length()>0) {
141         if (searchOrder.equals("datedesc"))
142           queryBuilder.appendDescendingOrder("webdb_create");
143         else if (searchOrder.equals("dateasc"))
144           queryBuilder.appendAscendingOrder("webdb_create");
145         else if (searchOrder.equals("title"))
146           queryBuilder.appendAscendingOrder("title");
147         else if (searchOrder.equals("creator"))
148           queryBuilder.appendAscendingOrder("creator");
149       }
150
151       returnList(aRequest, aResponse, queryBuilder.getWhereClause(), queryBuilder.getOrderByClause(), 0, selectArticleUrl);
152     }
153     catch (Throwable e) {
154       throw new ServletModuleFailure(e);
155     }
156   }
157
158   public void add(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
159     editObject(aRequest, aResponse, null);
160   }
161
162   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
163   {
164     try {
165       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
166
167       String now = StringUtil.date2webdbDate(new GregorianCalendar());
168       withValues.put("date", now);
169       withValues.put("publish_path", StringUtil.webdbDate2path(now));
170       withValues.put("to_publisher", ServletHelper.getUser(aRequest).getId());
171       withValues.put("is_produced", "0");
172       if (!withValues.containsKey("is_published"))
173         withValues.put("is_published","0");
174       if (!withValues.containsKey("is_html"))
175         withValues.put("is_html","0");
176
177       String webdbCreate = (String) withValues.get("webdb_create");
178       if (webdbCreate==null || webdbCreate.trim().length()==0)
179         withValues.remove("webdb_create");
180
181       String id = mainModule.add(withValues);
182       logAdminUsage(aRequest, id, "object added");
183
184       List topics;
185
186       DatabaseContentToTopics.getInstance().setTopics(id, aRequest.getParameterValues("to_topic"));
187
188       editObject(aRequest, aResponse, id);
189     }
190     catch (Throwable e) {
191       throw new ServletModuleFailure(e);
192     }
193   }
194
195   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
196   {
197     String idParam = aRequest.getParameter("id");
198     if (idParam == null)
199       throw new ServletModuleExc("Invalid call: id not supplied ");
200     editObject(aRequest, aResponse, idParam);
201   }
202
203   /**
204    * Attaches media to an article
205    *
206    */
207   public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
208   {
209     String  mediaIdParam = aRequest.getParameter("mid");
210     String  articleId = aRequest.getParameter("articleid");
211
212     if (articleId == null || mediaIdParam==null)
213       throw new ServletModuleExc("smod content :: attach :: articleid/mid missing");
214
215     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
216       throw new ServletModuleExc("Article has been locked");
217
218     try {
219       EntityContent entContent = (EntityContent) mainModule.getById(articleId);
220       entContent.attach(mediaIdParam);
221     }
222     catch(Throwable e) {
223       throw new ServletModuleFailure(e);
224     }
225
226     logAdminUsage(aRequest, articleId, "media " + mediaIdParam + " attached");
227
228     editObject(aRequest, aResponse, articleId);
229   }
230
231   /**
232    * Deattaches media from an article
233    */
234   public void dettach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
235   {
236     String  articleId = aRequest.getParameter("articleid");
237     String  midParam = aRequest.getParameter("mid");
238     if (articleId == null)
239       throw new ServletModuleExc("smod content :: dettach :: articleid missing");
240     if (midParam == null)
241       throw new ServletModuleExc("smod content :: dettach :: mid missing");
242
243     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
244       throw new ServletModuleExc("Article has been locked");
245
246     try {
247       EntityContent entContent = (EntityContent)mainModule.getById(articleId);
248       entContent.dettach(articleId, midParam);
249     }
250     catch(Throwable e) {
251       throw new ServletModuleFailure(e);
252     }
253
254     logAdminUsage(aRequest, articleId, "media " + midParam + " deattached");
255
256     editObject(aRequest, aResponse, articleId);
257   }
258
259   /**
260    * Locks an article
261    */
262   public void lock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
263   {
264     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
265
266     String returnUrl = requestParser.getParameter("returnurl");
267
268     String idParam = aRequest.getParameter("id");
269     if (idParam == null)
270       throw new ServletModuleExc("Wrong call: (id) is missing");
271
272     EntityUsers user = ServletHelper.getUser(aRequest);
273
274     if (!MirGlobal.accessControl().article().mayLockArticle(user, idParam))
275       throw new ServletModuleExc("Unable to lock");
276
277     contentModule.lockArticle(idParam, user.getId(), false);
278
279     editObject(aRequest, aResponse, idParam);
280   }
281
282   /**
283    * Unlocks an article
284    */
285   public void unlock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
286   {
287     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
288
289     String returnUrl = requestParser.getParameter("returnurl");
290
291     String idParam = aRequest.getParameter("id");
292     if (idParam == null)
293       throw new ServletModuleExc("Wrong call: (id) is missing");
294
295     EntityUsers user = ServletHelper.getUser(aRequest);
296
297     if (!MirGlobal.accessControl().article().mayUnlockArticle(user, idParam))
298       throw new ServletModuleExc("Unable to unlock");
299
300     contentModule.unlockArticle(idParam, user.getId(), false);
301
302     editObject(aRequest, aResponse, idParam);
303   }
304
305   /**
306    * Forcelocks an article
307    */
308   public void forcelock(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
309   {
310     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
311
312     String returnUrl = requestParser.getParameter("returnurl");
313
314     String idParam = aRequest.getParameter("id");
315     if (idParam == null)
316       throw new ServletModuleExc("Wrong call: (id) is missing");
317
318     EntityUsers user = ServletHelper.getUser(aRequest);
319
320     if (!MirGlobal.accessControl().article().mayForceLockArticle(user, idParam))
321       throw new ServletModuleExc("Unable to force lock");
322
323     contentModule.lockArticle(idParam, user.getId(), true);
324
325     editObject(aRequest, aResponse, idParam);
326   }
327
328   /**
329    * Stores an article
330    */
331   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
332   {
333     try {
334       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
335
336       String returnUrl = requestParser.getParameter("returnurl");
337
338       String idParam = aRequest.getParameter("id");
339       if (idParam == null)
340         throw new ServletModuleExc("Wrong call: (id) is missing");
341
342       if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), idParam))
343         throw new ServletModuleExc("Article has been locked");
344
345       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
346
347       String content_id = aRequest.getParameter("id");
348
349       withValues.put("is_produced", "0");
350       if (!withValues.containsKey("is_published"))
351         withValues.put("is_published","0");
352       if (!withValues.containsKey("is_html"))
353         withValues.put("is_html","0");
354
355       String webdbCreate = (String) withValues.get("webdb_create");
356       if (webdbCreate==null || webdbCreate.trim().length()==0)
357         withValues.remove("webdb_create");
358
359       String id = mainModule.set(withValues);
360
361       logAdminUsage(aRequest, id, "object modified");
362
363       DatabaseContentToTopics.getInstance().setTopics(aRequest.getParameter("id"), aRequest.getParameterValues("to_topic"));
364
365       if (MirGlobal.accessControl().article().mayUnlockArticle(ServletHelper.getUser(aRequest), idParam) &&
366          (requestParser.getParameterWithDefault("unlock", "0").equals("1"))) {
367         contentModule.unlockArticle(id, ServletHelper.getUser(aRequest).getId(), false);
368       }
369
370       editObject(aRequest, aResponse, idParam);
371     }
372     catch (Throwable e) {
373       throw new ServletModuleFailure(e);
374     }
375   }
376
377
378   /**
379    * Returns the basic article editing form.
380    *
381    * @param id identifier of the article. <code>null</code>, means show an
382    *     empty form to add a new article.
383    */
384   public void editObject(HttpServletRequest aRequest, HttpServletResponse aResponse, String id)
385       throws ServletModuleExc {
386     try {
387       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
388       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
389       EntityAdapterModel model = MirGlobal.localizer().dataModel().adapterModel();
390       Map article;
391       URLBuilder urlBuilder = new URLBuilder();
392
393       urlBuilder.setValue("module", "Content");
394       urlBuilder.setValue("do", "edit");
395       urlBuilder.setValue("id", id);
396       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
397
398       if (id!=null) {
399         responseData.put("new", Boolean.FALSE);
400         article = model.makeEntityAdapter("content", mainModule.getById(id));
401
402         EntityUsers user = ServletHelper.getUser(aRequest);
403
404         responseData.put("mayEdit", new Boolean(MirGlobal.accessControl().article().mayEditArticle(user, id)));
405         responseData.put("mayLock", new Boolean(MirGlobal.accessControl().article().mayLockArticle(user, id)));
406         responseData.put("mayForceLock", new Boolean(MirGlobal.accessControl().article().mayForceLockArticle(user, id)));
407         responseData.put("mayUnlock", new Boolean(MirGlobal.accessControl().article().mayUnlockArticle(user, id)));
408       }
409       else {
410         List fields = DatabaseContent.getInstance().getFields();
411         responseData.put("new", Boolean.TRUE);
412         article = new HashMap();
413         Iterator i = fields.iterator();
414         while (i.hasNext()) {
415           article.put(i.next(), null);
416         }
417
418         article.put("to_topics", null);
419
420         MirGlobal.localizer().adminInterface().initializeArticle(article);
421
422         responseData.put("mayEdit", Boolean.TRUE);
423         responseData.put("mayLock", Boolean.FALSE);
424         responseData.put("mayForceLock", Boolean.FALSE);
425         responseData.put("mayUnlock", Boolean.FALSE);
426       }
427       responseData.put("article", article);
428
429       List topicsList = new Vector();
430
431       String[] topicCategories = configuration.getStringArray("Mir.Localizer.Admin.TopicLists");
432
433       if (topicCategories.length==0 ) {
434         Map categoryMap = new HashMap();
435         categoryMap.put("key", "topic");
436         categoryMap.put("listtype", "0");
437         categoryMap.put("listparameter", "3");
438         categoryMap.put("items",
439                         new EntityIteratorAdapter("", "title",
440             20, MirGlobal.localizer().dataModel().adapterModel(), "topic"));
441         topicsList.add(categoryMap);
442       }
443       else
444       {
445
446         for (int i = 0; i < topicCategories.length; i++) {
447           try {
448             Map categoryMap = new HashMap();
449             List parts = StringRoutines.splitString(topicCategories[i], ":");
450             String key = null;
451             String listtype = "0";
452             String listparameter = "5";
453             String where = "";
454             String order = "";
455
456             if (parts.size() > 0)
457               key = (String) parts.get(0);
458             if (parts.size() > 1)
459               listtype = (String) parts.get(1);
460             if (parts.size() > 2)
461               listparameter = (String) parts.get(2);
462             if (parts.size() > 3)
463               where = (String) parts.get(3);
464             if (parts.size() > 4)
465               order = (String) parts.get(4);
466
467             if (key != null) {
468               categoryMap.put("key", key);
469               categoryMap.put("listtype", listtype);
470               categoryMap.put("listparameter", listparameter);
471               categoryMap.put("items",
472                               new EntityIteratorAdapter(where, order,
473                   20, MirGlobal.localizer().dataModel().adapterModel(), "topic"));
474               topicsList.add(categoryMap);
475             }
476           }
477           catch (Throwable t) {
478             logger.error("error while preparing topics: " + t.toString());
479           }
480         }
481       }
482
483       responseData.put("topics", topicsList);
484
485       responseData.put("returnurl", requestParser.getParameter("returnurl"));
486       responseData.put("thisurl", urlBuilder.getQuery());
487
488       ServletHelper.generateResponse(aResponse.getWriter(), responseData, editGenerator);
489     }
490     catch (Throwable e) {
491       throw new ServletModuleFailure(e);
492     }
493   }
494
495   public void returnList(HttpServletRequest aRequest, HttpServletResponse aResponse,
496      String aWhereClause, String anOrderByClause, int anOffset) throws ServletModuleExc {
497     this.returnList(aRequest, aResponse, aWhereClause, anOrderByClause, anOffset, null);
498   }
499
500   public void returnList(
501        HttpServletRequest aRequest,
502        HttpServletResponse aResponse,
503        String aWhereClause,
504        String anOrderByClause,
505        int anOffset,
506        String aSelectArticleUrl) throws ServletModuleExc {
507
508     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
509     URLBuilder urlBuilder = new URLBuilder();
510     EntityAdapterModel model;
511     int count;
512
513     try {
514       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
515       model = MirGlobal.localizer().dataModel().adapterModel();
516
517       Object articleList =
518           new CachingRewindableIterator(
519             new EntityIteratorAdapter( aWhereClause, anOrderByClause, nrEntitiesPerListPage,
520                MirGlobal.localizer().dataModel().adapterModel(), "content", nrEntitiesPerListPage, anOffset)
521       );
522
523       responseData.put("nexturl", null);
524       responseData.put("prevurl", null);
525
526       count=mainModule.getSize(aWhereClause);
527
528       urlBuilder.setValue("module", "Content");
529       urlBuilder.setValue("do", "list");
530       urlBuilder.setValue("where", aWhereClause);
531       urlBuilder.setValue("order", anOrderByClause);
532
533
534       urlBuilder.setValue("searchfield", requestParser.getParameter("searchfield"));
535       urlBuilder.setValue("searchvalue", requestParser.getParameter("searchvalue"));
536       urlBuilder.setValue("searchispublished", requestParser.getParameter("searchispublished"));
537       urlBuilder.setValue("searchorder", requestParser.getParameter("searchorder"));
538       urlBuilder.setValue("searcharticletype", requestParser.getParameter("searcharticletype"));
539       urlBuilder.setValue("selectarticleurl", aSelectArticleUrl);
540
541       responseData.put("searchfield", requestParser.getParameter("searchfield"));
542       responseData.put("searchvalue", requestParser.getParameter("searchvalue"));
543       responseData.put("searchispublished", requestParser.getParameter("searchispublished"));
544       responseData.put("searchorder", requestParser.getParameter("searchorder"));
545       responseData.put("searcharticletype", requestParser.getParameter("searcharticletype"));
546       responseData.put("selectarticleurl", aSelectArticleUrl);
547
548       urlBuilder.setValue("offset", anOffset);
549       responseData.put("offset" , new Integer(anOffset).toString());
550       responseData.put("thisurl" , urlBuilder.getQuery());
551
552       if (count>=anOffset+nrEntitiesPerListPage) {
553         urlBuilder.setValue("offset", (anOffset + nrEntitiesPerListPage));
554         responseData.put("nexturl" , urlBuilder.getQuery());
555       }
556
557       if (anOffset>0) {
558         urlBuilder.setValue("offset", Math.max(anOffset - nrEntitiesPerListPage, 0));
559         responseData.put("prevurl" , urlBuilder.getQuery());
560       }
561
562       responseData.put("articles", articleList);
563
564       responseData.put("from" , Integer.toString(anOffset+1));
565       responseData.put("count", Integer.toString(count));
566       responseData.put("to", Integer.toString(Math.min(anOffset+nrEntitiesPerListPage, count)));
567       responseData.put("offset" , Integer.toString(anOffset));
568       responseData.put("order", anOrderByClause);
569       responseData.put("where" , aWhereClause);
570
571       ServletHelper.generateResponse(aResponse.getWriter(), responseData, listGenerator);
572     }
573     catch (Throwable e) {
574       throw new ServletModuleFailure(e);
575     }
576   }
577
578   public void selectparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
579   {
580     try {
581       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
582       URLBuilder urlBuilder = new URLBuilder();
583
584       urlBuilder.setValue("module", "Content");
585       urlBuilder.setValue("do", "setparent");
586       urlBuilder.setValue("childid", requestParser.getParameter("id"));
587       urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
588
589       returnList(aRequest, aResponse, "", "", 0, urlBuilder.getQuery());
590     }
591     catch (Throwable e) {
592       throw new ServletModuleFailure(e);
593     }
594   }
595
596   public void listchildren(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
597   {
598     try {
599       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
600       String articleId = requestParser.getParameter("article_id");
601
602       if (articleId == null)
603         throw new ServletModuleExc("ServletModuleContent.listchildren: article_id not set!");
604
605       returnList(aRequest, aResponse, "to_content = " + articleId, "", 0, null);
606     }
607     catch (Throwable e) {
608       throw new ServletModuleFailure(e);
609     }
610   }
611
612   public void setparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
613   {
614     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
615     String articleId = aRequest.getParameter("childid");
616     String parentId  = aRequest.getParameter("id");
617     String returnUrl = aRequest.getParameter("returnurl");
618
619     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
620       throw new ServletModuleExc("Article has been locked");
621
622     try {
623       EntityContent article = (EntityContent) mainModule.getById(articleId);
624       article.setFieldValue("to_content", parentId);
625       article.setProduced(false);
626       article.update();
627       logAdminUsage(aRequest, articleId, "parent set to " + parentId);
628     }
629     catch(Throwable e) {
630       logger.error("ServletModuleContent.setparent: " + e.getMessage());
631       throw new ServletModuleFailure(e);
632     }
633
634     redirect(aResponse, returnUrl);
635   }
636
637   public void clearparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
638   {
639     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
640     String articleId = requestParser.getParameter("id");
641     String returnUrl = requestParser.getParameter("returnurl");
642
643     try {
644       EntityContent article = (EntityContent) mainModule.getById(articleId);
645       article.setFieldValue("to_content", "");
646       article.setProduced(false);
647       article.update();
648       logAdminUsage(aRequest, articleId, "parent cleared");
649     }
650     catch(Throwable e) {
651       e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
652       logger.error("ServletModuleContent.clearparent: " + e.getMessage());
653
654       throw new ServletModuleFailure("ServletModuleContent.clearparent: " + e.getMessage(), e);
655     }
656
657     redirect(aResponse, returnUrl);
658   }
659 }