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