001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.util;
016    
017    import com.liferay.portal.kernel.configuration.Filter;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.Constants;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.HttpUtil;
025    import com.liferay.portal.kernel.util.InstancePool;
026    import com.liferay.portal.kernel.util.LocaleUtil;
027    import com.liferay.portal.kernel.util.LocalizationUtil;
028    import com.liferay.portal.kernel.util.OrderByComparator;
029    import com.liferay.portal.kernel.util.PropertiesUtil;
030    import com.liferay.portal.kernel.util.PropsKeys;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Time;
035    import com.liferay.portal.kernel.util.Validator;
036    import com.liferay.portal.kernel.xml.Attribute;
037    import com.liferay.portal.kernel.xml.Document;
038    import com.liferay.portal.kernel.xml.Element;
039    import com.liferay.portal.kernel.xml.Node;
040    import com.liferay.portal.kernel.xml.SAXReaderUtil;
041    import com.liferay.portal.kernel.xml.XPath;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.model.Layout;
044    import com.liferay.portal.model.LayoutSet;
045    import com.liferay.portal.model.User;
046    import com.liferay.portal.service.ImageLocalServiceUtil;
047    import com.liferay.portal.service.LayoutLocalServiceUtil;
048    import com.liferay.portal.service.UserLocalServiceUtil;
049    import com.liferay.portal.theme.ThemeDisplay;
050    import com.liferay.portal.util.ContentUtil;
051    import com.liferay.portal.util.FriendlyURLNormalizer;
052    import com.liferay.portal.util.PropsUtil;
053    import com.liferay.portal.util.PropsValues;
054    import com.liferay.portal.util.WebKeys;
055    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
056    import com.liferay.portlet.journal.TransformException;
057    import com.liferay.portlet.journal.model.JournalArticle;
058    import com.liferay.portlet.journal.model.JournalStructure;
059    import com.liferay.portlet.journal.model.JournalStructureConstants;
060    import com.liferay.portlet.journal.model.JournalTemplate;
061    import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
062    import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
063    import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
064    import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
065    import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
066    import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
067    import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
068    import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
069    import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
070    import com.liferay.util.FiniteUniqueStack;
071    import com.liferay.util.xml.XMLFormatter;
072    
073    import java.io.IOException;
074    
075    import java.util.ArrayList;
076    import java.util.Date;
077    import java.util.HashMap;
078    import java.util.Iterator;
079    import java.util.List;
080    import java.util.Map;
081    import java.util.Stack;
082    
083    import javax.portlet.PortletPreferences;
084    import javax.portlet.PortletRequest;
085    import javax.portlet.PortletSession;
086    
087    /**
088     * @author Brian Wing Shun Chan
089     * @author Raymond Augé
090     * @author Wesley Gong
091     */
092    public class JournalUtil {
093    
094            public static final int MAX_STACK_SIZE = 20;
095    
096            public static final String POP_PORTLET_PREFIX = "journal.";
097    
098            public static final String XML_INDENT = "  ";
099    
100            public static void addAllReservedEls(
101                    Element root, Map<String, String> tokens, JournalArticle article) {
102    
103                    JournalUtil.addReservedEl(
104                            root, tokens, JournalStructureConstants.RESERVED_ARTICLE_ID,
105                            article.getArticleId());
106    
107                    JournalUtil.addReservedEl(
108                            root, tokens, JournalStructureConstants.RESERVED_ARTICLE_VERSION,
109                            article.getVersion());
110    
111                    JournalUtil.addReservedEl(
112                            root, tokens, JournalStructureConstants.RESERVED_ARTICLE_TITLE,
113                            article.getTitle());
114    
115                    JournalUtil.addReservedEl(
116                            root, tokens,
117                            JournalStructureConstants.RESERVED_ARTICLE_URL_TITLE,
118                            article.getUrlTitle());
119    
120                    JournalUtil.addReservedEl(
121                            root, tokens,
122                            JournalStructureConstants.RESERVED_ARTICLE_DESCRIPTION,
123                            article.getDescription());
124    
125                    JournalUtil.addReservedEl(
126                            root, tokens, JournalStructureConstants.RESERVED_ARTICLE_TYPE,
127                            article.getType());
128    
129                    JournalUtil.addReservedEl(
130                            root, tokens,
131                            JournalStructureConstants.RESERVED_ARTICLE_CREATE_DATE,
132                            article.getCreateDate());
133    
134                    JournalUtil.addReservedEl(
135                            root, tokens,
136                            JournalStructureConstants.RESERVED_ARTICLE_MODIFIED_DATE,
137                            article.getModifiedDate());
138    
139                    if (article.getDisplayDate() != null) {
140                            JournalUtil.addReservedEl(
141                                    root, tokens,
142                                    JournalStructureConstants.RESERVED_ARTICLE_DISPLAY_DATE,
143                                    article.getDisplayDate());
144                    }
145    
146                    JournalUtil.addReservedEl(
147                            root, tokens,
148                            JournalStructureConstants.RESERVED_ARTICLE_SMALL_IMAGE_URL,
149                            article.getSmallImageURL());
150    
151                    String[] assetTagNames = new String[0];
152    
153                    try {
154                            assetTagNames = AssetTagLocalServiceUtil.getTagNames(
155                                    JournalArticle.class.getName(), article.getResourcePrimKey());
156                    }
157                    catch (SystemException se) {
158                    }
159    
160                    JournalUtil.addReservedEl(
161                            root, tokens,
162                            JournalStructureConstants.RESERVED_ARTICLE_ASSET_TAG_NAMES,
163                            StringUtil.merge(assetTagNames));
164    
165                    JournalUtil.addReservedEl(
166                            root, tokens, JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_ID,
167                            String.valueOf(article.getUserId()));
168    
169                    String userName = StringPool.BLANK;
170                    String userEmailAddress = StringPool.BLANK;
171                    String userComments = StringPool.BLANK;
172                    String userJobTitle = StringPool.BLANK;
173    
174                    User user = null;
175    
176                    try {
177                            user = UserLocalServiceUtil.getUserById(article.getUserId());
178    
179                            userName = user.getFullName();
180                            userEmailAddress = user.getEmailAddress();
181                            userComments = user.getComments();
182                            userJobTitle = user.getJobTitle();
183                    }
184                    catch (PortalException pe) {
185                    }
186                    catch (SystemException se) {
187                    }
188    
189                    JournalUtil.addReservedEl(
190                            root, tokens,
191                            JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_NAME, userName);
192    
193                    JournalUtil.addReservedEl(
194                            root, tokens,
195                            JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
196                            userEmailAddress);
197    
198                    JournalUtil.addReservedEl(
199                            root, tokens,
200                            JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_COMMENTS,
201                            userComments);
202    
203                    JournalUtil.addReservedEl(
204                            root, tokens,
205                            JournalStructureConstants.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
206                            userJobTitle);
207            }
208    
209            public static void addRecentArticle(
210                    PortletRequest portletRequest, JournalArticle article) {
211    
212                    if (article != null) {
213                            Stack<JournalArticle> stack = getRecentArticles(portletRequest);
214    
215                            stack.push(article);
216                    }
217            }
218    
219            public static void addRecentStructure(
220                    PortletRequest portletRequest, JournalStructure structure) {
221    
222                    if (structure != null) {
223                            Stack<JournalStructure> stack = getRecentStructures(portletRequest);
224    
225                            stack.push(structure);
226                    }
227            }
228    
229            public static void addRecentTemplate(
230                    PortletRequest portletRequest, JournalTemplate template) {
231    
232                    if (template != null) {
233                            Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
234    
235                            stack.push(template);
236                    }
237            }
238    
239            public static void addReservedEl(
240                    Element root, Map<String, String> tokens, String name, Date value) {
241    
242                    addReservedEl(root, tokens, name, Time.getRFC822(value));
243            }
244    
245            public static void addReservedEl(
246                    Element root, Map<String, String> tokens, String name, double value) {
247    
248                    addReservedEl(root, tokens, name, String.valueOf(value));
249            }
250    
251            public static void addReservedEl(
252                    Element root, Map<String, String> tokens, String name, String value) {
253    
254                    // XML
255    
256                    if (root != null) {
257                            Element dynamicEl = SAXReaderUtil.createElement("dynamic-element");
258    
259                            dynamicEl.add(
260                                    SAXReaderUtil.createAttribute(dynamicEl, "name", name));
261                            dynamicEl.add(
262                                    SAXReaderUtil.createAttribute(dynamicEl, "type", "text"));
263    
264                            Element dynamicContent = SAXReaderUtil.createElement(
265                                    "dynamic-content");
266    
267                            //dynamicContent.setText("<![CDATA[" + value + "]]>");
268                            dynamicContent.setText(value);
269    
270                            dynamicEl.add(dynamicContent);
271    
272                            root.add(dynamicEl);
273                    }
274    
275                    // Tokens
276    
277                    tokens.put(
278                            StringUtil.replace(name, StringPool.DASH, StringPool.UNDERLINE),
279                            value);
280            }
281    
282            public static String formatVM(String vm) {
283                    return vm;
284            }
285    
286            public static String formatXML(Document doc) throws IOException {
287                    return doc.formattedString(XML_INDENT);
288            }
289    
290            public static String formatXML(String xml)
291                    throws org.dom4j.DocumentException, IOException {
292    
293                    // This is only supposed to format your xml, however, it will also
294                    // unwantingly change &#169; and other characters like it into their
295                    // respective readable versions
296    
297                    xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
298    
299                    xml = XMLFormatter.toString(xml, XML_INDENT);
300    
301                    xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
302    
303                    return xml;
304            }
305    
306            public static OrderByComparator getArticleOrderByComparator(
307                    String orderByCol, String orderByType) {
308    
309                    boolean orderByAsc = false;
310    
311                    if (orderByType.equals("asc")) {
312                            orderByAsc = true;
313                    }
314    
315                    OrderByComparator orderByComparator = null;
316    
317                    if (orderByCol.equals("create-date")) {
318                            orderByComparator = new ArticleCreateDateComparator(orderByAsc);
319                    }
320                    else if (orderByCol.equals("display-date")) {
321                            orderByComparator = new ArticleDisplayDateComparator(orderByAsc);
322                    }
323                    else if (orderByCol.equals("id")) {
324                            orderByComparator = new ArticleIDComparator(orderByAsc);
325                    }
326                    else if (orderByCol.equals("modified-date")) {
327                            orderByComparator = new ArticleModifiedDateComparator(orderByAsc);
328                    }
329                    else if (orderByCol.equals("review-date")) {
330                            orderByComparator = new ArticleReviewDateComparator(orderByAsc);
331                    }
332                    else if (orderByCol.equals("title")) {
333                            orderByComparator = new ArticleTitleComparator(orderByAsc);
334                    }
335                    else if (orderByCol.equals("version")) {
336                            orderByComparator = new ArticleVersionComparator(orderByAsc);
337                    }
338    
339                    return orderByComparator;
340            }
341    
342            public static String getEmailArticleAddedBody(
343                    PortletPreferences preferences) {
344    
345                    String emailArticleAddedBody = preferences.getValue(
346                            "email-article-added-body", StringPool.BLANK);
347    
348                    if (Validator.isNotNull(emailArticleAddedBody)) {
349                            return emailArticleAddedBody;
350                    }
351                    else {
352                            return ContentUtil.get(PropsUtil.get(
353                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_BODY));
354                    }
355            }
356    
357            public static boolean getEmailArticleAddedEnabled(
358                    PortletPreferences preferences) {
359    
360                    String emailArticleAddedEnabled = preferences.getValue(
361                            "email-article-added-enabled", StringPool.BLANK);
362    
363                    if (Validator.isNotNull(emailArticleAddedEnabled)) {
364                            return GetterUtil.getBoolean(emailArticleAddedEnabled);
365                    }
366                    else {
367                            return GetterUtil.getBoolean(PropsUtil.get(
368                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_ENABLED));
369                    }
370            }
371    
372            public static String getEmailArticleAddedSubject(
373                    PortletPreferences preferences) {
374    
375                    String emailArticleAddedSubject = preferences.getValue(
376                            "email-article-added-subject", StringPool.BLANK);
377    
378                    if (Validator.isNotNull(emailArticleAddedSubject)) {
379                            return emailArticleAddedSubject;
380                    }
381                    else {
382                            return ContentUtil.get(PropsUtil.get(
383                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_ADDED_SUBJECT));
384                    }
385            }
386    
387            public static String getEmailArticleApprovalDeniedBody(
388                    PortletPreferences preferences) {
389    
390                    String emailArticleApprovalDeniedBody = preferences.getValue(
391                            "email-article-approval-denied-body", StringPool.BLANK);
392    
393                    if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
394                            return emailArticleApprovalDeniedBody;
395                    }
396                    else {
397                            return ContentUtil.get(PropsUtil.get(
398                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
399                    }
400            }
401    
402            public static boolean getEmailArticleApprovalDeniedEnabled(
403                    PortletPreferences preferences) {
404    
405                    String emailArticleApprovalDeniedEnabled = preferences.getValue(
406                            "email-article-approval-denied-enabled", StringPool.BLANK);
407    
408                    if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
409                            return GetterUtil.getBoolean(emailArticleApprovalDeniedEnabled);
410                    }
411                    else {
412                            return GetterUtil.getBoolean(PropsUtil.get(
413                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
414                    }
415            }
416    
417            public static String getEmailArticleApprovalDeniedSubject(
418                    PortletPreferences preferences) {
419    
420                    String emailArticleApprovalDeniedSubject = preferences.getValue(
421                            "email-article-approval-denied-subject", StringPool.BLANK);
422    
423                    if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
424                            return emailArticleApprovalDeniedSubject;
425                    }
426                    else {
427                            return ContentUtil.get(PropsUtil.get(
428                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
429                    }
430            }
431    
432            public static String getEmailArticleApprovalGrantedBody(
433                    PortletPreferences preferences) {
434    
435                    String emailArticleApprovalGrantedBody = preferences.getValue(
436                            "email-article-approval-granted-body", StringPool.BLANK);
437    
438                    if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
439                            return emailArticleApprovalGrantedBody;
440                    }
441                    else {
442                            return ContentUtil.get(PropsUtil.get(
443                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
444                    }
445            }
446    
447            public static boolean getEmailArticleApprovalGrantedEnabled(
448                    PortletPreferences preferences) {
449    
450                    String emailArticleApprovalGrantedEnabled = preferences.getValue(
451                            "email-article-approval-granted-enabled", StringPool.BLANK);
452    
453                    if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
454                            return GetterUtil.getBoolean(emailArticleApprovalGrantedEnabled);
455                    }
456                    else {
457                            return GetterUtil.getBoolean(PropsUtil.get(
458                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
459                    }
460            }
461    
462            public static String getEmailArticleApprovalGrantedSubject(
463                    PortletPreferences preferences) {
464    
465                    String emailArticleApprovalGrantedSubject = preferences.getValue(
466                            "email-article-approval-granted-subject", StringPool.BLANK);
467    
468                    if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
469                            return emailArticleApprovalGrantedSubject;
470                    }
471                    else {
472                            return ContentUtil.get(PropsUtil.get(
473                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
474                    }
475            }
476    
477            public static String getEmailArticleApprovalRequestedBody(
478                    PortletPreferences preferences) {
479    
480                    String emailArticleApprovalRequestedBody = preferences.getValue(
481                            "email-article-approval-requested-body", StringPool.BLANK);
482    
483                    if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
484                            return emailArticleApprovalRequestedBody;
485                    }
486                    else {
487                            return ContentUtil.get(PropsUtil.get(
488                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
489                    }
490            }
491    
492            public static boolean getEmailArticleApprovalRequestedEnabled(
493                    PortletPreferences preferences) {
494    
495                    String emailArticleApprovalRequestedEnabled = preferences.getValue(
496                            "email-article-approval-requested-enabled", StringPool.BLANK);
497    
498                    if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
499                            return GetterUtil.getBoolean(emailArticleApprovalRequestedEnabled);
500                    }
501                    else {
502                            return GetterUtil.getBoolean(PropsUtil.get(
503                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
504                    }
505            }
506    
507            public static String getEmailArticleApprovalRequestedSubject(
508                    PortletPreferences preferences) {
509    
510                    String emailArticleApprovalRequestedSubject = preferences.getValue(
511                            "email-article-approval-requested-subject", StringPool.BLANK);
512    
513                    if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
514                            return emailArticleApprovalRequestedSubject;
515                    }
516                    else {
517                            return ContentUtil.get(PropsUtil.get(
518                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
519                    }
520            }
521    
522            public static String getEmailArticleReviewBody(
523                    PortletPreferences preferences) {
524    
525                    String emailArticleReviewBody = preferences.getValue(
526                            "email-article-review-body", StringPool.BLANK);
527    
528                    if (Validator.isNotNull(emailArticleReviewBody)) {
529                            return emailArticleReviewBody;
530                    }
531                    else {
532                            return ContentUtil.get(PropsUtil.get(
533                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
534                    }
535            }
536    
537            public static boolean getEmailArticleReviewEnabled(
538                    PortletPreferences preferences) {
539    
540                    String emailArticleReviewEnabled = preferences.getValue(
541                            "email-article-review-enabled", StringPool.BLANK);
542    
543                    if (Validator.isNotNull(emailArticleReviewEnabled)) {
544                            return GetterUtil.getBoolean(emailArticleReviewEnabled);
545                    }
546                    else {
547                            return GetterUtil.getBoolean(PropsUtil.get(
548                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
549                    }
550            }
551    
552            public static String getEmailArticleReviewSubject(
553                    PortletPreferences preferences) {
554    
555                    String emailArticleReviewSubject = preferences.getValue(
556                            "email-article-review-subject", StringPool.BLANK);
557    
558                    if (Validator.isNotNull(emailArticleReviewSubject)) {
559                            return emailArticleReviewSubject;
560                    }
561                    else {
562                            return ContentUtil.get(PropsUtil.get(
563                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
564                    }
565            }
566    
567            public static String getEmailArticleUpdatedBody(
568                    PortletPreferences preferences) {
569    
570                    String emailArticleUpdatedBody = preferences.getValue(
571                            "email-article-updated-body", StringPool.BLANK);
572    
573                    if (Validator.isNotNull(emailArticleUpdatedBody)) {
574                            return emailArticleUpdatedBody;
575                    }
576                    else {
577                            return ContentUtil.get(PropsUtil.get(
578                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_BODY));
579                    }
580            }
581    
582            public static boolean getEmailArticleUpdatedEnabled(
583                    PortletPreferences preferences) {
584    
585                    String emailArticleUpdatedEnabled = preferences.getValue(
586                            "email-article-updated-enabled", StringPool.BLANK);
587    
588                    if (Validator.isNotNull(emailArticleUpdatedEnabled)) {
589                            return GetterUtil.getBoolean(emailArticleUpdatedEnabled);
590                    }
591                    else {
592                            return GetterUtil.getBoolean(PropsUtil.get(
593                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_ENABLED));
594                    }
595            }
596    
597            public static String getEmailArticleUpdatedSubject(
598                    PortletPreferences preferences) {
599    
600                    String emailArticleUpdatedSubject = preferences.getValue(
601                            "email-article-updated-subject", StringPool.BLANK);
602    
603                    if (Validator.isNotNull(emailArticleUpdatedSubject)) {
604                            return emailArticleUpdatedSubject;
605                    }
606                    else {
607                            return ContentUtil.get(PropsUtil.get(
608                                    PropsKeys.JOURNAL_EMAIL_ARTICLE_UPDATED_SUBJECT));
609                    }
610            }
611    
612            public static String getEmailFromAddress(PortletPreferences preferences) {
613                    String emailFromAddress = PropsUtil.get(
614                            PropsKeys.JOURNAL_EMAIL_FROM_ADDRESS);
615    
616                    return preferences.getValue("email-from-address", emailFromAddress);
617            }
618    
619            public static String getEmailFromName(PortletPreferences preferences) {
620                    String emailFromName = PropsUtil.get(
621                            PropsKeys.JOURNAL_EMAIL_FROM_NAME);
622    
623                    return preferences.getValue("email-from-name", emailFromName);
624            }
625    
626            public static String getMailId(String mx, String articleId) {
627                    StringBundler sb = new StringBundler(8);
628    
629                    sb.append(StringPool.LESS_THAN);
630                    sb.append(POP_PORTLET_PREFIX);
631                    sb.append(articleId);
632                    sb.append(StringPool.AT);
633                    sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
634                    sb.append(StringPool.PERIOD);
635                    sb.append(mx);
636                    sb.append(StringPool.GREATER_THAN);
637    
638                    return sb.toString();
639            }
640    
641            public static Stack<JournalArticle> getRecentArticles(
642                    PortletRequest portletRequest) {
643    
644                    PortletSession portletSession = portletRequest.getPortletSession();
645    
646                    Stack<JournalArticle> recentArticles =
647                            (Stack<JournalArticle>)portletSession.getAttribute(
648                                    WebKeys.JOURNAL_RECENT_ARTICLES);
649    
650                    if (recentArticles == null) {
651                            recentArticles = new FiniteUniqueStack<JournalArticle>(
652                                    MAX_STACK_SIZE);
653    
654                            portletSession.setAttribute(
655                                    WebKeys.JOURNAL_RECENT_ARTICLES, recentArticles);
656                    }
657    
658                    return recentArticles;
659            }
660    
661            public static Stack<JournalStructure> getRecentStructures(
662                    PortletRequest portletRequest) {
663    
664                    PortletSession portletSession = portletRequest.getPortletSession();
665    
666                    Stack<JournalStructure> recentStructures =
667                            (Stack<JournalStructure>)portletSession.getAttribute(
668                                    WebKeys.JOURNAL_RECENT_STRUCTURES);
669    
670                    if (recentStructures == null) {
671                            recentStructures = new FiniteUniqueStack<JournalStructure>(
672                                    MAX_STACK_SIZE);
673    
674                            portletSession.setAttribute(
675                                    WebKeys.JOURNAL_RECENT_STRUCTURES, recentStructures);
676                    }
677    
678                    return recentStructures;
679            }
680    
681            public static Stack<JournalTemplate> getRecentTemplates(
682                    PortletRequest portletRequest) {
683    
684                    PortletSession portletSession = portletRequest.getPortletSession();
685    
686                    Stack<JournalTemplate> recentTemplates =
687                            (Stack<JournalTemplate>)portletSession.getAttribute(
688                                    WebKeys.JOURNAL_RECENT_TEMPLATES);
689    
690                    if (recentTemplates == null) {
691                            recentTemplates = new FiniteUniqueStack<JournalTemplate>(
692                                    MAX_STACK_SIZE);
693    
694                            portletSession.setAttribute(
695                                    WebKeys.JOURNAL_RECENT_TEMPLATES, recentTemplates);
696                    }
697    
698                    return recentTemplates;
699            }
700    
701            public static String getTemplateScript(
702                    JournalTemplate template, Map<String, String> tokens, String languageId,
703                    boolean transform) {
704    
705                    String script = template.getXsl();
706    
707                    if (transform) {
708    
709                            // Listeners
710    
711                            String[] listeners =
712                                    PropsUtil.getArray(PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
713    
714                            for (int i = 0; i < listeners.length; i++) {
715                                    TransformerListener listener = null;
716    
717                                    try {
718                                            listener =
719                                                    (TransformerListener)Class.forName(
720                                                            listeners[i]).newInstance();
721    
722                                            listener.setTemplateDriven(true);
723                                            listener.setLanguageId(languageId);
724                                            listener.setTokens(tokens);
725                                    }
726                                    catch (Exception e) {
727                                            _log.error(e, e);
728                                    }
729    
730                                    // Modify transform script
731    
732                                    if (listener != null) {
733                                            script = listener.onScript(script);
734                                    }
735                            }
736                    }
737    
738                    return script;
739            }
740    
741            public static String getTemplateScript(
742                            long groupId, String templateId, Map<String, String> tokens,
743                            String languageId)
744                    throws PortalException, SystemException {
745    
746                    return getTemplateScript(groupId, templateId, tokens, languageId, true);
747            }
748    
749            public static String getTemplateScript(
750                            long groupId, String templateId, Map<String, String> tokens,
751                            String languageId, boolean transform)
752                    throws PortalException, SystemException {
753    
754                    JournalTemplate template = JournalTemplateLocalServiceUtil.getTemplate(
755                            groupId, templateId);
756    
757                    return getTemplateScript(template, tokens, languageId, transform);
758            }
759    
760            public static Map<String, String> getTokens(
761                            long groupId, ThemeDisplay themeDisplay)
762                    throws PortalException, SystemException {
763    
764                    return getTokens(groupId, themeDisplay, null);
765            }
766    
767            public static Map<String, String> getTokens(
768                            long groupId, ThemeDisplay themeDisplay, String xmlRequest)
769                    throws PortalException, SystemException {
770    
771                    Map<String, String> tokens = new HashMap<String, String>();
772    
773                    if (themeDisplay != null) {
774                            _populateTokens(tokens, groupId, themeDisplay);
775                    }
776                    else if (Validator.isNotNull(xmlRequest)) {
777                            try {
778                                    _populateTokens(tokens, groupId, xmlRequest);
779                            }
780                            catch (Exception e) {
781                                    if (_log.isWarnEnabled()) {
782                                            _log.warn(e, e);
783                                    }
784                            }
785                    }
786    
787                    return tokens;
788            }
789    
790            public static String getUrlTitle(long id, String title) {
791                    title = title.trim().toLowerCase();
792    
793                    if (Validator.isNull(title) || Validator.isNumber(title) ||
794                            title.equals("rss")) {
795    
796                            return String.valueOf(id);
797                    }
798                    else {
799                            return FriendlyURLNormalizer.normalize(
800                                    title, _URL_TITLE_REPLACE_CHARS);
801                    }
802            }
803    
804            public static String mergeArticleContent(
805                    String curContent, String newContent) {
806    
807                    try {
808                            Document curDocument = SAXReaderUtil.read(curContent);
809                            Document newDocument = SAXReaderUtil.read(newContent);
810    
811                            Element curRoot = curDocument.getRootElement();
812                            Element newRoot = newDocument.getRootElement();
813    
814                            curRoot.addAttribute(
815                                    "default-locale",
816                                    newRoot.attributeValue("default-locale"));
817                            curRoot.addAttribute(
818                                    "available-locales",
819                                    newRoot.attributeValue("available-locales"));
820    
821                            _mergeArticleContentUpdate(
822                                    curDocument, newRoot,
823                                    LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
824                            _mergeArticleContentDelete(curRoot, newDocument);
825    
826                            curContent = JournalUtil.formatXML(curDocument);
827                    }
828                    catch (Exception e) {
829                            _log.error(e, e);
830                    }
831    
832                    return curContent;
833            }
834    
835            public static void removeArticleLocale(Element el, String languageId)
836                    throws PortalException, SystemException {
837    
838                    for (Element dynamicEl : el.elements("dynamic-element")) {
839                            for (Element dynamicContentEl :
840                                            dynamicEl.elements("dynamic-content")) {
841    
842                                    String curLanguageId = GetterUtil.getString(
843                                            dynamicContentEl.attributeValue("language-id"));
844    
845                                    if (curLanguageId.equals(languageId)) {
846                                            long id = GetterUtil.getLong(
847                                                    dynamicContentEl.attributeValue("id"));
848    
849                                            if (id > 0) {
850                                                    ImageLocalServiceUtil.deleteImage(id);
851                                            }
852    
853                                            dynamicContentEl.detach();
854                                    }
855                            }
856    
857                            removeArticleLocale(dynamicEl, languageId);
858                    }
859            }
860    
861            public static String removeArticleLocale(
862                    String content, String languageId) {
863    
864                    try {
865                            Document doc = SAXReaderUtil.read(content);
866    
867                            Element root = doc.getRootElement();
868    
869                            String availableLocales = root.attributeValue("available-locales");
870    
871                            if (availableLocales == null) {
872                                    return content;
873                            }
874    
875                            availableLocales = StringUtil.remove(availableLocales, languageId);
876    
877                            if (availableLocales.endsWith(",")) {
878                                    availableLocales = availableLocales.substring(
879                                            0, availableLocales.length() - 1);
880                            }
881    
882                            root.addAttribute("available-locales", availableLocales);
883    
884                            removeArticleLocale(root, languageId);
885    
886                            content = formatXML(doc);
887                    }
888                    catch (Exception e) {
889                            _log.error(e, e);
890                    }
891    
892                    return content;
893            }
894    
895            public static String removeOldContent(String content, String xsd) {
896                    try {
897                            Document contentDoc = SAXReaderUtil.read(content);
898                            Document xsdDoc = SAXReaderUtil.read(xsd);
899    
900                            Element contentRoot = contentDoc.getRootElement();
901    
902                            Stack<String> path = new Stack<String>();
903    
904                            path.push(contentRoot.getName());
905    
906                            _removeOldContent(path, contentRoot, xsdDoc);
907    
908                            content = formatXML(contentDoc);
909                    }
910                    catch (Exception e) {
911                            _log.error(e, e);
912                    }
913    
914                    return content;
915            }
916    
917            public static void removeRecentArticle(
918                    PortletRequest portletRequest, String articleId) {
919    
920                    removeRecentArticle(portletRequest, articleId, 0);
921            }
922    
923            public static void removeRecentArticle(
924                    PortletRequest portletRequest, String articleId, double version) {
925    
926                    Stack<JournalArticle> stack = getRecentArticles(portletRequest);
927    
928                    Iterator<JournalArticle> itr = stack.iterator();
929    
930                    while (itr.hasNext()) {
931                            JournalArticle journalArticle = itr.next();
932    
933                            if (journalArticle.getArticleId().equals(articleId) &&
934                                    ((journalArticle.getVersion() == version) ||
935                                     (version == 0))) {
936    
937                                    itr.remove();
938                            }
939                    }
940            }
941    
942            public static void removeRecentStructure(
943                    PortletRequest portletRequest, String structureId) {
944    
945                    Stack<JournalStructure> stack = getRecentStructures(portletRequest);
946    
947                    Iterator<JournalStructure> itr = stack.iterator();
948    
949                    while (itr.hasNext()) {
950                            JournalStructure journalStructure = itr.next();
951    
952                            if (journalStructure.getStructureId().equals(structureId)) {
953                                    itr.remove();
954    
955                                    break;
956                            }
957                    }
958            }
959    
960            public static void removeRecentTemplate(
961                    PortletRequest portletRequest, String templateId) {
962    
963                    Stack<JournalTemplate> stack = getRecentTemplates(portletRequest);
964    
965                    Iterator<JournalTemplate> itr = stack.iterator();
966    
967                    while (itr.hasNext()) {
968                            JournalTemplate journalTemplate = itr.next();
969    
970                            if (journalTemplate.getTemplateId().equals(templateId)) {
971                                    itr.remove();
972    
973                                    break;
974                            }
975                    }
976            }
977    
978            public static String transform(
979                            ThemeDisplay themeDisplay, Map<String, String> tokens,
980                            String viewMode, String languageId, String xml, String script,
981                            String langType)
982                    throws Exception {
983    
984                    // Setup Listeners
985    
986                    if (_log.isDebugEnabled()) {
987                            _log.debug("Language " + languageId);
988                    }
989    
990                    if (Validator.isNull(viewMode)) {
991                            viewMode = Constants.VIEW;
992                    }
993    
994                    if (_logTokens.isDebugEnabled()) {
995                            String tokensString = PropertiesUtil.list(tokens);
996    
997                            _logTokens.debug(tokensString);
998                    }
999    
1000                    if (_logTransformBefore.isDebugEnabled()) {
1001                            _logTransformBefore.debug(xml);
1002                    }
1003    
1004                    List<TransformerListener> listenersList =
1005                            new ArrayList<TransformerListener>();
1006    
1007                    String[] listeners = PropsUtil.getArray(
1008                            PropsKeys.JOURNAL_TRANSFORMER_LISTENER);
1009    
1010                    for (int i = 0; i < listeners.length; i++) {
1011                            TransformerListener listener = null;
1012    
1013                            try {
1014                                    if (_log.isDebugEnabled()) {
1015                                            _log.debug("Instantiate listener " + listeners[i]);
1016                                    }
1017    
1018                                    boolean templateDriven = Validator.isNotNull(langType);
1019    
1020                                    listener = (TransformerListener)Class.forName(
1021                                            listeners[i]).newInstance();
1022    
1023                                    listener.setTemplateDriven(templateDriven);
1024                                    listener.setLanguageId(languageId);
1025                                    listener.setTokens(tokens);
1026    
1027                                    listenersList.add(listener);
1028                            }
1029                            catch (Exception e) {
1030                                    _log.error(e, e);
1031                            }
1032    
1033                            // Modify XML
1034    
1035                            if (_logXmlBeforeListener.isDebugEnabled()) {
1036                                    _logXmlBeforeListener.debug(xml);
1037                            }
1038    
1039                            if (listener != null) {
1040                                    xml = listener.onXml(xml);
1041    
1042                                    if (_logXmlAfterListener.isDebugEnabled()) {
1043                                            _logXmlAfterListener.debug(xml);
1044                                    }
1045                            }
1046    
1047                            // Modify script
1048    
1049                            if (_logScriptBeforeListener.isDebugEnabled()) {
1050                                    _logScriptBeforeListener.debug(script);
1051                            }
1052    
1053                            if (listener != null) {
1054                                    script = listener.onScript(script);
1055    
1056                                    if (_logScriptAfterListener.isDebugEnabled()) {
1057                                            _logScriptAfterListener.debug(script);
1058                                    }
1059                            }
1060                    }
1061    
1062                    // Transform
1063    
1064                    String output = null;
1065    
1066                    if (Validator.isNull(langType)) {
1067                            output = LocalizationUtil.getLocalization(xml, languageId);
1068                    }
1069                    else {
1070                            String templateParserClassName = PropsUtil.get(
1071                                    PropsKeys.JOURNAL_TEMPLATE_LANGUAGE_PARSER,
1072                                    new Filter(langType));
1073    
1074                            if (_log.isDebugEnabled()) {
1075                                    _log.debug(
1076                                            "Template parser class name " + templateParserClassName);
1077                            }
1078    
1079                            if (Validator.isNotNull(templateParserClassName)) {
1080                                    TemplateParser templateParser =
1081                                            (TemplateParser)InstancePool.get(templateParserClassName);
1082    
1083                                    if (templateParser == null) {
1084                                            throw new TransformException(
1085                                                    "No template parser found for " +
1086                                                            templateParserClassName);
1087                                    }
1088    
1089                                    output = templateParser.transform(
1090                                            themeDisplay, tokens, viewMode, languageId, xml, script);
1091                            }
1092                    }
1093    
1094                    // Postprocess output
1095    
1096                    for (int i = 0; i < listenersList.size(); i++) {
1097                            TransformerListener listener = listenersList.get(i);
1098    
1099                            // Modify output
1100    
1101                            if (_logOutputBeforeListener.isDebugEnabled()) {
1102                                    _logOutputBeforeListener.debug(output);
1103                            }
1104    
1105                            output = listener.onOutput(output);
1106    
1107                            if (_logOutputAfterListener.isDebugEnabled()) {
1108                                    _logOutputAfterListener.debug(output);
1109                            }
1110                    }
1111    
1112                    if (_logTransfromAfter.isDebugEnabled()) {
1113                            _logTransfromAfter.debug(output);
1114                    }
1115    
1116                    return output;
1117            }
1118    
1119            private static void _addElementOptions (
1120                    Element curContentElement, Element newContentElement) {
1121    
1122                    List<Element> newElementOptions = newContentElement.elements("option");
1123    
1124                    for (Element newElementOption : newElementOptions) {
1125                            Element curElementOption = SAXReaderUtil.createElement("option");
1126    
1127                            curElementOption.addCDATA(newElementOption.getText());
1128    
1129                            curContentElement.add(curElementOption);
1130                    }
1131            }
1132    
1133            private static Element _getElementByInstanceId(
1134                    Document document, String instanceId) {
1135    
1136                    XPath xPathSelector = SAXReaderUtil.createXPath(
1137                            "//dynamic-element[@instance-id='" + instanceId + "']");
1138    
1139                    List<Node> nodes = xPathSelector.selectNodes(document);
1140    
1141                    if (nodes.size() == 1) {
1142                            return (Element)nodes.get(0);
1143                    }
1144                    else {
1145                            return null;
1146                    }
1147            }
1148    
1149            private static void _mergeArticleContentDelete(
1150                            Element curParentElement, Document newDocument)
1151                    throws Exception {
1152    
1153                    List<Element> curElements = curParentElement.elements(
1154                            "dynamic-element");
1155    
1156                    for (int i = 0; i < curElements.size(); i++) {
1157                            Element curElement = curElements.get(i);
1158    
1159                            _mergeArticleContentDelete(curElement, newDocument);
1160    
1161                            String instanceId = curElement.attributeValue("instance-id");
1162    
1163                            Element newElement = _getElementByInstanceId(
1164                                    newDocument, instanceId);
1165    
1166                            if (newElement == null) {
1167                                    curElement.detach();
1168    
1169                                    String type = curElement.attributeValue("type");
1170    
1171                                    if (type.equals("image")) {
1172                                            _mergeArticleContentDeleteImages(
1173                                                    curElement.elements("dynamic-content"));
1174                                    }
1175                            }
1176                    }
1177            }
1178    
1179            private static void _mergeArticleContentDeleteImages(List<Element> elements)
1180                    throws Exception {
1181    
1182                    for (Element element : elements) {
1183                            long articleImageId = GetterUtil.getLong(
1184                                    element.attributeValue("id"));
1185    
1186                            JournalArticleImageLocalServiceUtil.deleteArticleImage(
1187                                    articleImageId);
1188                    }
1189            }
1190    
1191            private static void _mergeArticleContentUpdate(
1192                            Document curDocument, Element newParentElement, Element newElement,
1193                            int pos, String defaultLocale)
1194                    throws Exception {
1195    
1196                    _mergeArticleContentUpdate(curDocument, newElement, defaultLocale);
1197    
1198                    String instanceId = newElement.attributeValue("instance-id");
1199    
1200                    Element curElement = _getElementByInstanceId(curDocument, instanceId);
1201    
1202                    if (curElement != null) {
1203                            _mergeArticleContentUpdate(curElement, newElement, defaultLocale);
1204                    }
1205                    else {
1206                            String parentInstanceId = newParentElement.attributeValue(
1207                                    "instance-id");
1208    
1209                            if (Validator.isNull(parentInstanceId)) {
1210                                    Element curRoot = curDocument.getRootElement();
1211    
1212                                    List<Element> curRootElements = curRoot.elements();
1213    
1214                                    curRootElements.add(pos, newElement.createCopy());
1215                            }
1216                            else {
1217                                    Element curParentElement = _getElementByInstanceId(
1218                                            curDocument, parentInstanceId);
1219    
1220                                    if (curParentElement != null) {
1221                                            List<Element> curParentElements =
1222                                                    curParentElement.elements();
1223    
1224                                            curParentElements.add(pos, newElement.createCopy());
1225                                    }
1226                            }
1227                    }
1228            }
1229    
1230            private static void _mergeArticleContentUpdate(
1231                            Document curDocument, Element newParentElement,
1232                            String defaultLocale)
1233                    throws Exception {
1234    
1235                    List<Element> newElements = newParentElement.elements(
1236                            "dynamic-element");
1237    
1238                    for (int i = 0; i < newElements.size(); i++) {
1239                            Element newElement = newElements.get(i);
1240    
1241                            _mergeArticleContentUpdate(
1242                                    curDocument, newParentElement, newElement, i, defaultLocale);
1243                    }
1244            }
1245    
1246            private static void _mergeArticleContentUpdate(
1247                    Element curElement, Element newElement, String defaultLocale) {
1248    
1249                    Attribute curTypeAttribute = curElement.attribute("type");
1250                    Attribute newTypeAttribute = newElement.attribute("type");
1251    
1252                    curTypeAttribute.setValue(newTypeAttribute.getValue());
1253    
1254                    Attribute curIndexTypeAttribute = curElement.attribute("index-type");
1255                    Attribute newIndexTypeAttribute = newElement.attribute("index-type");
1256    
1257                    if ((curIndexTypeAttribute != null) &&
1258                            (newIndexTypeAttribute != null)) {
1259    
1260                            curIndexTypeAttribute.setValue(newIndexTypeAttribute.getValue());
1261                    }
1262    
1263                    Element newContentElement = newElement.elements(
1264                            "dynamic-content").get(0);
1265    
1266                    String newLanguageId = newContentElement.attributeValue("language-id");
1267                    String newValue = newContentElement.getText();
1268    
1269                    String indexType = newElement.attributeValue("index-type");
1270    
1271                    if (Validator.isNotNull(indexType)) {
1272                            curElement.addAttribute("index-type", indexType);
1273                    }
1274    
1275                    List<Element> curContentElements = curElement.elements(
1276                            "dynamic-content");
1277    
1278                    if (Validator.isNull(newLanguageId)) {
1279                            for (Element curContentElement : curContentElements) {
1280                                    curContentElement.detach();
1281                            }
1282    
1283                            Element curContentElement = SAXReaderUtil.createElement(
1284                                    "dynamic-content");
1285    
1286                            if (newContentElement.element("option") != null) {
1287                                    _addElementOptions(curContentElement, newContentElement);
1288                            }
1289                            else {
1290                                    curContentElement.addCDATA(newValue);
1291                            }
1292    
1293                            curElement.add(curContentElement);
1294                    }
1295                    else {
1296                            boolean alreadyExists = false;
1297    
1298                            for (Element curContentElement : curContentElements) {
1299                                    String curLanguageId = curContentElement.attributeValue(
1300                                            "language-id");
1301    
1302                                    if (newLanguageId.equals(curLanguageId)) {
1303                                            alreadyExists = true;
1304    
1305                                            curContentElement.clearContent();
1306    
1307                                            if (newContentElement.element("option") != null) {
1308                                                    _addElementOptions(
1309                                                            curContentElement, newContentElement);
1310                                            }
1311                                            else {
1312                                                    curContentElement.addCDATA(newValue);
1313                                            }
1314    
1315                                            break;
1316                                    }
1317                            }
1318    
1319                            if (!alreadyExists) {
1320                                    Element curContentElement = curContentElements.get(0);
1321    
1322                                    String curLanguageId = curContentElement.attributeValue(
1323                                            "language-id");
1324    
1325                                    if (Validator.isNull(curLanguageId)) {
1326                                            curContentElement.detach();
1327                                    }
1328    
1329                                    curElement.add(newContentElement.createCopy());
1330                            }
1331                    }
1332            }
1333    
1334            private static void _populateCustomTokens(Map<String, String> tokens) {
1335                    if (_customTokens == null) {
1336                            synchronized (JournalUtil.class) {
1337                                    _customTokens = new HashMap<String, String>();
1338    
1339                                    for (String customToken :
1340                                                    PropsValues.JOURNAL_ARTICLE_CUSTOM_TOKENS) {
1341    
1342                                            String value = PropsUtil.get(
1343                                                    PropsKeys.JOURNAL_ARTICLE_CUSTOM_TOKEN_VALUE,
1344                                                    new Filter(customToken));
1345    
1346                                            _customTokens.put(customToken, value);
1347                                    }
1348                            }
1349                    }
1350    
1351                    if (!_customTokens.isEmpty()) {
1352                            tokens.putAll(_customTokens);
1353                    }
1354            }
1355    
1356            private static void _populateTokens(
1357                            Map<String, String> tokens, long groupId, String xmlRequest)
1358                    throws Exception {
1359    
1360                    Document request = SAXReaderUtil.read(xmlRequest);
1361    
1362                    Element root = request.getRootElement();
1363    
1364                    Element themeDisplayEl = root.element("theme-display");
1365    
1366                    Layout layout = LayoutLocalServiceUtil.getLayout(
1367                            GetterUtil.getLong(themeDisplayEl.elementText("plid")));
1368    
1369                    Group group = layout.getGroup();
1370    
1371                    LayoutSet layoutSet = layout.getLayoutSet();
1372    
1373                    String friendlyUrlCurrent = null;
1374    
1375                    if (layout.isPublicLayout()) {
1376                            friendlyUrlCurrent = themeDisplayEl.elementText(
1377                                    "path-friendly-url-public");
1378                    }
1379                    else if (group.isUserGroup()) {
1380                            friendlyUrlCurrent = themeDisplayEl.elementText(
1381                                    "path-friendly-url-private-user");
1382                    }
1383                    else {
1384                            friendlyUrlCurrent = themeDisplayEl.elementText(
1385                                    "path-friendly-url-private-group");
1386                    }
1387    
1388                    String layoutSetFriendlyUrl = StringPool.BLANK;
1389    
1390                    String virtualHost = layoutSet.getVirtualHost();
1391    
1392                    if (Validator.isNull(virtualHost) ||
1393                            !virtualHost.equals(themeDisplayEl.elementText("server-name"))) {
1394    
1395                            layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1396                    }
1397    
1398                    tokens.put("cdn_host", themeDisplayEl.elementText("cdn-host"));
1399                    tokens.put("company_id", themeDisplayEl.elementText("company-id"));
1400                    tokens.put("friendly_url_current", friendlyUrlCurrent);
1401                    tokens.put(
1402                            "friendly_url_private_group",
1403                            themeDisplayEl.elementText("path-friendly-url-private-group"));
1404                    tokens.put(
1405                            "friendly_url_private_user",
1406                            themeDisplayEl.elementText("path-friendly-url-private-user"));
1407                    tokens.put(
1408                            "friendly_url_public",
1409                            themeDisplayEl.elementText("path-friendly-url-public"));
1410                    tokens.put("group_friendly_url", group.getFriendlyURL());
1411                    tokens.put("group_id", String.valueOf(groupId));
1412                    tokens.put("image_path", themeDisplayEl.elementText("path-image"));
1413                    tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1414                    tokens.put("main_path", themeDisplayEl.elementText("path-main"));
1415                    tokens.put("portal_ctx", themeDisplayEl.elementText("path-context"));
1416                    tokens.put(
1417                            "portal_url",
1418                            HttpUtil.removeProtocol(themeDisplayEl.elementText("url-portal")));
1419                    tokens.put(
1420                            "protocol",
1421                            HttpUtil.getProtocol(themeDisplayEl.elementText("url-portal")));
1422                    tokens.put("root_path", themeDisplayEl.elementText("path-context"));
1423                    tokens.put(
1424                            "theme_image_path",
1425                            themeDisplayEl.elementText("path-theme-images"));
1426    
1427                    _populateCustomTokens(tokens);
1428    
1429                    // Deprecated tokens
1430    
1431                    tokens.put(
1432                            "friendly_url",
1433                            themeDisplayEl.elementText("path-friendly-url-public"));
1434                    tokens.put(
1435                            "friendly_url_private",
1436                            themeDisplayEl.elementText("path-friendly-url-private-group"));
1437                    tokens.put(
1438                            "page_url", themeDisplayEl.elementText("path-friendly-url-public"));
1439            }
1440    
1441            private static void _populateTokens(
1442                            Map<String, String> tokens, long groupId, ThemeDisplay themeDisplay)
1443                    throws PortalException, SystemException {
1444    
1445                    Layout layout = themeDisplay.getLayout();
1446    
1447                    Group group = layout.getGroup();
1448    
1449                    LayoutSet layoutSet = layout.getLayoutSet();
1450    
1451                    String friendlyUrlCurrent = null;
1452    
1453                    if (layout.isPublicLayout()) {
1454                            friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPublic();
1455                    }
1456                    else if (group.isUserGroup()) {
1457                            friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateUser();
1458                    }
1459                    else {
1460                            friendlyUrlCurrent = themeDisplay.getPathFriendlyURLPrivateGroup();
1461                    }
1462    
1463                    String layoutSetFriendlyUrl = StringPool.BLANK;
1464    
1465                    String virtualHost = layoutSet.getVirtualHost();
1466    
1467                    if (Validator.isNull(virtualHost) ||
1468                            !virtualHost.equals(themeDisplay.getServerName())) {
1469    
1470                            layoutSetFriendlyUrl = friendlyUrlCurrent + group.getFriendlyURL();
1471                    }
1472    
1473                    tokens.put("cdn_host", themeDisplay.getCDNHost());
1474                    tokens.put("company_id", String.valueOf(themeDisplay.getCompanyId()));
1475                    tokens.put("friendly_url_current", friendlyUrlCurrent);
1476                    tokens.put(
1477                            "friendly_url_private_group",
1478                            themeDisplay.getPathFriendlyURLPrivateGroup());
1479                    tokens.put(
1480                            "friendly_url_private_user",
1481                            themeDisplay.getPathFriendlyURLPrivateUser());
1482                    tokens.put(
1483                            "friendly_url_public", themeDisplay.getPathFriendlyURLPublic());
1484                    tokens.put("group_friendly_url", group.getFriendlyURL());
1485                    tokens.put("group_id", String.valueOf(groupId));
1486                    tokens.put("image_path", themeDisplay.getPathImage());
1487                    tokens.put("layout_set_friendly_url", layoutSetFriendlyUrl);
1488                    tokens.put("main_path", themeDisplay.getPathMain());
1489                    tokens.put("portal_ctx", themeDisplay.getPathContext());
1490                    tokens.put(
1491                            "portal_url", HttpUtil.removeProtocol(themeDisplay.getURLPortal()));
1492                    tokens.put(
1493                            "protocol", HttpUtil.getProtocol(themeDisplay.getURLPortal()));
1494                    tokens.put("root_path", themeDisplay.getPathContext());
1495                    tokens.put("theme_image_path", themeDisplay.getPathThemeImages());
1496    
1497                    _populateCustomTokens(tokens);
1498    
1499                    // Deprecated tokens
1500    
1501                    tokens.put("friendly_url", themeDisplay.getPathFriendlyURLPublic());
1502                    tokens.put(
1503                            "friendly_url_private",
1504                            themeDisplay.getPathFriendlyURLPrivateGroup());
1505                    tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
1506            }
1507    
1508            private static void _removeOldContent(
1509                            Stack<String> path, Element contentEl, Document xsdDoc)
1510                    throws SystemException {
1511    
1512                    String elPath = "";
1513    
1514                    for (int i = 0; i < path.size(); i++) {
1515                            elPath += "/" + path.elementAt(i);
1516                    }
1517    
1518                    for (int i = 0; i < contentEl.nodeCount(); i++) {
1519                            Node contentNode = contentEl.node(i);
1520    
1521                            if (contentNode instanceof Element) {
1522                                    _removeOldContent(path, (Element)contentNode, xsdDoc, elPath);
1523                            }
1524                    }
1525            }
1526    
1527            private static void _removeOldContent(
1528                            Stack<String> path, Element contentEl, Document xsdDoc,
1529                            String elPath)
1530                    throws SystemException {
1531    
1532                    String name = contentEl.attributeValue("name");
1533    
1534                    if (Validator.isNull(name)) {
1535                            return;
1536                    }
1537    
1538                    String localPath = "dynamic-element[@name='" + name + "']";
1539    
1540                    String fullPath = elPath + "/" + localPath;
1541    
1542                    XPath xPathSelector = SAXReaderUtil.createXPath(fullPath);
1543    
1544                    List<Node> curNodes = xPathSelector.selectNodes(xsdDoc);
1545    
1546                    if (curNodes.size() == 0) {
1547                            contentEl.detach();
1548                    }
1549    
1550                    path.push(localPath);
1551    
1552                    _removeOldContent(path, contentEl, xsdDoc);
1553    
1554                    path.pop();
1555            }
1556    
1557            private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] {
1558                    '.', '/'
1559            };
1560    
1561            private static Log _log = LogFactoryUtil.getLog(JournalUtil.class);
1562    
1563            private static Log _logOutputAfterListener = LogFactoryUtil.getLog(
1564                    JournalUtil.class.getName() + ".OutputAfterListener");
1565    
1566            private static Log _logOutputBeforeListener = LogFactoryUtil.getLog(
1567                    JournalUtil.class.getName() + ".OutputBeforeListener");
1568    
1569            private static Log _logScriptAfterListener = LogFactoryUtil.getLog(
1570                    JournalUtil.class.getName() + ".ScriptAfterListener");
1571    
1572            private static Log _logScriptBeforeListener = LogFactoryUtil.getLog(
1573                    JournalUtil.class.getName() + ".ScriptBeforeListener");
1574    
1575            private static Log _logTokens = LogFactoryUtil.getLog(
1576                    JournalUtil.class.getName() + ".Tokens");
1577    
1578            private static Log _logTransformBefore = LogFactoryUtil.getLog(
1579                    JournalUtil.class.getName() + ".BeforeTransform");
1580    
1581            private static Log _logTransfromAfter = LogFactoryUtil.getLog(
1582                    JournalUtil.class.getName() + ".TransformAfter");
1583    
1584            private static Log _logXmlAfterListener = LogFactoryUtil.getLog(
1585                    JournalUtil.class.getName() + ".XmlAfterListener");
1586    
1587            private static Log _logXmlBeforeListener = LogFactoryUtil.getLog(
1588                    JournalUtil.class.getName() + ".XmlBeforeListener");
1589    
1590            private static Map<String, String> _customTokens;
1591    
1592    }