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