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