1
4 package org.torweg.pulse.site.content.admin;
5
6 import java.io.StringReader;
7 import java.util.GregorianCalendar;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.Set;
12 import java.util.TimeZone;
13 import java.util.TreeMap;
14
15 import net.sf.json.JSONArray;
16 import net.sf.json.JSONObject;
17
18 import org.hibernate.HibernateException;
19 import org.hibernate.Session;
20 import org.hibernate.Transaction;
21 import org.hibernate.search.FullTextSession;
22 import org.jdom.Document;
23 import org.jdom.input.SAXBuilder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.torweg.pulse.annotations.Action;
27 import org.torweg.pulse.annotations.Groups;
28 import org.torweg.pulse.annotations.Permission;
29 import org.torweg.pulse.annotations.RequireToken;
30 import org.torweg.pulse.bundle.Bundle;
31 import org.torweg.pulse.bundle.Controller;
32 import org.torweg.pulse.configuration.ConfigBean;
33 import org.torweg.pulse.configuration.DeprecatedConfigurable;
34 import org.torweg.pulse.invocation.lifecycle.Lifecycle;
35 import org.torweg.pulse.service.PulseException;
36 import org.torweg.pulse.service.event.JSONOutputEvent;
37 import org.torweg.pulse.service.event.XSLTOutputEvent;
38 import org.torweg.pulse.service.request.Command;
39 import org.torweg.pulse.service.request.Parameter;
40 import org.torweg.pulse.service.request.ServiceRequest;
41 import org.torweg.pulse.site.View;
42 import org.torweg.pulse.site.content.AbstractBasicContent;
43 import org.torweg.pulse.site.content.Attachment;
44 import org.torweg.pulse.site.content.Content;
45 import org.torweg.pulse.site.content.ContentLocalizationMap;
46 import org.torweg.pulse.site.content.InconsistentLocalizationException;
47 import org.torweg.pulse.site.map.SitemapNode;
48 import org.torweg.pulse.util.adminui.FCKEditorResult;
49 import org.torweg.pulse.util.adminui.JSONCommunicationUtils;
50 import org.torweg.pulse.util.adminui.RightsCheckUtils;
51 import org.torweg.pulse.util.time.Duration;
52 import org.torweg.pulse.util.xml.XMLConverter;
53 import org.torweg.pulse.vfs.VirtualFile;
54
55
63 public class AbstractBasicContentEditor extends Controller implements
64 DeprecatedConfigurable {
65
66
69 protected static final Logger LOGGER = LoggerFactory
70 .getLogger(AbstractBasicContentEditor.class);
71
72
75 private AbstractBasicContentEditorConfig config;
77
88 @RequireToken
89 @Action(value = "initSummaryEditor", generate = true)
90 @Permission("viewAbstractBasicContent")
91 @Groups(values = { "ContentAdministrator" })
92 public final FCKEditorResult initSummaryEditor(final Bundle bundle,
93 final ServiceRequest request) {
94
95 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
97 .getFirstValue());
98
99 Session s = Lifecycle.getHibernateDataSource().createNewSession();
101 Transaction tx = s.beginTransaction();
102 AbstractBasicContent content = null;
103
104 try {
105
106 content = (AbstractBasicContent) s.get(Content.class, contentId);
108
109 tx.commit();
110 } catch (Exception e) {
111 tx.rollback();
112 throw new PulseException(
113 "AbstractBasicContentContentEditor.initSummaryEditor.failed: "
114 + e.getLocalizedMessage(), e);
115 } finally {
116 s.close();
117 }
118
119 FCKEditorResult result = new FCKEditorResult();
121 if (content != null) {
122 result.setContentLocale(content.getLocale());
123 result.setFCKContent(content.getSummary());
124 }
125 XSLTOutputEvent event = new XSLTOutputEvent(this.config.getFCKAjaxXSL());
126 event.setStopEvent(true);
127 request.getEventManager().addEvent(event);
128 return result;
129 }
130
131
138 @RequireToken
139 @Action(value = "saveSummary", generate = true)
140 @Permission("editAbstractBasicContent")
141 @Groups(values = { "ContentAdministrator" })
142 public final void saveSummary(final Bundle bundle,
143 final ServiceRequest request) {
144
145 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
147 .getFirstValue());
148 String value = request.getCommand().getParameter("value")
149 .getFirstValue();
150
151 Session s = Lifecycle.getHibernateDataSource().createNewSession();
153 Transaction tx = s.beginTransaction();
154 AbstractBasicContent content = null;
155 JSONObject error = null;
157
158 try {
159
160 content = (AbstractBasicContent) s.get(Content.class, contentId);
162
163 error = RightsCheckUtils.checkUserAgainstLocale(error, bundle,
165 request, content.getLocale());
166
167 if (error == null) {
168
169 content.setSummary(buildDocument(value).getRootElement());
171
172 s.saveOrUpdate(content);
174 }
175
176 content.updateAssociatedVirtualFiles();
178
179 AbstractBasicContentEditor.initHibernateSearchFix(s, content);
181
182 tx.commit();
183
184 } catch (Exception e) {
185 tx.rollback();
186 throw new PulseException(
187 "AbstractBasicContentEditor.saveSummary.failed"
188 + e.getLocalizedMessage(), e);
189 } finally {
190 s.close();
191 }
192
193 if (error == null) {
195 JSONCommunicationUtils.jsonSuccessMessage(request);
196 } else {
197 JSONCommunicationUtils.jsonErrorMessage(request, error);
198 }
199 }
200
201
208 @RequireToken
209 @Action(value = "loadSummary", generate = true)
210 @Permission("viewAbstractBasicContent")
211 @Groups(values = { "ContentAdministrator" })
212 public final AbstractBasicContentEditorResult loadSummary(
213 final Bundle bundle, final ServiceRequest request) {
214
215 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
217 .getFirstValue());
218
219 Session s = Lifecycle.getHibernateDataSource().createNewSession();
221 Transaction tx = s.beginTransaction();
222 AbstractBasicContent content = null;
223
224 try {
225
226 content = (AbstractBasicContent) s.get(Content.class, contentId);
228
229 tx.commit();
230
231 } catch (Exception e) {
232 tx.rollback();
233 throw new PulseException(
234 "AbstractBasicContentEditor.loadSummary.failed"
235 + e.getLocalizedMessage(), e);
236 } finally {
237 s.close();
238 }
239
240 AbstractBasicContentEditorResult result = new AbstractBasicContentEditorResult();
242 if (content != null) {
243 result.setContent(content);
244 }
245 XSLTOutputEvent event = new XSLTOutputEvent(
246 this.config.getAjaxSummaryXSL());
247 event.setStopEvent(true);
248 request.getEventManager().addEvent(event);
249 return result;
250 }
251
252
263 @RequireToken
264 @Action(value = "initContentLocalizationMap", generate = true)
265 @Permission("viewLocalizationMaps")
266 @Groups(values = { "ContentAdministrator" })
267 public final AbstractBasicContentEditorResult loadContentLocalizationMap(
268 final Bundle bundle, final ServiceRequest request) {
269
270 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
272 .getFirstValue());
273
274 Session s = Lifecycle.getHibernateDataSource().createNewSession();
276 Transaction tx = s.beginTransaction();
277 AbstractBasicContentEditorResult result = new AbstractBasicContentEditorResult();
278
279 try {
280
281 AbstractBasicContent content = (AbstractBasicContent) s.get(
283 Content.class, contentId);
284
285 content.getLocalizationMap().keySet().size();
287 content.getLocalizationMap().values().size();
288
289 result.setContent(content);
290
291 tx.commit();
292
293 } catch (Exception e) {
294 tx.rollback();
295 throw new PulseException(
296 "AbstractBasicContentEditor.loadContentLocalizationMap.failed"
297 + e.getLocalizedMessage(), e);
298 } finally {
299 s.close();
300 }
301
302 LOGGER.debug("{} ### {} ### ", bundle.getName(), this.config);
304 XSLTOutputEvent event = new XSLTOutputEvent(
305 this.config.getAjaxContentLocalizationMapXSL());
306 event.setStopEvent(true);
307 request.getEventManager().addEvent(event);
308 return result;
309
310 }
311
312
321 @RequireToken
322 @Action(value = "contentLocalizationMapAdd", generate = true)
323 @Permission("editLocalizationMaps")
324 @Groups(values = { "ContentAdministrator" })
325 public final void addToLocalizationMap(final Bundle bundle,
326 final ServiceRequest request) {
327
328 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
330 .getFirstValue());
331 Long addId = Long.parseLong(request.getCommand().getParameter("addid")
332 .getFirstValue());
333
334 Session s = Lifecycle.getHibernateDataSource().createNewSession();
336 Transaction tx = s.beginTransaction();
337
338 try {
339
340 AbstractBasicContent content = (AbstractBasicContent) s.get(
342 Content.class, contentId);
343
344 JSONObject error = RightsCheckUtils.checkUserAgainstLocale(bundle,
345 request, content.getLocale());
346
347 if (error != null) {
348 JSONCommunicationUtils.jsonErrorMessage(request, error);
349 tx.rollback();
350 return;
351 }
352
353 AbstractBasicContent addContent = (AbstractBasicContent) s.get(
355 Content.class, addId);
356
357 if (hasLocaleClashes(content, addContent)) {
359 error = new JSONObject();
360 error.put("e", "duplicate locales");
361 JSONCommunicationUtils.jsonErrorMessage(request, error);
362 tx.rollback();
363 return;
364 }
365 if (content.getLocale().equals(addContent.getLocale())) {
366 error = new JSONObject();
367 error.put("e", "sameLocalesError");
368 JSONCommunicationUtils.jsonErrorMessage(request, error);
369 tx.rollback();
370 return;
371 }
372
373 try {
374 buildUnionLocalizationMap(s, tx, content, addContent);
375 } catch (InconsistentLocalizationException e) {
376 error = new JSONObject();
377 error.put("e", e.getLocalizedMessage());
378 JSONCommunicationUtils.jsonErrorMessage(request, error);
379 tx.rollback();
380 return;
381 } catch (HibernateException e) {
382 tx.rollback();
383 tx = s.beginTransaction();
384 content = (AbstractBasicContent) s.get(Content.class,
385 content.getId());
386 addContent = (AbstractBasicContent) s.get(Content.class,
387 addContent.getId());
388 buildUnionLocalizationMap(s, tx, addContent, content);
389 }
390
391 } catch (Exception e) {
392 tx.rollback();
393 LOGGER.error(e.getLocalizedMessage(), e);
394 JSONObject error = new JSONObject();
395 if (e.getCause() != null) {
396 error.put("e", e.getMessage() + "<br/>"
397 + e.getCause().getMessage());
398 } else {
399 error.put("e", e.getMessage());
400 }
401 JSONCommunicationUtils.jsonErrorMessage(request, error);
402 return;
403 } finally {
404 s.close();
405 }
406
407 JSONCommunicationUtils.jsonSuccessMessage(request);
409 }
410
411
426 private void buildUnionLocalizationMap(final Session s,
427 final Transaction tx, final AbstractBasicContent dstContent,
428 final AbstractBasicContent srcContent) {
429 ContentLocalizationMap locMap = dstContent.getLocalizationMap();
431
432 ContentLocalizationMap delLocMap = srcContent.getLocalizationMap();
435
436 Set<Content> srcContents = new HashSet<Content>();
438 srcContents.addAll(delLocMap.values());
439 for (Content content : srcContents) {
440 locMap.put(content.getLocale(), content);
441 }
442 s.delete(delLocMap);
443 s.saveOrUpdate(srcContent);
444
445 tx.commit();
446 }
447
448
460 private boolean hasLocaleClashes(final AbstractBasicContent content1,
461 final AbstractBasicContent content2) {
462 Set<Locale> c2Locales = new HashSet<Locale>();
463 c2Locales.addAll(content2.getLocalizationMap().keySet());
464 for (Locale c1Locale : content1.getLocalizationMap().keySet()) {
465 if (c2Locales.contains(c1Locale)) {
466 return true;
467 }
468 }
469 return false;
470 }
471
472
481 @RequireToken
482 @Action(value = "contentLocalizationMapRemove", generate = true)
483 @Permission("editLocalizationMaps")
484 @Groups(values = { "ContentAdministrator" })
485 public final void removeFromLocalizationMap(final Bundle bundle,
486 final ServiceRequest request) {
487
488 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
490 .getFirstValue());
491 Long removeId = Long.parseLong(request.getCommand()
492 .getParameter("removeid").getFirstValue());
493
494 Session s = Lifecycle.getHibernateDataSource().createNewSession();
496 Transaction tx = s.beginTransaction();
497 JSONObject error = null;
499
500 try {
501
502 AbstractBasicContent content = (AbstractBasicContent) s.get(
504 Content.class, contentId);
505
506 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
507 content.getLocale());
508
509 if (error == null) {
510
511 AbstractBasicContent removeContent = (AbstractBasicContent) s
513 .get(Content.class, removeId);
514
515 ContentLocalizationMap locMap = content.getLocalizationMap();
517
518 locMap.remove(removeContent.getLocale());
520
521 s.saveOrUpdate(removeContent);
523 s.saveOrUpdate(content);
524
525 tx.commit();
526
527 }
528
529 } catch (Exception e) {
530 tx.rollback();
531 throw new PulseException(
532 "AbstractBasicContentEditor.removeFromLocalizationMap.failed"
533 + e.getLocalizedMessage(), e);
534 } finally {
535 s.close();
536 }
537
538 if (error == null) {
540 JSONCommunicationUtils.jsonSuccessMessage(request);
541 } else {
542 JSONCommunicationUtils.jsonErrorMessage(request, error);
543 }
544
545 }
546
547
555 @RequireToken
556 @Action(value = "loadSitemapNodesForContent", generate = true)
557 @Permission("viewAbstractBasicContent")
558 @Groups(values = { "ContentAdministrator" })
559 public final void findSitemapNodesForContent(final Bundle bundle,
560 final ServiceRequest request) {
561
562 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
564 .getFirstValue());
565
566 Session s = Lifecycle.getHibernateDataSource().createNewSession();
568 Transaction tx = s.beginTransaction();
569 JSONArray responseArray = new JSONArray();
570 JSONObject error = null;
572
573 try {
574
575 AbstractBasicContent content = (AbstractBasicContent) s.get(
577 Content.class, contentId);
578
579 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
580 content.getLocale());
581
582 if (error == null) {
583
584 @SuppressWarnings("unchecked")
586 List<SitemapNode> sitemapNodes = (List<SitemapNode>) s
587 .createQuery(
588 "from SitemapNode sn where sn.view.content.id=?")
589 .setLong(0, contentId).list();
590
591 for (SitemapNode sn : sitemapNodes) {
593 JSONObject snJSON = sn.toJSON();
594 JSONArray expandInfo = buildExpandInfoArray(sn);
595 snJSON.put("expandInfo", expandInfo);
596 responseArray.add(snJSON);
597 }
598
599 }
600 tx.commit();
601
602 } catch (Exception e) {
603 tx.rollback();
604 throw new PulseException(
605 "AbstractBasicContentEditor.findSitemapNodesForContent.failed"
606 + e.getLocalizedMessage(), e);
607 } finally {
608 s.close();
609 }
610
611 if (error == null) {
613 JSONCommunicationUtils.jsonSuccessMessage(request, "sitemapNodes",
614 responseArray);
615 } else {
616 JSONCommunicationUtils.jsonErrorMessage(request, error);
617 }
618 }
619
620
628 @RequireToken
629 @Action(value = "loadAttachmentsForContent", generate = true)
630 @Permission("viewAbstractBasicContent")
631 @Groups(values = { "ContentAdministrator" })
632 public final void loadAttachmentsForContent(final Bundle bundle,
633 final ServiceRequest request) {
634
635 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
637 .getFirstValue());
638
639 Session s = Lifecycle.getHibernateDataSource().createNewSession();
641 Transaction tx = s.beginTransaction();
642 JSONArray responseArray = new JSONArray();
643 JSONObject error = null;
645
646 try {
647
648 AbstractBasicContent content = (AbstractBasicContent) s.get(
650 Content.class, contentId);
651
652 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
653 content.getLocale());
654
655 if (error == null) {
656
657 TreeMap<String, Attachment> sortMap = new TreeMap<String, Attachment>();
659 for (Attachment att : content.getAttachments()) {
660 sortMap.put(att.getName() + "__" + att.getId(), att);
661 }
662
663 for (Attachment att : sortMap.values()) {
665 responseArray.add(att.toJSON());
666 }
667
668 }
669
670 tx.commit();
671
672 } catch (Exception e) {
673 tx.rollback();
674 throw new PulseException(
675 "AbstractBasicContentEditor.loadAttachmentsForContent.failed"
676 + e.getLocalizedMessage(), e);
677 } finally {
678 s.close();
679 }
680
681 if (error == null) {
683 request.getEventManager().addEvent(
684 new JSONOutputEvent(responseArray));
685 } else {
686 JSONCommunicationUtils.jsonErrorMessage(request, error);
687 }
688 }
689
690
698 @RequireToken
699 @Action(value = "addAttachmentToContent", generate = true)
700 @Permission("editAbstractBasicContent")
701 @Groups(values = { "ContentAdministrator" })
702 public final void addAttachmentToContent(final Bundle bundle,
703 final ServiceRequest request) {
704
705 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
707 .getFirstValue());
708 Long vfsId = Long.parseLong(request.getCommand().getParameter("vfsid")
709 .getFirstValue());
710 String name = request.getCommand().getParameter("name").getFirstValue();
711
712 Session s = Lifecycle.getHibernateDataSource().createNewSession();
714 Transaction tx = s.beginTransaction();
715 JSONObject error = null;
717
718 try {
719
720 AbstractBasicContent content = (AbstractBasicContent) s.get(
722 Content.class, contentId);
723
724 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
725 content.getLocale());
726
727 if (error == null && name.equals("")) {
729 error = new JSONObject();
730 error.put("e", "nameCannotBeEmty");
731 }
732
733 if (error == null) {
734
735 Attachment attachment = new Attachment((VirtualFile) s.get(
737 VirtualFile.class, vfsId), name);
738
739 content.getAttachments().add(attachment);
741
742 s.saveOrUpdate(content);
744
745 }
746
747 tx.commit();
748
749 } catch (Exception e) {
750 tx.rollback();
751 throw new PulseException(
752 "AbstractBasicContentEditor.addAttachmentToContent.failed"
753 + e.getLocalizedMessage(), e);
754 } finally {
755 s.close();
756 }
757
758 if (error == null) {
760 JSONCommunicationUtils.jsonSuccessMessage(request);
761 } else {
762 JSONCommunicationUtils.jsonErrorMessage(request, error);
763 }
764 }
765
766
781 @RequireToken
782 @Action(value = "editAttachmentOfContent", generate = true)
783 @Permission("editAbstractBasicContent")
784 @Groups(values = { "ContentAdministrator" })
785 public final AbstractBasicContentEditorResult editAttachmentOfContent(
786 final Bundle bundle, final ServiceRequest request) {
787
788 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
790 .getFirstValue());
791 Long attachmentId = Long.parseLong(request.getCommand()
792 .getParameter("attachmentid").getFirstValue());
793
794 Session s = Lifecycle.getHibernateDataSource().createNewSession();
796 Transaction tx = s.beginTransaction();
797 AbstractBasicContentEditorResult result = new AbstractBasicContentEditorResult();
798 JSONObject error = null;
800
801 try {
802
803 AbstractBasicContent content = (AbstractBasicContent) s.get(
805 Content.class, contentId);
806
807 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
809 content.getLocale());
810
811 if (error == null) {
812 result.setContent(content);
814 result.setAttachment((Attachment) s.get(Attachment.class,
816 attachmentId));
817 }
818
819 tx.commit();
820
821 } catch (Exception e) {
822 tx.rollback();
823 throw new PulseException(
824 "AbstractBasicContentEditor.editAttachmentOfContent.failed: "
825 + e.getLocalizedMessage(), e);
826 } finally {
827 s.close();
828 }
829
830 result.setMode(2);
832
833 XSLTOutputEvent event = new XSLTOutputEvent(
834 this.config.getAttachmentsAjaxXSL());
835 event.setStopEvent(true);
836 request.getEventManager().addEvent(event);
837 return result;
838 }
839
840
848 @RequireToken
849 @Action(value = "removeAttachmentFromContent", generate = true)
850 @Permission("editAbstractBasicContent")
851 @Groups(values = { "ContentAdministrator" })
852 public final void removeAttachmentFromContent(final Bundle bundle,
853 final ServiceRequest request) {
854
855 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
857 .getFirstValue());
858 Long attachmentId = Long.parseLong(request.getCommand()
859 .getParameter("attachmentid").getFirstValue());
860
861 Session s = Lifecycle.getHibernateDataSource().createNewSession();
863 Transaction tx = s.beginTransaction();
864 JSONObject error = null;
866
867 try {
868
869 AbstractBasicContent content = (AbstractBasicContent) s.get(
871 Content.class, contentId);
872
873 error = RightsCheckUtils.checkUserAgainstLocale(bundle, request,
875 content.getLocale());
876
877 if (error == null) {
878
879 Attachment toDelete = (Attachment) s.get(Attachment.class,
881 attachmentId);
882
883 content.getAttachments().remove(toDelete);
885
886 s.saveOrUpdate(content);
888 s.delete(toDelete);
889
890 }
891
892 tx.commit();
893
894 } catch (Exception e) {
895 tx.rollback();
896 throw new PulseException(
897 "AbstractBasicContentEditor.removeAttachmentFromContent.failed: "
898 + e.getLocalizedMessage(), e);
899 } finally {
900 s.close();
901 }
902
903 if (error == null) {
905 JSONCommunicationUtils.jsonSuccessMessage(request);
906 } else {
907 JSONCommunicationUtils.jsonErrorMessage(request, error);
908 }
909 }
910
911
922 @RequireToken
923 @Action(value = "initAttachmentDescriptionEditor", generate = true)
924 @Permission("editAbstractBasicContent")
925 @Groups(values = { "ContentAdministrator" })
926 public final FCKEditorResult initAttachmentDescriptionEditor(
927 final Bundle bundle, final ServiceRequest request) {
928
929 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
931 .getFirstValue());
932 Long attachmentId = Long.parseLong(request.getCommand()
933 .getParameter("attachmentid").getFirstValue());
934
935 Session s = Lifecycle.getHibernateDataSource().createNewSession();
937 Transaction tx = s.beginTransaction();
938 AbstractBasicContent content = null;
939 Attachment attachment = null;
940
941 try {
942
943 content = (AbstractBasicContent) s.get(Content.class, contentId);
945 attachment = (Attachment) s.get(Attachment.class, attachmentId);
946
947 tx.commit();
948 } catch (Exception e) {
949 tx.rollback();
950 throw new PulseException(
951 "AbstractBasicContentEditor.initAttachmentDescriptionEditor.failed: "
952 + e.getLocalizedMessage(), e);
953 } finally {
954 s.close();
955 }
956
957 FCKEditorResult result = new FCKEditorResult();
959 if (content != null) {
960 result.setContentLocale(content.getLocale());
961 result.setFCKContent(attachment.getDescriptionText());
962 }
963 XSLTOutputEvent event = new XSLTOutputEvent(this.config.getFCKAjaxXSL());
964 event.setStopEvent(true);
965 request.getEventManager().addEvent(event);
966 return result;
967 }
968
969
980 @RequireToken
981 @Action(value = "loadAttachmentDescription", generate = true)
982 @Permission("editAbstractBasicContent")
983 @Groups(values = { "ContentAdministrator" })
984 public final FCKEditorResult loadAttachmentDescription(final Bundle bundle,
985 final ServiceRequest request) {
986
987 Long attachmentId = Long.parseLong(request.getCommand()
989 .getParameter("attachmentid").getFirstValue());
990
991 Session s = Lifecycle.getHibernateDataSource().createNewSession();
993 Transaction tx = s.beginTransaction();
994 Attachment attachment = null;
995
996 try {
997
998 attachment = (Attachment) s.get(Attachment.class, attachmentId);
1000
1001 tx.commit();
1002 } catch (Exception e) {
1003 tx.rollback();
1004 throw new PulseException(
1005 "AbstractBasicContentEditor.loadAttachmentDescription.failed: "
1006 + e.getLocalizedMessage(), e);
1007 } finally {
1008 s.close();
1009 }
1010
1011 FCKEditorResult result = new FCKEditorResult();
1013 if (attachment != null) {
1014 result.setPanelReloadContent(attachment.getDescription());
1015 }
1016 XSLTOutputEvent event = new XSLTOutputEvent(this.config.getFCKAjaxXSL());
1017 event.setStopEvent(true);
1018 request.getEventManager().addEvent(event);
1019 return result;
1020 }
1021
1022
1029 @RequireToken
1030 @Action(value = "saveAttachmentDescriptionEditor", generate = true)
1031 @Permission("editAbstractBasicContent")
1032 @Groups(values = { "ContentAdministrator" })
1033 public final void saveAttachmentDescription(final Bundle bundle,
1034 final ServiceRequest request) {
1035
1036 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
1038 .getFirstValue());
1039 Long attachmentId = Long.parseLong(request.getCommand()
1040 .getParameter("attachmentid").getFirstValue());
1041 String value = request.getCommand().getParameter("value")
1042 .getFirstValue();
1043
1044 Session s = Lifecycle.getHibernateDataSource().createNewSession();
1046 Transaction tx = s.beginTransaction();
1047 AbstractBasicContent content = null;
1048 JSONObject error = null;
1050
1051 try {
1052
1053 content = (AbstractBasicContent) s.get(Content.class, contentId);
1055
1056 error = RightsCheckUtils.checkUserAgainstLocale(error, bundle,
1058 request, content.getLocale());
1059
1060 if (error == null) {
1061
1062 Attachment attachment = (Attachment) s.get(Attachment.class,
1064 attachmentId);
1065
1066 attachment
1068 .setDescription(buildDocument(value).getRootElement());
1069
1070 s.saveOrUpdate(attachment);
1072 }
1073
1074 tx.commit();
1075
1076 } catch (Exception e) {
1077 tx.rollback();
1078 throw new PulseException(
1079 "AbstractBasicContentEditor.saveAttachmentDescriptionEditor.failed"
1080 + e.getLocalizedMessage(), e);
1081 } finally {
1082 s.close();
1083 }
1084
1085 if (error == null) {
1087 JSONCommunicationUtils.jsonSuccessMessage(request);
1088 } else {
1089 JSONCommunicationUtils.jsonErrorMessage(request, error);
1090 }
1091 }
1092
1093
1108 @RequireToken
1109 @Action(value = "initFileBrowserForAttachmentsForContent", generate = true)
1110 @Permission("editAbstractBasicContent")
1111 @Groups(values = { "ContentAdministrator" })
1112 public final AbstractBasicContentEditorResult initFileBrowserForAttachmentsForContent(
1113 final Bundle bundle, final ServiceRequest request) {
1114
1115 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
1117 .getFirstValue());
1118
1119 Session s = Lifecycle.getHibernateDataSource().createNewSession();
1121 Transaction tx = s.beginTransaction();
1122 AbstractBasicContent content = null;
1123
1124 try {
1125
1126 content = (AbstractBasicContent) s.get(Content.class, contentId);
1128
1129 tx.commit();
1130 } catch (Exception e) {
1131 tx.rollback();
1132 throw new PulseException(
1133 "AbstractBasicContentEditor.initFileBrowserForAttachmentsForContent.failed: "
1134 + e.getLocalizedMessage(), e);
1135 } finally {
1136 s.close();
1137 }
1138
1139 AbstractBasicContentEditorResult result = new AbstractBasicContentEditorResult();
1141 if (content != null) {
1142 result.setContent(content);
1143 }
1144
1145 result.setMode(1);
1147
1148 XSLTOutputEvent event = new XSLTOutputEvent(
1149 this.config.getAttachmentsAjaxXSL());
1150 event.setStopEvent(true);
1151 request.getEventManager().addEvent(event);
1152 return result;
1153 }
1154
1155
1163 @RequireToken
1164 @Action(value = "initReferenceDurationEditor", generate = true)
1165 @Permission("editAbstractBasicContent")
1166 @Groups(values = { "ContentAdministrator" })
1167 public final AbstractBasicContentEditorResult initReferenceDurationEditor(
1168 final ServiceRequest request) {
1169
1170 AbstractBasicContentEditorResult result = new AbstractBasicContentEditorResult();
1171
1172 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
1174 .getFirstValue());
1175
1176 Session s = Lifecycle.getHibernateDataSource().createNewSession();
1178 Transaction tx = s.beginTransaction();
1179
1180 try {
1181
1182 Content content = (Content) s.get(Content.class, contentId);
1184
1185 content.initLazyFields();
1187
1188 result.setContent((AbstractBasicContent) content);
1190 result.addTimeZones();
1191
1192 tx.commit();
1193
1194 } catch (Exception e) {
1195 tx.rollback();
1196 throw new PulseException(
1197 "AbstractBasicContentEditor.initReferenceDurationEditor.failed: "
1198 + e.getLocalizedMessage(), e);
1199 } finally {
1200 s.close();
1201 }
1202
1203 XSLTOutputEvent event = new XSLTOutputEvent(
1205 this.config.getAjaxReferenceDurationEditorXSL());
1206 event.setStopEvent(true);
1207 request.getEventManager().addEvent(event);
1208
1209 return result;
1210 }
1211
1212
1219 @RequireToken
1220 @Action(value = "removeReferenceDuration", generate = true)
1221 @Permission("editAbstractBasicContent")
1222 @Groups(values = { "ContentAdministrator" })
1223 public final void removeReferenceDuration(final ServiceRequest request) {
1224
1225 Long contentId = Long.parseLong(request.getCommand().getParameter("id")
1227 .getFirstValue());
1228
1229 Session s = Lifecycle.getHibernateDataSource().createNewSession();
1231 Transaction tx = s.beginTransaction();
1232
1233 try {
1234
1235 Content content = (Content) s.get(Content.class, contentId);
1237
1238 if (content != null) {
1240 content.removeReferenceDuration();
1241 s.saveOrUpdate(content);
1242 }
1243
1244 tx.commit();
1245
1246 } catch (Exception e) {
1247 tx.rollback();
1248 throw new PulseException(
1249 "AbstractBasicContentEditor.removeReferenceDuration.failed: "
1250 + e.getLocalizedMessage(), e);
1251 } finally {
1252 s.close();
1253 }
1254
1255 JSONCommunicationUtils.jsonSuccessMessage(request);
1257 }
1258
1259
1265 private JSONArray buildExpandInfoArray(final SitemapNode sn) {
1266 JSONArray expandInfo = new JSONArray();
1267 SitemapNode parent = (SitemapNode) sn.getParent();
1268 int i = 0;
1269 while (parent != null) {
1270 expandInfo.add(i, parent.toJSON());
1271 parent = (SitemapNode) parent.getParent();
1272 i++;
1273 }
1274 return expandInfo;
1275 }
1276
1277
1285 protected Document buildDocument(final String s) {
1286 Document document;
1288
1289 try {
1290 if (s != null) {
1291 document = XMLConverter.getCleanedXHTML(s);
1292 } else {
1293 document = new SAXBuilder().build(new StringReader(
1294 "<body></body>"));
1295 }
1296 } catch (Exception e) {
1297 throw new PulseException(e);
1298 }
1299 document.getRootElement().setName("body");
1300
1301 if (LOGGER.isTraceEnabled()) {
1303 LOGGER.trace("AbstractBasicContentEditor.buildDocument:\n{}",
1304 XMLConverter.getPrettyString(document, true));
1305 }
1306 return document;
1307 }
1308
1309
1322 public static final JSONObject setBasics(
1323 final AbstractBasicContent content, final ServiceRequest request,
1324 final Session s) {
1325
1326 if (request.getCommand().getParameter("name") != null) {
1328 content.setName(request.getCommand().getParameter("name")
1329 .getFirstValue().trim());
1330 }
1331
1332 if (request.getCommand().getParameter("suffix") != null) {
1334 content.setSuffix(request.getCommand().getParameter("suffix")
1335 .getFirstValue().trim());
1336 }
1337
1338 if (request.getCommand().getParameter("keywords") != null) {
1340 content.setKeywords(request.getCommand().getParameter("keywords")
1341 .getFirstValue().trim());
1342 }
1343
1344 if (request.getCommand().getParameter("title") != null) {
1346 content.setTitle(request.getCommand().getParameter("title")
1347 .getFirstValue().trim());
1348 }
1349
1350 if (request.getCommand().getParameter("metakeywords") != null) {
1352 content.setMetaKeywords(request.getCommand()
1353 .getParameter("metakeywords").getFirstValue().trim());
1354 }
1355
1356 if (request.getCommand().getParameter("metadescription") != null) {
1358 content.setMetaDescription(request.getCommand()
1359 .getParameter("metadescription").getFirstValue().trim());
1360 }
1361
1362 for (String parameterName : request.getCommand().getParameterNames()) {
1364 if (parameterName.length() > 11
1365 && parameterName.startsWith("attachment_")) {
1366
1367 String[] attachmentProperties = parameterName.split("_");
1368
1369 Attachment attachment = (Attachment) s.get(Attachment.class,
1371 Long.parseLong(attachmentProperties[1]));
1372
1373 boolean hasChanged = proccessAttachmentValue(attachment,
1375 attachmentProperties[2], request.getCommand()
1376 .getParameter(parameterName));
1377
1378 if (hasChanged) {
1379 s.saveOrUpdate(attachment);
1380 }
1381
1382 }
1383 }
1384
1385 return AbstractBasicContentEditor.processDuration(request, content);
1387
1388 }
1389
1390
1401 private static JSONObject processDuration(final ServiceRequest request,
1402 final Content content) {
1403
1404 LOGGER.error("processing reference duration for content");
1405
1406 JSONObject error = new JSONObject();
1407
1408 GregorianCalendar startCal = buildGregCal("start_",
1409 request.getCommand(), content.getLocale());
1410 if (startCal == null) {
1411 return null;
1412 }
1413
1414
1420 GregorianCalendar endCal = buildGregCal("end_", request.getCommand(),
1421 content.getLocale());
1422 if (endCal == null) {
1423 error.put("e", "noEndDateSpecified");
1424 return error;
1425 }
1426
1427 if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) {
1428 error.put("e", "startDateAfterEndDateIsNotAllowed");
1429 return error;
1430 }
1431
1432 LOGGER.error("setting reference duration for content: {}",
1433 new Duration(startCal.getTime(), endCal.getTime()));
1434
1435 content.setReferenceDuration(new Duration(startCal.getTime(), endCal
1436 .getTime()));
1437
1438 return null;
1439
1440 }
1441
1442
1458 private static GregorianCalendar buildGregCal(final String parameterPrefix,
1459 final Command c, final Locale locale) {
1460
1461 Parameter year = c.getParameter(parameterPrefix + "YYYY");
1462 if (year == null) {
1463 return null;
1464 }
1465 Parameter month = c.getParameter(parameterPrefix + "MM");
1466 if (month == null) {
1467 return null;
1468 }
1469 Parameter date = c.getParameter(parameterPrefix + "DD");
1470 if (date == null) {
1471 return null;
1472 }
1473 Parameter hrs = c.getParameter(parameterPrefix + "hh");
1474 if (hrs == null) {
1475 return null;
1476 }
1477 Parameter mins = c.getParameter(parameterPrefix + "mm");
1478 if (mins == null) {
1479 return null;
1480 }
1481 Parameter secs = c.getParameter(parameterPrefix + "ss");
1482 if (secs == null) {
1483 return null;
1484 }
1485 Parameter timezone = c.getParameter(parameterPrefix + "tz");
1486 if (timezone == null) {
1487 return null;
1488 }
1489
1490 GregorianCalendar cal = (GregorianCalendar) GregorianCalendar
1491 .getInstance(TimeZone.getTimeZone(timezone.getFirstValue()),
1492 locale);
1493
1494 cal.set(Integer.valueOf(year.getFirstValue()),
1495 Integer.valueOf(month.getFirstValue()),
1496 Integer.valueOf(date.getFirstValue()),
1497 Integer.valueOf(hrs.getFirstValue()),
1498 Integer.valueOf(mins.getFirstValue()),
1499 Integer.valueOf(secs.getFirstValue()));
1500
1501 return cal;
1502 }
1503
1504
1517 private static boolean proccessAttachmentValue(final Attachment attachment,
1518 final String propertyName, final Parameter requestParameter) {
1519 boolean hasChanged = false;
1520
1521 if (propertyName.equals("name")
1523 && !requestParameter.getFirstValue().trim().equals("")) {
1524 attachment.setName(requestParameter.getFirstValue().trim());
1525 hasChanged = true;
1526 }
1527
1528 return hasChanged;
1529 }
1530
1531
1547 public static final void initHibernateSearchFix(final Session s,
1548 final Content content) {
1549
1550 if (content.getAssociatedViews() != null) {
1551 LOGGER.debug(" >>> Starting Hibernate Search work around...");
1552 for (View v : content.getAssociatedViews()) {
1553 LOGGER.debug(" >>> >> Processing View '{}' [{}]", v.getName(),
1554 v.getId());
1555 if (v.getSitemapNode() != null) {
1556 ((FullTextSession) s).index(v.getSitemapNode());
1557 LOGGER.debug(" >>> >> >> Processing SitemapNode '{}' [{}]",
1558 v.getSitemapNode().getName(), v.getSitemapNode()
1559 .getId());
1560 }
1561 }
1562 }
1563 }
1564
1565
1571 public void init(final ConfigBean c) {
1572 this.config = (AbstractBasicContentEditorConfig) c;
1573 }
1574
1575
1580 protected final AbstractBasicContentEditorConfig getConfig() {
1581 return this.config;
1582 }
1583
1584 }
1585