1
22
23 package com.liferay.portlet.journal.util;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.util.GetterUtil;
28 import com.liferay.portal.kernel.util.LocaleUtil;
29 import com.liferay.portal.kernel.util.OrderByComparator;
30 import com.liferay.portal.kernel.util.PropertiesUtil;
31 import com.liferay.portal.kernel.util.StringPool;
32 import com.liferay.portal.kernel.util.StringUtil;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.model.Contact;
35 import com.liferay.portal.model.User;
36 import com.liferay.portal.service.UserLocalServiceUtil;
37 import com.liferay.portal.service.impl.ImageLocalUtil;
38 import com.liferay.portal.theme.ThemeDisplay;
39 import com.liferay.portal.util.ContentUtil;
40 import com.liferay.portal.util.PropsUtil;
41 import com.liferay.portal.util.WebKeys;
42 import com.liferay.portlet.journal.TransformException;
43 import com.liferay.portlet.journal.model.JournalArticle;
44 import com.liferay.portlet.journal.model.JournalStructure;
45 import com.liferay.portlet.journal.model.JournalTemplate;
46 import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
47 import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
48 import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
49 import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
50 import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
51 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
52 import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
53 import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
54 import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
55 import com.liferay.util.CollectionFactory;
56 import com.liferay.util.FiniteUniqueStack;
57 import com.liferay.util.Http;
58 import com.liferay.util.Time;
59 import com.liferay.util.xml.XMLFormatter;
60
61 import java.io.IOException;
62 import java.io.StringReader;
63 import java.io.UnsupportedEncodingException;
64
65 import java.util.ArrayList;
66 import java.util.Date;
67 import java.util.Iterator;
68 import java.util.List;
69 import java.util.Map;
70 import java.util.Stack;
71
72 import javax.portlet.PortletPreferences;
73 import javax.portlet.PortletRequest;
74 import javax.portlet.PortletSession;
75
76 import org.apache.commons.logging.Log;
77 import org.apache.commons.logging.LogFactory;
78
79 import org.dom4j.Document;
80 import org.dom4j.DocumentException;
81 import org.dom4j.DocumentFactory;
82 import org.dom4j.DocumentHelper;
83 import org.dom4j.Element;
84 import org.dom4j.Node;
85 import org.dom4j.XPath;
86 import org.dom4j.io.SAXReader;
87
88
95 public class JournalUtil {
96
97 public static final int MAX_STACK_SIZE = 20;
98
99 public static final String XML_INDENT = " ";
100
101 public static void addRecentArticle(
102 PortletRequest req, JournalArticle article) {
103
104 if (article != null) {
105 Stack stack = getRecentArticles(req);
106
107 stack.push(article);
108 }
109 }
110
111 public static void addRecentStructure(
112 PortletRequest req, JournalStructure structure) {
113
114 if (structure != null) {
115 Stack stack = getRecentStructures(req);
116
117 stack.push(structure);
118 }
119 }
120
121 public static void addRecentTemplate(
122 PortletRequest req, JournalTemplate template) {
123
124 if (template != null) {
125 Stack stack = getRecentTemplates(req);
126
127 stack.push(template);
128 }
129 }
130
131 public static void addReservedEl(
132 Element root, Map tokens, String name, double value) {
133
134 addReservedEl(root, tokens, name, String.valueOf(value));
135 }
136
137 public static void addReservedEl(
138 Element root, Map tokens, String name, Date value) {
139
140 addReservedEl(root, tokens, name, Time.getRFC822(value));
141 }
142
143 public static void addReservedEl(
144 Element root, Map tokens, String name, String value) {
145
146
148 if (root != null) {
149 DocumentFactory docFactory = DocumentFactory.getInstance();
150
151 Element dynamicEl = docFactory.createElement("dynamic-element");
152
153 dynamicEl.add(docFactory.createAttribute(dynamicEl, "name", name));
154 dynamicEl.add(
155 docFactory.createAttribute(dynamicEl, "type", "text"));
156
157 Element dynamicContent =
158 docFactory.createElement("dynamic-content");
159
160 dynamicContent.setText(value);
162
163 dynamicEl.add(dynamicContent);
164
165 root.add(dynamicEl);
166 }
167
168
170 tokens.put(
171 StringUtil.replace(name, StringPool.DASH, StringPool.UNDERLINE),
172 value);
173 }
174
175 public static void addAllReservedEls(
176 Element root, Map tokens, JournalArticle article) {
177
178 JournalUtil.addReservedEl(
179 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_ID,
180 article.getArticleId());
181
182 JournalUtil.addReservedEl(
183 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_VERSION,
184 article.getVersion());
185
186 JournalUtil.addReservedEl(
187 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TITLE,
188 article.getTitle());
189
190 JournalUtil.addReservedEl(
191 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_DESCRIPTION,
192 article.getDescription());
193
194 JournalUtil.addReservedEl(
195 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_TYPE,
196 article.getType());
197
198 JournalUtil.addReservedEl(
199 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_CREATE_DATE,
200 article.getCreateDate());
201
202 JournalUtil.addReservedEl(
203 root, tokens,
204 JournalStructureImpl.RESERVED_ARTICLE_MODIFIED_DATE,
205 article.getModifiedDate());
206
207 if (article.getDisplayDate() != null) {
208 JournalUtil.addReservedEl(
209 root, tokens,
210 JournalStructureImpl.RESERVED_ARTICLE_DISPLAY_DATE,
211 article.getDisplayDate());
212 }
213
214 JournalUtil.addReservedEl(
215 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_SMALL_IMAGE_URL,
216 article.getSmallImageURL());
217
218 JournalUtil.addReservedEl(
219 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_ID,
220 String.valueOf(article.getUserId()));
221
222 String userName = StringPool.BLANK;
223 String userEmailAddress = StringPool.BLANK;
224 String userComments = StringPool.BLANK;
225 String userJobTitle = StringPool.BLANK;
226
227 User user = null;
228
229 try {
230 user = UserLocalServiceUtil.getUserById(article.getUserId());
231
232 userName = user.getFullName();
233 userEmailAddress = user.getEmailAddress();
234 userComments = user.getComments();
235
236 Contact contact = user.getContact();
237
238 if (contact != null) {
239 userJobTitle = contact.getJobTitle();
240 }
241 }
242 catch (PortalException pe) {
243 }
244 catch (SystemException se) {
245 }
246
247 JournalUtil.addReservedEl(
248 root, tokens, JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_NAME,
249 userName);
250
251 JournalUtil.addReservedEl(
252 root, tokens,
253 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
254 userEmailAddress);
255
256 JournalUtil.addReservedEl(
257 root, tokens,
258 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_COMMENTS,
259 userComments);
260
261 JournalUtil.addReservedEl(
262 root, tokens,
263 JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
264 userJobTitle);
265 }
266
267 public static String formatVM(String vm) {
268 return vm;
269 }
270
271 public static String formatXML(String xml)
272 throws DocumentException, IOException {
273
274
278 xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
279
280 xml = XMLFormatter.toString(xml, XML_INDENT);
281
282 xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
283
284 return xml;
285 }
286
287 public static String formatXML(Document doc)
288 throws DocumentException, IOException {
289
290 return XMLFormatter.toString(doc, XML_INDENT);
291 }
292
293 public static OrderByComparator getArticleOrderByComparator(
294 String orderByCol, String orderByType) {
295
296 boolean orderByAsc = false;
297
298 if (orderByType.equals("asc")) {
299 orderByAsc = true;
300 }
301
302 OrderByComparator orderByComparator = null;
303
304 if (orderByCol.equals("create-date")) {
305 orderByComparator = new ArticleCreateDateComparator(orderByAsc);
306 }
307 else if (orderByCol.equals("display-date")) {
308 orderByComparator = new ArticleDisplayDateComparator(orderByAsc);
309 }
310 else if (orderByCol.equals("id")) {
311 orderByComparator = new ArticleIDComparator(orderByAsc);
312 }
313 else if (orderByCol.equals("modified-date")) {
314 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
315 }
316 else if (orderByCol.equals("review-date")) {
317 orderByComparator = new ArticleReviewDateComparator(orderByAsc);
318 }
319 else if (orderByCol.equals("title")) {
320 orderByComparator = new ArticleTitleComparator(orderByAsc);
321 }
322 else if (orderByCol.equals("version")) {
323 orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
324 }
325
326 return orderByComparator;
327 }
328
329 public static String getEmailFromAddress(PortletPreferences prefs) {
330 String emailFromAddress = PropsUtil.get(
331 PropsUtil.JOURNAL_EMAIL_FROM_ADDRESS);
332
333 return prefs.getValue("email-from-address", emailFromAddress);
334 }
335
336 public static String getEmailFromName(PortletPreferences prefs) {
337 String emailFromName = PropsUtil.get(
338 PropsUtil.JOURNAL_EMAIL_FROM_NAME);
339
340 return prefs.getValue("email-from-name", emailFromName);
341 }
342
343 public static boolean getEmailArticleApprovalDeniedEnabled(
344 PortletPreferences prefs) {
345
346 String emailArticleApprovalDeniedEnabled = prefs.getValue(
347 "email-article-approval-denied-enabled", StringPool.BLANK);
348
349 if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
350 return GetterUtil.getBoolean(emailArticleApprovalDeniedEnabled);
351 }
352 else {
353 return GetterUtil.getBoolean(PropsUtil.get(
354 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
355 }
356 }
357
358 public static String getEmailArticleApprovalDeniedBody(
359 PortletPreferences prefs)
360 throws IOException {
361
362 String emailArticleApprovalDeniedBody = prefs.getValue(
363 "email-article-approval-denied-body", StringPool.BLANK);
364
365 if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
366 return emailArticleApprovalDeniedBody;
367 }
368 else {
369 return ContentUtil.get(PropsUtil.get(
370 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
371 }
372 }
373
374 public static String getEmailArticleApprovalDeniedSubject(
375 PortletPreferences prefs)
376 throws IOException {
377
378 String emailArticleApprovalDeniedSubject = prefs.getValue(
379 "email-article-approval-denied-subject", StringPool.BLANK);
380
381 if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
382 return emailArticleApprovalDeniedSubject;
383 }
384 else {
385 return ContentUtil.get(PropsUtil.get(
386 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
387 }
388 }
389
390 public static boolean getEmailArticleApprovalGrantedEnabled(
391 PortletPreferences prefs) {
392
393 String emailArticleApprovalGrantedEnabled = prefs.getValue(
394 "email-article-approval-granted-enabled", StringPool.BLANK);
395
396 if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
397 return GetterUtil.getBoolean(emailArticleApprovalGrantedEnabled);
398 }
399 else {
400 return GetterUtil.getBoolean(PropsUtil.get(
401 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
402 }
403 }
404
405 public static String getEmailArticleApprovalGrantedBody(
406 PortletPreferences prefs)
407 throws IOException {
408
409 String emailArticleApprovalGrantedBody = prefs.getValue(
410 "email-article-approval-granted-body", StringPool.BLANK);
411
412 if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
413 return emailArticleApprovalGrantedBody;
414 }
415 else {
416 return ContentUtil.get(PropsUtil.get(
417 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
418 }
419 }
420
421 public static String getEmailArticleApprovalGrantedSubject(
422 PortletPreferences prefs)
423 throws IOException {
424
425 String emailArticleApprovalGrantedSubject = prefs.getValue(
426 "email-article-approval-granted-subject", StringPool.BLANK);
427
428 if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
429 return emailArticleApprovalGrantedSubject;
430 }
431 else {
432 return ContentUtil.get(PropsUtil.get(
433 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
434 }
435 }
436
437 public static boolean getEmailArticleApprovalRequestedEnabled(
438 PortletPreferences prefs) {
439
440 String emailArticleApprovalRequestedEnabled = prefs.getValue(
441 "email-article-approval-requested-enabled", StringPool.BLANK);
442
443 if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
444 return GetterUtil.getBoolean(emailArticleApprovalRequestedEnabled);
445 }
446 else {
447 return GetterUtil.getBoolean(PropsUtil.get(
448 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
449 }
450 }
451
452 public static String getEmailArticleApprovalRequestedBody(
453 PortletPreferences prefs)
454 throws IOException {
455
456 String emailArticleApprovalRequestedBody = prefs.getValue(
457 "email-article-approval-requested-body", StringPool.BLANK);
458
459 if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
460 return emailArticleApprovalRequestedBody;
461 }
462 else {
463 return ContentUtil.get(PropsUtil.get(
464 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
465 }
466 }
467
468 public static String getEmailArticleApprovalRequestedSubject(
469 PortletPreferences prefs)
470 throws IOException {
471
472 String emailArticleApprovalRequestedSubject = prefs.getValue(
473 "email-article-approval-requested-subject", StringPool.BLANK);
474
475 if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
476 return emailArticleApprovalRequestedSubject;
477 }
478 else {
479 return ContentUtil.get(PropsUtil.get(
480 PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
481 }
482 }
483
484 public static boolean getEmailArticleReviewEnabled(
485 PortletPreferences prefs) {
486
487 String emailArticleReviewEnabled = prefs.getValue(
488 "email-article-review-enabled", StringPool.BLANK);
489
490 if (Validator.isNotNull(emailArticleReviewEnabled)) {
491 return GetterUtil.getBoolean(emailArticleReviewEnabled);
492 }
493 else {
494 return GetterUtil.getBoolean(PropsUtil.get(
495 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
496 }
497 }
498
499 public static String getEmailArticleReviewBody(PortletPreferences prefs)
500 throws IOException {
501
502 String emailArticleReviewBody = prefs.getValue(
503 "email-article-review-body", StringPool.BLANK);
504
505 if (Validator.isNotNull(emailArticleReviewBody)) {
506 return emailArticleReviewBody;
507 }
508 else {
509 return ContentUtil.get(PropsUtil.get(
510 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
511 }
512 }
513
514 public static String getEmailArticleReviewSubject(PortletPreferences prefs)
515 throws IOException {
516
517 String emailArticleReviewSubject = prefs.getValue(
518 "email-article-review-subject", StringPool.BLANK);
519
520 if (Validator.isNotNull(emailArticleReviewSubject)) {
521 return emailArticleReviewSubject;
522 }
523 else {
524 return ContentUtil.get(PropsUtil.get(
525 PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
526 }
527 }
528
529 public static Stack getRecentArticles(PortletRequest req) {
530 PortletSession ses = req.getPortletSession();
531
532 Stack recentArticles =
533 (Stack)ses.getAttribute(WebKeys.JOURNAL_RECENT_ARTICLES);
534
535 if (recentArticles == null) {
536 recentArticles = new FiniteUniqueStack(MAX_STACK_SIZE);
537
538 ses.setAttribute(WebKeys.JOURNAL_RECENT_ARTICLES, recentArticles);
539 }
540
541 return recentArticles;
542 }
543
544 public static Stack getRecentStructures(PortletRequest req) {
545 PortletSession ses = req.getPortletSession();
546
547 Stack recentStructures =
548 (Stack)ses.getAttribute(WebKeys.JOURNAL_RECENT_STRUCTURES);
549
550 if (recentStructures == null) {
551 recentStructures = new FiniteUniqueStack(MAX_STACK_SIZE);
552
553 ses.setAttribute(
554 WebKeys.JOURNAL_RECENT_STRUCTURES, recentStructures);
555 }
556
557 return recentStructures;
558 }
559
560 public static Stack getRecentTemplates(PortletRequest req) {
561 PortletSession ses = req.getPortletSession();
562
563 Stack recentTemplates =
564 (Stack)ses.getAttribute(WebKeys.JOURNAL_RECENT_TEMPLATES);
565
566 if (recentTemplates == null) {
567 recentTemplates = new FiniteUniqueStack(MAX_STACK_SIZE);
568
569 ses.setAttribute(WebKeys.JOURNAL_RECENT_TEMPLATES, recentTemplates);
570 }
571
572 return recentTemplates;
573 }
574
575 public static String getTemplateScript(
576 long groupId, String templateId, Map tokens, String languageId)
577 throws PortalException, SystemException {
578
579 return getTemplateScript(groupId, templateId, tokens, languageId, true);
580 }
581
582 public static String getTemplateScript(
583 long groupId, String templateId, Map tokens, String languageId,
584 boolean transform)
585 throws PortalException, SystemException {
586
587 JournalTemplate template = JournalTemplateLocalServiceUtil.getTemplate(
588 groupId, templateId);
589
590 return getTemplateScript(template, tokens, languageId, transform);
591 }
592
593 public static String getTemplateScript(
594 JournalTemplate template, Map tokens, String languageId,
595 boolean transform)
596 throws PortalException, SystemException {
597
598 String script = template.getXsl();
599
600 if (transform) {
601
602
604 String[] listeners =
605 PropsUtil.getArray(PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
606
607 for (int i = 0; i < listeners.length; i++) {
608 TransformerListener listener = null;
609
610 try {
611 listener =
612 (TransformerListener)Class.forName(
613 listeners[i]).newInstance();
614
615 listener.setTemplateDriven(true);
616 listener.setLanguageId(languageId);
617 listener.setTokens(tokens);
618 }
619 catch (Exception e) {
620 e.printStackTrace();
621 }
622
623
625 if (listener != null) {
626 script = listener.onScript(script);
627 }
628 }
629 }
630
631 return script;
632 }
633
634 public static Map getTokens(long groupId, ThemeDisplay themeDisplay) {
635 Map tokens = CollectionFactory.getHashMap();
636
637 if (themeDisplay == null) {
638 return tokens;
639 }
640
641 tokens.put("cdn_host", themeDisplay.getCDNHost());
642 tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
643 tokens.put("group_id", String.valueOf(groupId));
644 tokens.put("cms_url", themeDisplay.getPathContext() + "/cms/servlet");
645 tokens.put("image_path", themeDisplay.getPathImage());
646 tokens.put(
647 "friendly_url_private_group",
648 themeDisplay.getPathFriendlyURLPrivateGroup());
649 tokens.put(
650 "friendly_url_private_user",
651 themeDisplay.getPathFriendlyURLPrivateUser());
652 tokens.put(
653 "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
654 tokens.put("main_path", themeDisplay.getPathMain());
655 tokens.put("portal_ctx", themeDisplay.getPathContext());
656 tokens.put(
657 "portal_url", Http.removeProtocol(themeDisplay.getURLPortal()));
658 tokens.put("root_path", themeDisplay.getPathContext());
659 tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
660
661
663 tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
664 tokens.put(
665 "friendly_url_private",
666 themeDisplay.getPathFriendlyURLPrivateGroup());
667 tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
668
669 return tokens;
670 }
671
672 public static String mergeLocaleContent(
673 String curContent, String newContent, String xsd) {
674
675 try {
676 SAXReader reader = new SAXReader();
677
678 Document curContentDoc = reader.read(new StringReader(curContent));
679 Document newContentDoc = reader.read(new StringReader(newContent));
680 Document xsdDoc = reader.read(new StringReader(xsd));
681
682 Element curContentRoot = curContentDoc.getRootElement();
683 Element newContentRoot = newContentDoc.getRootElement();
684 Element xsdRoot = xsdDoc.getRootElement();
685
686 curContentRoot.addAttribute(
687 "default-locale",
688 newContentRoot.attributeValue("default-locale"));
689 curContentRoot.addAttribute(
690 "available-locales",
691 newContentRoot.attributeValue("available-locales"));
692
693 Stack path = new Stack();
694
695 path.push(xsdRoot.getName());
696
697 _mergeLocaleContent(
698 path, curContentDoc, newContentDoc, xsdRoot,
699 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
700
701 curContent = formatXML(curContentDoc);
702 }
703 catch (Exception e) {
704 _log.error(e);
705 }
706
707 return curContent;
708 }
709
710 public static String removeArticleLocale(
711 String content, String languageId) {
712
713 try {
714 SAXReader reader = new SAXReader();
715
716 Document doc = reader.read(new StringReader(content));
717
718 Element root = doc.getRootElement();
719
720 String availableLocales = root.attributeValue("available-locales");
721
722 if (availableLocales == null) {
723 return content;
724 }
725
726 availableLocales = StringUtil.remove(availableLocales, languageId);
727
728 if (availableLocales.endsWith(",")) {
729 availableLocales = availableLocales.substring(
730 0, availableLocales.length() - 1);
731 }
732
733 root.addAttribute("available-locales", availableLocales);
734
735 removeArticleLocale(root, languageId);
736
737 content = formatXML(doc);
738 }
739 catch (Exception e) {
740 _log.error(e);
741 }
742
743 return content;
744 }
745
746 public static void removeArticleLocale(Element el, String languageId)
747 throws SystemException {
748
749 Iterator itr1 = el.elements("dynamic-element").iterator();
750
751 while (itr1.hasNext()) {
752 Element dynamicEl = (Element)itr1.next();
753
754 Iterator itr2 = dynamicEl.elements("dynamic-content").iterator();
755
756 while (itr2.hasNext()) {
757 Element dynamicContentEl = (Element)itr2.next();
758
759 String curLanguageId = GetterUtil.getString(
760 dynamicContentEl.attributeValue("language-id"));
761
762 if (curLanguageId.equals(languageId)) {
763 long id = GetterUtil.getLong(
764 dynamicContentEl.attributeValue("id"));
765
766 if (id > 0) {
767 ImageLocalUtil.deleteImage(id);
768 }
769
770 dynamicContentEl.detach();
771 }
772 }
773
774 removeArticleLocale(dynamicEl, languageId);
775 }
776 }
777
778 public static String removeOldContent(String content, String xsd) {
779 try {
780 SAXReader reader = new SAXReader();
781
782 Document contentDoc = reader.read(new StringReader(content));
783 Document xsdDoc = reader.read(new StringReader(xsd));
784
785 Element contentRoot = contentDoc.getRootElement();
786
787 Stack path = new Stack();
788
789 path.push(contentRoot.getName());
790
791 _removeOldContent(path, contentRoot, xsdDoc);
792
793 content = formatXML(contentDoc);
794 }
795 catch (Exception e) {
796 _log.error(e);
797 }
798
799 return content;
800 }
801
802 public static void removeRecentArticle(
803 PortletRequest req, String articleId) {
804
805 Stack stack = getRecentArticles(req);
806
807 Iterator itr = stack.iterator();
808
809 while (itr.hasNext()) {
810 JournalArticle journalArticle = (JournalArticle)itr.next();
811
812 if (journalArticle.getArticleId().equals(articleId)) {
813 itr.remove();
814
815 break;
816 }
817 }
818 }
819
820 public static void removeRecentStructure(
821 PortletRequest req, String structureId) {
822
823 Stack stack = getRecentStructures(req);
824
825 Iterator itr = stack.iterator();
826
827 while (itr.hasNext()) {
828 JournalStructure journalStructure = (JournalStructure)itr.next();
829
830 if (journalStructure.getStructureId().equals(structureId)) {
831 itr.remove();
832
833 break;
834 }
835 }
836 }
837
838 public static void removeRecentTemplate(
839 PortletRequest req, String templateId) {
840
841 Stack stack = getRecentTemplates(req);
842
843 Iterator itr = stack.iterator();
844
845 while (itr.hasNext()) {
846 JournalTemplate journalTemplate = (JournalTemplate)itr.next();
847
848 if (journalTemplate.getTemplateId().equals(templateId)) {
849 itr.remove();
850
851 break;
852 }
853 }
854 }
855
856 public static String transform(
857 Map tokens, String languageId, String xml, String script,
858 String langType)
859 throws TransformException, UnsupportedEncodingException {
860
861
863 if (_log.isDebugEnabled()) {
864 _log.debug("Language " + languageId);
865 }
866
867 if (_logTokens.isDebugEnabled()) {
868 String tokensString = PropertiesUtil.list(tokens);
869
870 _logTokens.debug(tokensString);
871 }
872
873 if (_logTransformBefore.isDebugEnabled()) {
874 _logTransformBefore.debug(xml);
875 }
876
877 List listenersList = new ArrayList();
878
879 String[] listeners = PropsUtil.getArray(
880 PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
881
882 for (int i = 0; i < listeners.length; i++) {
883 TransformerListener listener = null;
884
885 try {
886 if (_log.isDebugEnabled()) {
887 _log.debug("Instantiate listener " + listeners[i]);
888 }
889
890 boolean templateDriven = Validator.isNotNull(langType);
891
892 listener = (TransformerListener)Class.forName(
893 listeners[i]).newInstance();
894
895 listener.setTemplateDriven(templateDriven);
896 listener.setLanguageId(languageId);
897 listener.setTokens(tokens);
898
899 listenersList.add(listener);
900 }
901 catch (Exception e) {
902 _log.error(e, e);
903 }
904
905
907 if (_logXmlBeforeListener.isDebugEnabled()) {
908 _logXmlBeforeListener.debug(xml);
909 }
910
911 if (listener != null) {
912 xml = listener.onXml(xml);
913
914 if (_logXmlAfterListener.isDebugEnabled()) {
915 _logXmlAfterListener.debug(xml);
916 }
917 }
918
919
921 if (_logScriptBeforeListener.isDebugEnabled()) {
922 _logScriptBeforeListener.debug(script);
923 }
924
925 if (listener != null) {
926 script = listener.onScript(script);
927
928 if (_logScriptAfterListener.isDebugEnabled()) {
929 _logScriptAfterListener.debug(script);
930 }
931 }
932 }
933
934
936 String output = null;
937
938 if (Validator.isNull(langType)) {
939 output = xml;
940 }
941 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
942 output = JournalVmUtil.transform(tokens, languageId, xml, script);
943 }
944 else if (langType.equals(JournalTemplateImpl.LANG_TYPE_XSL)) {
945 output = JournalXslUtil.transform(tokens, languageId, xml, script);
946 }
947
948
950 for (int i = 0; i < listenersList.size(); i++) {
951 TransformerListener listener =
952 (TransformerListener)listenersList.get(i);
953
954
956 if (_logOutputBeforeListener.isDebugEnabled()) {
957 _logOutputBeforeListener.debug(output);
958 }
959
960 output = listener.onOutput(output);
961
962 if (_logOutputAfterListener.isDebugEnabled()) {
963 _logOutputAfterListener.debug(output);
964 }
965 }
966
967 if (_logTransfromAfter.isDebugEnabled()) {
968 _logTransfromAfter.debug(output);
969 }
970
971 return output;
972 }
973
974 private static void _mergeLocaleContent(
975 Stack path, Document curDoc, Document newDoc, Element xsdEl,
976 String defaultLocale)
977 throws SystemException {
978
979 String elPath = "";
980
981 for (int i = 0; i < path.size(); i++) {
982 elPath += "/" + path.elementAt(i);
983 }
984
985 for (int i = 0; i < xsdEl.nodeCount(); i++) {
986 Node xsdNode = xsdEl.node(i);
987
988 if ((xsdNode instanceof Element) &&
989 (xsdNode.getName().equals("dynamic-element"))) {
990
991 _mergeLocaleContent(
992 path, curDoc, newDoc, (Element)xsdNode, defaultLocale,
993 elPath);
994 }
995 }
996 }
997
998 private static void _mergeLocaleContent(
999 Stack path, Document curDoc, Document newDoc, Element xsdEl,
1000 String defaultLocale, String elPath)
1001 throws SystemException {
1002
1003 String name = xsdEl.attributeValue("name");
1004
1005 String localPath = "dynamic-element[@name='" + name + "']";
1006
1007 String fullPath = elPath + "/" + localPath;
1008
1009 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1010
1011 List curElements = xPathSelector.selectNodes(curDoc);
1012
1013 Element newEl = (Element)xPathSelector.selectNodes(newDoc).get(0);
1014
1015 if (curElements.size() > 0) {
1016 Element curEl = (Element)curElements.get(0);
1017
1018 List curDynamicContents = curEl.elements("dynamic-content");
1019
1020 Element newContentEl = newEl.element("dynamic-content");
1021
1022 String newContentLanguageId = newContentEl.attributeValue(
1023 "language-id", StringPool.BLANK);
1024
1025 if (newContentLanguageId.equals(StringPool.BLANK)) {
1026 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1027 Element curContentEl = (Element)curDynamicContents.get(k);
1028
1029 String curContentLanguageId = curContentEl.attributeValue(
1030 "language-id", StringPool.BLANK);
1031
1032 if ((curEl.attributeValue("type").equals("image")) &&
1033 (!curContentLanguageId.equals(defaultLocale) &&
1034 !curContentLanguageId.equals(StringPool.BLANK))) {
1035
1036 long id = GetterUtil.getLong(
1037 curContentEl.attributeValue("id"));
1038
1039 ImageLocalUtil.deleteImage(id);
1040 }
1041
1042 curContentEl.detach();
1043 }
1044
1045 curEl.content().add(newContentEl.createCopy());
1046 }
1047 else {
1048 boolean match = false;
1049
1050 for (int k = curDynamicContents.size() - 1; k >= 0 ; k--) {
1051 Element curContentEl = (Element)curDynamicContents.get(k);
1052
1053 String curContentLanguageId = curContentEl.attributeValue(
1054 "language-id", StringPool.BLANK);
1055
1056 if ((newContentLanguageId.equals(curContentLanguageId)) ||
1057 (newContentLanguageId.equals(defaultLocale) &&
1058 curContentLanguageId.equals(StringPool.BLANK))) {
1059
1060 curContentEl.detach();
1061
1062 curEl.content().add(k, newContentEl.createCopy());
1063
1064 match = true;
1065 }
1066
1067 if (curContentLanguageId.equals(StringPool.BLANK)) {
1068 curContentEl.addAttribute("language-id", defaultLocale);
1069 }
1070 }
1071
1072 if (!match) {
1073 curEl.content().add(newContentEl.createCopy());
1074 }
1075 }
1076 }
1077 else {
1078 xPathSelector = DocumentHelper.createXPath(elPath);
1079
1080 Element parentEl =
1081 (Element)xPathSelector.selectNodes(curDoc).get(0);
1082
1083 parentEl.content().add(newEl.createCopy());
1084 }
1085
1086 String type = xsdEl.attributeValue("type", StringPool.BLANK);
1087
1088 if (!type.equals("list") && !type.equals("multi-list")) {
1089 path.push(localPath);
1090
1091 _mergeLocaleContent(path, curDoc, newDoc, xsdEl, defaultLocale);
1092
1093 path.pop();
1094 }
1095 }
1096
1097 private static void _removeOldContent(
1098 Stack path, Element contentEl, Document xsdDoc)
1099 throws SystemException {
1100
1101 String elPath = "";
1102
1103 for (int i = 0; i < path.size(); i++) {
1104 elPath += "/" + path.elementAt(i);
1105 }
1106
1107 for (int i = 0; i < contentEl.nodeCount(); i++) {
1108 Node contentNode = contentEl.node(i);
1109
1110 if (contentNode instanceof Element) {
1111 _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1112 }
1113 }
1114 }
1115
1116 private static void _removeOldContent(
1117 Stack path, Element contentEl, Document xsdDoc, String elPath)
1118 throws SystemException {
1119
1120 String name = contentEl.attributeValue("name");
1121
1122 if (Validator.isNull(name)) {
1123 return;
1124 }
1125
1126 String localPath = "dynamic-element[@name='" + name + "']";
1127
1128 String fullPath = elPath + "/" + localPath;
1129
1130 XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1131
1132 List curElements = xPathSelector.selectNodes(xsdDoc);
1133
1134 if (curElements.size() == 0) {
1135 contentEl.detach();
1136 }
1137
1138 path.push(localPath);
1139
1140 _removeOldContent(path, contentEl, xsdDoc);
1141
1142 path.pop();
1143 }
1144
1145 private static Log _log = LogFactory.getLog(JournalUtil.class);
1146
1147 private static Log _logOutputAfterListener = LogFactory.getLog(
1148 JournalUtil.class.getName() + ".OutputAfterListener");
1149
1150 private static Log _logOutputBeforeListener = LogFactory.getLog(
1151 JournalUtil.class.getName() + ".OutputBeforeListener");
1152
1153 private static Log _logScriptAfterListener = LogFactory.getLog(
1154 JournalUtil.class.getName() + ".ScriptAfterListener");
1155
1156 private static Log _logScriptBeforeListener = LogFactory.getLog(
1157 JournalUtil.class.getName() + ".ScriptBeforeListener");
1158
1159 private static Log _logTransfromAfter = LogFactory.getLog(
1160 JournalUtil.class.getName() + ".TransformAfter");
1161
1162 private static Log _logTransformBefore = LogFactory.getLog(
1163 JournalUtil.class.getName() + ".BeforeTransform");
1164
1165 private static Log _logTokens = LogFactory.getLog(
1166 JournalUtil.class.getName() + ".Tokens");
1167
1168 private static Log _logXmlAfterListener = LogFactory.getLog(
1169 JournalUtil.class.getName() + ".XmlAfterListener");
1170
1171 private static Log _logXmlBeforeListener = LogFactory.getLog(
1172 JournalUtil.class.getName() + ".XmlBeforeListener");
1173
1174}