0001: /**
0002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
0003: *
0004: * Permission is hereby granted, free of charge, to any person obtaining a copy
0005: * of this software and associated documentation files (the "Software"), to deal
0006: * in the Software without restriction, including without limitation the rights
0007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0008: * copies of the Software, and to permit persons to whom the Software is
0009: * furnished to do so, subject to the following conditions:
0010: *
0011: * The above copyright notice and this permission notice shall be included in
0012: * all copies or substantial portions of the Software.
0013: *
0014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0020: * SOFTWARE.
0021: */package com.liferay.portlet.journal.util;
0022:
0023: import com.liferay.portal.PortalException;
0024: import com.liferay.portal.SystemException;
0025: import com.liferay.portal.kernel.util.GetterUtil;
0026: import com.liferay.portal.kernel.util.LocaleUtil;
0027: import com.liferay.portal.kernel.util.OrderByComparator;
0028: import com.liferay.portal.kernel.util.PropertiesUtil;
0029: import com.liferay.portal.kernel.util.StringPool;
0030: import com.liferay.portal.kernel.util.StringUtil;
0031: import com.liferay.portal.kernel.util.Validator;
0032: import com.liferay.portal.model.Contact;
0033: import com.liferay.portal.model.User;
0034: import com.liferay.portal.service.UserLocalServiceUtil;
0035: import com.liferay.portal.service.impl.ImageLocalUtil;
0036: import com.liferay.portal.theme.ThemeDisplay;
0037: import com.liferay.portal.util.ContentUtil;
0038: import com.liferay.portal.util.PropsUtil;
0039: import com.liferay.portal.util.WebKeys;
0040: import com.liferay.portlet.journal.TransformException;
0041: import com.liferay.portlet.journal.model.JournalArticle;
0042: import com.liferay.portlet.journal.model.JournalStructure;
0043: import com.liferay.portlet.journal.model.JournalTemplate;
0044: import com.liferay.portlet.journal.model.impl.JournalStructureImpl;
0045: import com.liferay.portlet.journal.model.impl.JournalTemplateImpl;
0046: import com.liferay.portlet.journal.service.JournalTemplateLocalServiceUtil;
0047: import com.liferay.portlet.journal.util.comparator.ArticleCreateDateComparator;
0048: import com.liferay.portlet.journal.util.comparator.ArticleDisplayDateComparator;
0049: import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
0050: import com.liferay.portlet.journal.util.comparator.ArticleModifiedDateComparator;
0051: import com.liferay.portlet.journal.util.comparator.ArticleReviewDateComparator;
0052: import com.liferay.portlet.journal.util.comparator.ArticleTitleComparator;
0053: import com.liferay.util.CollectionFactory;
0054: import com.liferay.util.FiniteUniqueStack;
0055: import com.liferay.util.Http;
0056: import com.liferay.util.Time;
0057: import com.liferay.util.xml.XMLFormatter;
0058:
0059: import java.io.IOException;
0060: import java.io.StringReader;
0061: import java.io.UnsupportedEncodingException;
0062:
0063: import java.util.ArrayList;
0064: import java.util.Date;
0065: import java.util.Iterator;
0066: import java.util.List;
0067: import java.util.Map;
0068: import java.util.Stack;
0069:
0070: import javax.portlet.PortletPreferences;
0071: import javax.portlet.PortletRequest;
0072: import javax.portlet.PortletSession;
0073:
0074: import org.apache.commons.logging.Log;
0075: import org.apache.commons.logging.LogFactory;
0076:
0077: import org.dom4j.Document;
0078: import org.dom4j.DocumentException;
0079: import org.dom4j.DocumentFactory;
0080: import org.dom4j.DocumentHelper;
0081: import org.dom4j.Element;
0082: import org.dom4j.Node;
0083: import org.dom4j.XPath;
0084: import org.dom4j.io.SAXReader;
0085:
0086: /**
0087: * <a href="JournalUtil.java.html"><b><i>View Source</i></b></a>
0088: *
0089: * @author Brian Wing Shun Chan
0090: * @author Raymond Augé
0091: *
0092: */
0093: public class JournalUtil {
0094:
0095: public static final int MAX_STACK_SIZE = 20;
0096:
0097: public static final String XML_INDENT = " ";
0098:
0099: public static void addRecentArticle(PortletRequest req,
0100: JournalArticle article) {
0101:
0102: if (article != null) {
0103: Stack stack = getRecentArticles(req);
0104:
0105: stack.push(article);
0106: }
0107: }
0108:
0109: public static void addRecentStructure(PortletRequest req,
0110: JournalStructure structure) {
0111:
0112: if (structure != null) {
0113: Stack stack = getRecentStructures(req);
0114:
0115: stack.push(structure);
0116: }
0117: }
0118:
0119: public static void addRecentTemplate(PortletRequest req,
0120: JournalTemplate template) {
0121:
0122: if (template != null) {
0123: Stack stack = getRecentTemplates(req);
0124:
0125: stack.push(template);
0126: }
0127: }
0128:
0129: public static void addReservedEl(Element root, Map tokens,
0130: String name, double value) {
0131:
0132: addReservedEl(root, tokens, name, String.valueOf(value));
0133: }
0134:
0135: public static void addReservedEl(Element root, Map tokens,
0136: String name, Date value) {
0137:
0138: addReservedEl(root, tokens, name, Time.getRFC822(value));
0139: }
0140:
0141: public static void addReservedEl(Element root, Map tokens,
0142: String name, String value) {
0143:
0144: // XML
0145:
0146: if (root != null) {
0147: DocumentFactory docFactory = DocumentFactory.getInstance();
0148:
0149: Element dynamicEl = docFactory
0150: .createElement("dynamic-element");
0151:
0152: dynamicEl.add(docFactory.createAttribute(dynamicEl, "name",
0153: name));
0154: dynamicEl.add(docFactory.createAttribute(dynamicEl, "type",
0155: "text"));
0156:
0157: Element dynamicContent = docFactory
0158: .createElement("dynamic-content");
0159:
0160: //dynamicContent.setText("<![CDATA[" + value + "]]>");
0161: dynamicContent.setText(value);
0162:
0163: dynamicEl.add(dynamicContent);
0164:
0165: root.add(dynamicEl);
0166: }
0167:
0168: // Tokens
0169:
0170: tokens.put(StringUtil.replace(name, StringPool.DASH,
0171: StringPool.UNDERLINE), value);
0172: }
0173:
0174: public static void addAllReservedEls(Element root, Map tokens,
0175: JournalArticle article) {
0176:
0177: JournalUtil.addReservedEl(root, tokens,
0178: JournalStructureImpl.RESERVED_ARTICLE_ID, article
0179: .getArticleId());
0180:
0181: JournalUtil.addReservedEl(root, tokens,
0182: JournalStructureImpl.RESERVED_ARTICLE_VERSION, article
0183: .getVersion());
0184:
0185: JournalUtil.addReservedEl(root, tokens,
0186: JournalStructureImpl.RESERVED_ARTICLE_TITLE, article
0187: .getTitle());
0188:
0189: JournalUtil.addReservedEl(root, tokens,
0190: JournalStructureImpl.RESERVED_ARTICLE_DESCRIPTION,
0191: article.getDescription());
0192:
0193: JournalUtil.addReservedEl(root, tokens,
0194: JournalStructureImpl.RESERVED_ARTICLE_TYPE, article
0195: .getType());
0196:
0197: JournalUtil.addReservedEl(root, tokens,
0198: JournalStructureImpl.RESERVED_ARTICLE_CREATE_DATE,
0199: article.getCreateDate());
0200:
0201: JournalUtil.addReservedEl(root, tokens,
0202: JournalStructureImpl.RESERVED_ARTICLE_MODIFIED_DATE,
0203: article.getModifiedDate());
0204:
0205: if (article.getDisplayDate() != null) {
0206: JournalUtil.addReservedEl(root, tokens,
0207: JournalStructureImpl.RESERVED_ARTICLE_DISPLAY_DATE,
0208: article.getDisplayDate());
0209: }
0210:
0211: JournalUtil.addReservedEl(root, tokens,
0212: JournalStructureImpl.RESERVED_ARTICLE_SMALL_IMAGE_URL,
0213: article.getSmallImageURL());
0214:
0215: JournalUtil.addReservedEl(root, tokens,
0216: JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_ID, String
0217: .valueOf(article.getUserId()));
0218:
0219: String userName = StringPool.BLANK;
0220: String userEmailAddress = StringPool.BLANK;
0221: String userComments = StringPool.BLANK;
0222: String userJobTitle = StringPool.BLANK;
0223:
0224: User user = null;
0225:
0226: try {
0227: user = UserLocalServiceUtil
0228: .getUserById(article.getUserId());
0229:
0230: userName = user.getFullName();
0231: userEmailAddress = user.getEmailAddress();
0232: userComments = user.getComments();
0233:
0234: Contact contact = user.getContact();
0235:
0236: if (contact != null) {
0237: userJobTitle = contact.getJobTitle();
0238: }
0239: } catch (PortalException pe) {
0240: } catch (SystemException se) {
0241: }
0242:
0243: JournalUtil.addReservedEl(root, tokens,
0244: JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_NAME,
0245: userName);
0246:
0247: JournalUtil
0248: .addReservedEl(
0249: root,
0250: tokens,
0251: JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_EMAIL_ADDRESS,
0252: userEmailAddress);
0253:
0254: JournalUtil.addReservedEl(root, tokens,
0255: JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_COMMENTS,
0256: userComments);
0257:
0258: JournalUtil.addReservedEl(root, tokens,
0259: JournalStructureImpl.RESERVED_ARTICLE_AUTHOR_JOB_TITLE,
0260: userJobTitle);
0261: }
0262:
0263: public static String formatVM(String vm) {
0264: return vm;
0265: }
0266:
0267: public static String formatXML(String xml)
0268: throws DocumentException, IOException {
0269:
0270: // This is only supposed to format your xml, however, it will also
0271: // unwantingly change © and other characters like it into their
0272: // respective readable versions
0273:
0274: xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
0275:
0276: xml = XMLFormatter.toString(xml, XML_INDENT);
0277:
0278: xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
0279:
0280: return xml;
0281: }
0282:
0283: public static String formatXML(Document doc)
0284: throws DocumentException, IOException {
0285:
0286: return XMLFormatter.toString(doc, XML_INDENT);
0287: }
0288:
0289: public static OrderByComparator getArticleOrderByComparator(
0290: String orderByCol, String orderByType) {
0291:
0292: boolean orderByAsc = false;
0293:
0294: if (orderByType.equals("asc")) {
0295: orderByAsc = true;
0296: }
0297:
0298: OrderByComparator orderByComparator = null;
0299:
0300: if (orderByCol.equals("create-date")) {
0301: orderByComparator = new ArticleCreateDateComparator(
0302: orderByAsc);
0303: } else if (orderByCol.equals("display-date")) {
0304: orderByComparator = new ArticleDisplayDateComparator(
0305: orderByAsc);
0306: } else if (orderByCol.equals("id")) {
0307: orderByComparator = new ArticleIDComparator(orderByAsc);
0308: } else if (orderByCol.equals("modified-date")) {
0309: orderByComparator = new ArticleModifiedDateComparator(
0310: orderByAsc);
0311: } else if (orderByCol.equals("review-date")) {
0312: orderByComparator = new ArticleReviewDateComparator(
0313: orderByAsc);
0314: } else if (orderByCol.equals("title")) {
0315: orderByComparator = new ArticleTitleComparator(orderByAsc);
0316: } else if (orderByCol.equals("version")) {
0317: orderByComparator = new ArticleModifiedDateComparator(
0318: orderByAsc);
0319: }
0320:
0321: return orderByComparator;
0322: }
0323:
0324: public static String getEmailFromAddress(PortletPreferences prefs) {
0325: String emailFromAddress = PropsUtil
0326: .get(PropsUtil.JOURNAL_EMAIL_FROM_ADDRESS);
0327:
0328: return prefs.getValue("email-from-address", emailFromAddress);
0329: }
0330:
0331: public static String getEmailFromName(PortletPreferences prefs) {
0332: String emailFromName = PropsUtil
0333: .get(PropsUtil.JOURNAL_EMAIL_FROM_NAME);
0334:
0335: return prefs.getValue("email-from-name", emailFromName);
0336: }
0337:
0338: public static boolean getEmailArticleApprovalDeniedEnabled(
0339: PortletPreferences prefs) {
0340:
0341: String emailArticleApprovalDeniedEnabled = prefs.getValue(
0342: "email-article-approval-denied-enabled",
0343: StringPool.BLANK);
0344:
0345: if (Validator.isNotNull(emailArticleApprovalDeniedEnabled)) {
0346: return GetterUtil
0347: .getBoolean(emailArticleApprovalDeniedEnabled);
0348: } else {
0349: return GetterUtil
0350: .getBoolean(PropsUtil
0351: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_ENABLED));
0352: }
0353: }
0354:
0355: public static String getEmailArticleApprovalDeniedBody(
0356: PortletPreferences prefs) throws IOException {
0357:
0358: String emailArticleApprovalDeniedBody = prefs.getValue(
0359: "email-article-approval-denied-body", StringPool.BLANK);
0360:
0361: if (Validator.isNotNull(emailArticleApprovalDeniedBody)) {
0362: return emailArticleApprovalDeniedBody;
0363: } else {
0364: return ContentUtil
0365: .get(PropsUtil
0366: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_BODY));
0367: }
0368: }
0369:
0370: public static String getEmailArticleApprovalDeniedSubject(
0371: PortletPreferences prefs) throws IOException {
0372:
0373: String emailArticleApprovalDeniedSubject = prefs.getValue(
0374: "email-article-approval-denied-subject",
0375: StringPool.BLANK);
0376:
0377: if (Validator.isNotNull(emailArticleApprovalDeniedSubject)) {
0378: return emailArticleApprovalDeniedSubject;
0379: } else {
0380: return ContentUtil
0381: .get(PropsUtil
0382: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_DENIED_SUBJECT));
0383: }
0384: }
0385:
0386: public static boolean getEmailArticleApprovalGrantedEnabled(
0387: PortletPreferences prefs) {
0388:
0389: String emailArticleApprovalGrantedEnabled = prefs.getValue(
0390: "email-article-approval-granted-enabled",
0391: StringPool.BLANK);
0392:
0393: if (Validator.isNotNull(emailArticleApprovalGrantedEnabled)) {
0394: return GetterUtil
0395: .getBoolean(emailArticleApprovalGrantedEnabled);
0396: } else {
0397: return GetterUtil
0398: .getBoolean(PropsUtil
0399: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_ENABLED));
0400: }
0401: }
0402:
0403: public static String getEmailArticleApprovalGrantedBody(
0404: PortletPreferences prefs) throws IOException {
0405:
0406: String emailArticleApprovalGrantedBody = prefs
0407: .getValue("email-article-approval-granted-body",
0408: StringPool.BLANK);
0409:
0410: if (Validator.isNotNull(emailArticleApprovalGrantedBody)) {
0411: return emailArticleApprovalGrantedBody;
0412: } else {
0413: return ContentUtil
0414: .get(PropsUtil
0415: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_BODY));
0416: }
0417: }
0418:
0419: public static String getEmailArticleApprovalGrantedSubject(
0420: PortletPreferences prefs) throws IOException {
0421:
0422: String emailArticleApprovalGrantedSubject = prefs.getValue(
0423: "email-article-approval-granted-subject",
0424: StringPool.BLANK);
0425:
0426: if (Validator.isNotNull(emailArticleApprovalGrantedSubject)) {
0427: return emailArticleApprovalGrantedSubject;
0428: } else {
0429: return ContentUtil
0430: .get(PropsUtil
0431: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_GRANTED_SUBJECT));
0432: }
0433: }
0434:
0435: public static boolean getEmailArticleApprovalRequestedEnabled(
0436: PortletPreferences prefs) {
0437:
0438: String emailArticleApprovalRequestedEnabled = prefs.getValue(
0439: "email-article-approval-requested-enabled",
0440: StringPool.BLANK);
0441:
0442: if (Validator.isNotNull(emailArticleApprovalRequestedEnabled)) {
0443: return GetterUtil
0444: .getBoolean(emailArticleApprovalRequestedEnabled);
0445: } else {
0446: return GetterUtil
0447: .getBoolean(PropsUtil
0448: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_ENABLED));
0449: }
0450: }
0451:
0452: public static String getEmailArticleApprovalRequestedBody(
0453: PortletPreferences prefs) throws IOException {
0454:
0455: String emailArticleApprovalRequestedBody = prefs.getValue(
0456: "email-article-approval-requested-body",
0457: StringPool.BLANK);
0458:
0459: if (Validator.isNotNull(emailArticleApprovalRequestedBody)) {
0460: return emailArticleApprovalRequestedBody;
0461: } else {
0462: return ContentUtil
0463: .get(PropsUtil
0464: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_BODY));
0465: }
0466: }
0467:
0468: public static String getEmailArticleApprovalRequestedSubject(
0469: PortletPreferences prefs) throws IOException {
0470:
0471: String emailArticleApprovalRequestedSubject = prefs.getValue(
0472: "email-article-approval-requested-subject",
0473: StringPool.BLANK);
0474:
0475: if (Validator.isNotNull(emailArticleApprovalRequestedSubject)) {
0476: return emailArticleApprovalRequestedSubject;
0477: } else {
0478: return ContentUtil
0479: .get(PropsUtil
0480: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_APPROVAL_REQUESTED_SUBJECT));
0481: }
0482: }
0483:
0484: public static boolean getEmailArticleReviewEnabled(
0485: PortletPreferences prefs) {
0486:
0487: String emailArticleReviewEnabled = prefs.getValue(
0488: "email-article-review-enabled", StringPool.BLANK);
0489:
0490: if (Validator.isNotNull(emailArticleReviewEnabled)) {
0491: return GetterUtil.getBoolean(emailArticleReviewEnabled);
0492: } else {
0493: return GetterUtil
0494: .getBoolean(PropsUtil
0495: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_ENABLED));
0496: }
0497: }
0498:
0499: public static String getEmailArticleReviewBody(
0500: PortletPreferences prefs) throws IOException {
0501:
0502: String emailArticleReviewBody = prefs.getValue(
0503: "email-article-review-body", StringPool.BLANK);
0504:
0505: if (Validator.isNotNull(emailArticleReviewBody)) {
0506: return emailArticleReviewBody;
0507: } else {
0508: return ContentUtil.get(PropsUtil
0509: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_BODY));
0510: }
0511: }
0512:
0513: public static String getEmailArticleReviewSubject(
0514: PortletPreferences prefs) throws IOException {
0515:
0516: String emailArticleReviewSubject = prefs.getValue(
0517: "email-article-review-subject", StringPool.BLANK);
0518:
0519: if (Validator.isNotNull(emailArticleReviewSubject)) {
0520: return emailArticleReviewSubject;
0521: } else {
0522: return ContentUtil
0523: .get(PropsUtil
0524: .get(PropsUtil.JOURNAL_EMAIL_ARTICLE_REVIEW_SUBJECT));
0525: }
0526: }
0527:
0528: public static Stack getRecentArticles(PortletRequest req) {
0529: PortletSession ses = req.getPortletSession();
0530:
0531: Stack recentArticles = (Stack) ses
0532: .getAttribute(WebKeys.JOURNAL_RECENT_ARTICLES);
0533:
0534: if (recentArticles == null) {
0535: recentArticles = new FiniteUniqueStack(MAX_STACK_SIZE);
0536:
0537: ses.setAttribute(WebKeys.JOURNAL_RECENT_ARTICLES,
0538: recentArticles);
0539: }
0540:
0541: return recentArticles;
0542: }
0543:
0544: public static Stack getRecentStructures(PortletRequest req) {
0545: PortletSession ses = req.getPortletSession();
0546:
0547: Stack recentStructures = (Stack) ses
0548: .getAttribute(WebKeys.JOURNAL_RECENT_STRUCTURES);
0549:
0550: if (recentStructures == null) {
0551: recentStructures = new FiniteUniqueStack(MAX_STACK_SIZE);
0552:
0553: ses.setAttribute(WebKeys.JOURNAL_RECENT_STRUCTURES,
0554: recentStructures);
0555: }
0556:
0557: return recentStructures;
0558: }
0559:
0560: public static Stack getRecentTemplates(PortletRequest req) {
0561: PortletSession ses = req.getPortletSession();
0562:
0563: Stack recentTemplates = (Stack) ses
0564: .getAttribute(WebKeys.JOURNAL_RECENT_TEMPLATES);
0565:
0566: if (recentTemplates == null) {
0567: recentTemplates = new FiniteUniqueStack(MAX_STACK_SIZE);
0568:
0569: ses.setAttribute(WebKeys.JOURNAL_RECENT_TEMPLATES,
0570: recentTemplates);
0571: }
0572:
0573: return recentTemplates;
0574: }
0575:
0576: public static String getTemplateScript(long groupId,
0577: String templateId, Map tokens, String languageId)
0578: throws PortalException, SystemException {
0579:
0580: return getTemplateScript(groupId, templateId, tokens,
0581: languageId, true);
0582: }
0583:
0584: public static String getTemplateScript(long groupId,
0585: String templateId, Map tokens, String languageId,
0586: boolean transform) throws PortalException, SystemException {
0587:
0588: JournalTemplate template = JournalTemplateLocalServiceUtil
0589: .getTemplate(groupId, templateId);
0590:
0591: return getTemplateScript(template, tokens, languageId,
0592: transform);
0593: }
0594:
0595: public static String getTemplateScript(JournalTemplate template,
0596: Map tokens, String languageId, boolean transform)
0597: throws PortalException, SystemException {
0598:
0599: String script = template.getXsl();
0600:
0601: if (transform) {
0602:
0603: // Listeners
0604:
0605: String[] listeners = PropsUtil
0606: .getArray(PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
0607:
0608: for (int i = 0; i < listeners.length; i++) {
0609: TransformerListener listener = null;
0610:
0611: try {
0612: listener = (TransformerListener) Class.forName(
0613: listeners[i]).newInstance();
0614:
0615: listener.setTemplateDriven(true);
0616: listener.setLanguageId(languageId);
0617: listener.setTokens(tokens);
0618: } catch (Exception e) {
0619: e.printStackTrace();
0620: }
0621:
0622: // Modify transform script
0623:
0624: if (listener != null) {
0625: script = listener.onScript(script);
0626: }
0627: }
0628: }
0629:
0630: return script;
0631: }
0632:
0633: public static Map getTokens(long groupId, ThemeDisplay themeDisplay) {
0634: Map tokens = CollectionFactory.getHashMap();
0635:
0636: if (themeDisplay == null) {
0637: return tokens;
0638: }
0639:
0640: tokens.put("cdn_host", themeDisplay.getCDNHost());
0641: tokens.put("company_id", String.valueOf(themeDisplay
0642: .getCompanyId()));
0643: tokens.put("group_id", String.valueOf(groupId));
0644: tokens.put("cms_url", themeDisplay.getPathContext()
0645: + "/cms/servlet");
0646: tokens.put("image_path", themeDisplay.getPathImage());
0647: tokens.put("friendly_url_private_group", themeDisplay
0648: .getPathFriendlyURLPrivateGroup());
0649: tokens.put("friendly_url_private_user", themeDisplay
0650: .getPathFriendlyURLPrivateUser());
0651: tokens.put("friendly_url_public", themeDisplay
0652: .getPathFriendlyURLPublic());
0653: tokens.put("main_path", themeDisplay.getPathMain());
0654: tokens.put("portal_ctx", themeDisplay.getPathContext());
0655: tokens.put("portal_url", Http.removeProtocol(themeDisplay
0656: .getURLPortal()));
0657: tokens.put("root_path", themeDisplay.getPathContext());
0658: tokens.put("theme_image_path", themeDisplay
0659: .getPathThemeImages());
0660:
0661: // Deprecated tokens
0662:
0663: tokens.put("friendly_url", themeDisplay
0664: .getPathFriendlyURLPublic());
0665: tokens.put("friendly_url_private", themeDisplay
0666: .getPathFriendlyURLPrivateGroup());
0667: tokens.put("page_url", themeDisplay.getPathFriendlyURLPublic());
0668:
0669: return tokens;
0670: }
0671:
0672: public static String mergeLocaleContent(String curContent,
0673: String newContent, String xsd) {
0674:
0675: try {
0676: SAXReader reader = new SAXReader();
0677:
0678: Document curContentDoc = reader.read(new StringReader(
0679: curContent));
0680: Document newContentDoc = reader.read(new StringReader(
0681: newContent));
0682: Document xsdDoc = reader.read(new StringReader(xsd));
0683:
0684: Element curContentRoot = curContentDoc.getRootElement();
0685: Element newContentRoot = newContentDoc.getRootElement();
0686: Element xsdRoot = xsdDoc.getRootElement();
0687:
0688: curContentRoot.addAttribute("default-locale",
0689: newContentRoot.attributeValue("default-locale"));
0690: curContentRoot.addAttribute("available-locales",
0691: newContentRoot.attributeValue("available-locales"));
0692:
0693: Stack path = new Stack();
0694:
0695: path.push(xsdRoot.getName());
0696:
0697: _mergeLocaleContent(path, curContentDoc, newContentDoc,
0698: xsdRoot, LocaleUtil.toLanguageId(LocaleUtil
0699: .getDefault()));
0700:
0701: curContent = formatXML(curContentDoc);
0702: } catch (Exception e) {
0703: _log.error(e);
0704: }
0705:
0706: return curContent;
0707: }
0708:
0709: public static String removeArticleLocale(String content,
0710: String languageId) {
0711:
0712: try {
0713: SAXReader reader = new SAXReader();
0714:
0715: Document doc = reader.read(new StringReader(content));
0716:
0717: Element root = doc.getRootElement();
0718:
0719: String availableLocales = root
0720: .attributeValue("available-locales");
0721:
0722: if (availableLocales == null) {
0723: return content;
0724: }
0725:
0726: availableLocales = StringUtil.remove(availableLocales,
0727: languageId);
0728:
0729: if (availableLocales.endsWith(",")) {
0730: availableLocales = availableLocales.substring(0,
0731: availableLocales.length() - 1);
0732: }
0733:
0734: root.addAttribute("available-locales", availableLocales);
0735:
0736: removeArticleLocale(root, languageId);
0737:
0738: content = formatXML(doc);
0739: } catch (Exception e) {
0740: _log.error(e);
0741: }
0742:
0743: return content;
0744: }
0745:
0746: public static void removeArticleLocale(Element el, String languageId)
0747: throws SystemException {
0748:
0749: Iterator itr1 = el.elements("dynamic-element").iterator();
0750:
0751: while (itr1.hasNext()) {
0752: Element dynamicEl = (Element) itr1.next();
0753:
0754: Iterator itr2 = dynamicEl.elements("dynamic-content")
0755: .iterator();
0756:
0757: while (itr2.hasNext()) {
0758: Element dynamicContentEl = (Element) itr2.next();
0759:
0760: String curLanguageId = GetterUtil
0761: .getString(dynamicContentEl
0762: .attributeValue("language-id"));
0763:
0764: if (curLanguageId.equals(languageId)) {
0765: long id = GetterUtil.getLong(dynamicContentEl
0766: .attributeValue("id"));
0767:
0768: if (id > 0) {
0769: ImageLocalUtil.deleteImage(id);
0770: }
0771:
0772: dynamicContentEl.detach();
0773: }
0774: }
0775:
0776: removeArticleLocale(dynamicEl, languageId);
0777: }
0778: }
0779:
0780: public static String removeOldContent(String content, String xsd) {
0781: try {
0782: SAXReader reader = new SAXReader();
0783:
0784: Document contentDoc = reader
0785: .read(new StringReader(content));
0786: Document xsdDoc = reader.read(new StringReader(xsd));
0787:
0788: Element contentRoot = contentDoc.getRootElement();
0789:
0790: Stack path = new Stack();
0791:
0792: path.push(contentRoot.getName());
0793:
0794: _removeOldContent(path, contentRoot, xsdDoc);
0795:
0796: content = formatXML(contentDoc);
0797: } catch (Exception e) {
0798: _log.error(e);
0799: }
0800:
0801: return content;
0802: }
0803:
0804: public static void removeRecentArticle(PortletRequest req,
0805: String articleId) {
0806:
0807: Stack stack = getRecentArticles(req);
0808:
0809: Iterator itr = stack.iterator();
0810:
0811: while (itr.hasNext()) {
0812: JournalArticle journalArticle = (JournalArticle) itr.next();
0813:
0814: if (journalArticle.getArticleId().equals(articleId)) {
0815: itr.remove();
0816:
0817: break;
0818: }
0819: }
0820: }
0821:
0822: public static void removeRecentStructure(PortletRequest req,
0823: String structureId) {
0824:
0825: Stack stack = getRecentStructures(req);
0826:
0827: Iterator itr = stack.iterator();
0828:
0829: while (itr.hasNext()) {
0830: JournalStructure journalStructure = (JournalStructure) itr
0831: .next();
0832:
0833: if (journalStructure.getStructureId().equals(structureId)) {
0834: itr.remove();
0835:
0836: break;
0837: }
0838: }
0839: }
0840:
0841: public static void removeRecentTemplate(PortletRequest req,
0842: String templateId) {
0843:
0844: Stack stack = getRecentTemplates(req);
0845:
0846: Iterator itr = stack.iterator();
0847:
0848: while (itr.hasNext()) {
0849: JournalTemplate journalTemplate = (JournalTemplate) itr
0850: .next();
0851:
0852: if (journalTemplate.getTemplateId().equals(templateId)) {
0853: itr.remove();
0854:
0855: break;
0856: }
0857: }
0858: }
0859:
0860: public static String transform(Map tokens, String languageId,
0861: String xml, String script, String langType)
0862: throws TransformException, UnsupportedEncodingException {
0863:
0864: // Setup Listeners
0865:
0866: if (_log.isDebugEnabled()) {
0867: _log.debug("Language " + languageId);
0868: }
0869:
0870: if (_logTokens.isDebugEnabled()) {
0871: String tokensString = PropertiesUtil.list(tokens);
0872:
0873: _logTokens.debug(tokensString);
0874: }
0875:
0876: if (_logTransformBefore.isDebugEnabled()) {
0877: _logTransformBefore.debug(xml);
0878: }
0879:
0880: List listenersList = new ArrayList();
0881:
0882: String[] listeners = PropsUtil
0883: .getArray(PropsUtil.JOURNAL_TRANSFORMER_LISTENER);
0884:
0885: for (int i = 0; i < listeners.length; i++) {
0886: TransformerListener listener = null;
0887:
0888: try {
0889: if (_log.isDebugEnabled()) {
0890: _log.debug("Instantiate listener " + listeners[i]);
0891: }
0892:
0893: boolean templateDriven = Validator.isNotNull(langType);
0894:
0895: listener = (TransformerListener) Class.forName(
0896: listeners[i]).newInstance();
0897:
0898: listener.setTemplateDriven(templateDriven);
0899: listener.setLanguageId(languageId);
0900: listener.setTokens(tokens);
0901:
0902: listenersList.add(listener);
0903: } catch (Exception e) {
0904: _log.error(e, e);
0905: }
0906:
0907: // Modify XML
0908:
0909: if (_logXmlBeforeListener.isDebugEnabled()) {
0910: _logXmlBeforeListener.debug(xml);
0911: }
0912:
0913: if (listener != null) {
0914: xml = listener.onXml(xml);
0915:
0916: if (_logXmlAfterListener.isDebugEnabled()) {
0917: _logXmlAfterListener.debug(xml);
0918: }
0919: }
0920:
0921: // Modify script
0922:
0923: if (_logScriptBeforeListener.isDebugEnabled()) {
0924: _logScriptBeforeListener.debug(script);
0925: }
0926:
0927: if (listener != null) {
0928: script = listener.onScript(script);
0929:
0930: if (_logScriptAfterListener.isDebugEnabled()) {
0931: _logScriptAfterListener.debug(script);
0932: }
0933: }
0934: }
0935:
0936: // Transform
0937:
0938: String output = null;
0939:
0940: if (Validator.isNull(langType)) {
0941: output = xml;
0942: } else if (langType.equals(JournalTemplateImpl.LANG_TYPE_VM)) {
0943: output = JournalVmUtil.transform(tokens, languageId, xml,
0944: script);
0945: } else if (langType.equals(JournalTemplateImpl.LANG_TYPE_XSL)) {
0946: output = JournalXslUtil.transform(tokens, languageId, xml,
0947: script);
0948: }
0949:
0950: // Postprocess output
0951:
0952: for (int i = 0; i < listenersList.size(); i++) {
0953: TransformerListener listener = (TransformerListener) listenersList
0954: .get(i);
0955:
0956: // Modify output
0957:
0958: if (_logOutputBeforeListener.isDebugEnabled()) {
0959: _logOutputBeforeListener.debug(output);
0960: }
0961:
0962: output = listener.onOutput(output);
0963:
0964: if (_logOutputAfterListener.isDebugEnabled()) {
0965: _logOutputAfterListener.debug(output);
0966: }
0967: }
0968:
0969: if (_logTransfromAfter.isDebugEnabled()) {
0970: _logTransfromAfter.debug(output);
0971: }
0972:
0973: return output;
0974: }
0975:
0976: private static void _mergeLocaleContent(Stack path,
0977: Document curDoc, Document newDoc, Element xsdEl,
0978: String defaultLocale) throws SystemException {
0979:
0980: String elPath = "";
0981:
0982: for (int i = 0; i < path.size(); i++) {
0983: elPath += "/" + path.elementAt(i);
0984: }
0985:
0986: for (int i = 0; i < xsdEl.nodeCount(); i++) {
0987: Node xsdNode = xsdEl.node(i);
0988:
0989: if ((xsdNode instanceof Element)
0990: && (xsdNode.getName().equals("dynamic-element"))) {
0991:
0992: _mergeLocaleContent(path, curDoc, newDoc,
0993: (Element) xsdNode, defaultLocale, elPath);
0994: }
0995: }
0996: }
0997:
0998: private static void _mergeLocaleContent(Stack path,
0999: Document curDoc, Document newDoc, Element xsdEl,
1000: String defaultLocale, String elPath) throws SystemException {
1001:
1002: String name = xsdEl.attributeValue("name");
1003:
1004: String localPath = "dynamic-element[@name='" + name + "']";
1005:
1006: String fullPath = elPath + "/" + localPath;
1007:
1008: XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1009:
1010: List curElements = xPathSelector.selectNodes(curDoc);
1011:
1012: Element newEl = (Element) xPathSelector.selectNodes(newDoc)
1013: .get(0);
1014:
1015: if (curElements.size() > 0) {
1016: Element curEl = (Element) curElements.get(0);
1017:
1018: List curDynamicContents = curEl.elements("dynamic-content");
1019:
1020: Element newContentEl = newEl.element("dynamic-content");
1021:
1022: String newContentLanguageId = newContentEl.attributeValue(
1023: "language-id", StringPool.BLANK);
1024:
1025: if (newContentLanguageId.equals(StringPool.BLANK)) {
1026: for (int k = curDynamicContents.size() - 1; k >= 0; k--) {
1027: Element curContentEl = (Element) curDynamicContents
1028: .get(k);
1029:
1030: String curContentLanguageId = curContentEl
1031: .attributeValue("language-id",
1032: StringPool.BLANK);
1033:
1034: if ((curEl.attributeValue("type").equals("image"))
1035: && (!curContentLanguageId
1036: .equals(defaultLocale) && !curContentLanguageId
1037: .equals(StringPool.BLANK))) {
1038:
1039: long id = GetterUtil.getLong(curContentEl
1040: .attributeValue("id"));
1041:
1042: ImageLocalUtil.deleteImage(id);
1043: }
1044:
1045: curContentEl.detach();
1046: }
1047:
1048: curEl.content().add(newContentEl.createCopy());
1049: } else {
1050: boolean match = false;
1051:
1052: for (int k = curDynamicContents.size() - 1; k >= 0; k--) {
1053: Element curContentEl = (Element) curDynamicContents
1054: .get(k);
1055:
1056: String curContentLanguageId = curContentEl
1057: .attributeValue("language-id",
1058: StringPool.BLANK);
1059:
1060: if ((newContentLanguageId
1061: .equals(curContentLanguageId))
1062: || (newContentLanguageId
1063: .equals(defaultLocale) && curContentLanguageId
1064: .equals(StringPool.BLANK))) {
1065:
1066: curContentEl.detach();
1067:
1068: curEl.content().add(k,
1069: newContentEl.createCopy());
1070:
1071: match = true;
1072: }
1073:
1074: if (curContentLanguageId.equals(StringPool.BLANK)) {
1075: curContentEl.addAttribute("language-id",
1076: defaultLocale);
1077: }
1078: }
1079:
1080: if (!match) {
1081: curEl.content().add(newContentEl.createCopy());
1082: }
1083: }
1084: } else {
1085: xPathSelector = DocumentHelper.createXPath(elPath);
1086:
1087: Element parentEl = (Element) xPathSelector.selectNodes(
1088: curDoc).get(0);
1089:
1090: parentEl.content().add(newEl.createCopy());
1091: }
1092:
1093: String type = xsdEl.attributeValue("type", StringPool.BLANK);
1094:
1095: if (!type.equals("list") && !type.equals("multi-list")) {
1096: path.push(localPath);
1097:
1098: _mergeLocaleContent(path, curDoc, newDoc, xsdEl,
1099: defaultLocale);
1100:
1101: path.pop();
1102: }
1103: }
1104:
1105: private static void _removeOldContent(Stack path,
1106: Element contentEl, Document xsdDoc) throws SystemException {
1107:
1108: String elPath = "";
1109:
1110: for (int i = 0; i < path.size(); i++) {
1111: elPath += "/" + path.elementAt(i);
1112: }
1113:
1114: for (int i = 0; i < contentEl.nodeCount(); i++) {
1115: Node contentNode = contentEl.node(i);
1116:
1117: if (contentNode instanceof Element) {
1118: _removeOldContent(path, (Element) contentNode, xsdDoc,
1119: elPath);
1120: }
1121: }
1122: }
1123:
1124: private static void _removeOldContent(Stack path,
1125: Element contentEl, Document xsdDoc, String elPath)
1126: throws SystemException {
1127:
1128: String name = contentEl.attributeValue("name");
1129:
1130: if (Validator.isNull(name)) {
1131: return;
1132: }
1133:
1134: String localPath = "dynamic-element[@name='" + name + "']";
1135:
1136: String fullPath = elPath + "/" + localPath;
1137:
1138: XPath xPathSelector = DocumentHelper.createXPath(fullPath);
1139:
1140: List curElements = xPathSelector.selectNodes(xsdDoc);
1141:
1142: if (curElements.size() == 0) {
1143: contentEl.detach();
1144: }
1145:
1146: path.push(localPath);
1147:
1148: _removeOldContent(path, contentEl, xsdDoc);
1149:
1150: path.pop();
1151: }
1152:
1153: private static Log _log = LogFactory.getLog(JournalUtil.class);
1154:
1155: private static Log _logOutputAfterListener = LogFactory
1156: .getLog(JournalUtil.class.getName()
1157: + ".OutputAfterListener");
1158:
1159: private static Log _logOutputBeforeListener = LogFactory
1160: .getLog(JournalUtil.class.getName()
1161: + ".OutputBeforeListener");
1162:
1163: private static Log _logScriptAfterListener = LogFactory
1164: .getLog(JournalUtil.class.getName()
1165: + ".ScriptAfterListener");
1166:
1167: private static Log _logScriptBeforeListener = LogFactory
1168: .getLog(JournalUtil.class.getName()
1169: + ".ScriptBeforeListener");
1170:
1171: private static Log _logTransfromAfter = LogFactory
1172: .getLog(JournalUtil.class.getName() + ".TransformAfter");
1173:
1174: private static Log _logTransformBefore = LogFactory
1175: .getLog(JournalUtil.class.getName() + ".BeforeTransform");
1176:
1177: private static Log _logTokens = LogFactory.getLog(JournalUtil.class
1178: .getName()
1179: + ".Tokens");
1180:
1181: private static Log _logXmlAfterListener = LogFactory
1182: .getLog(JournalUtil.class.getName() + ".XmlAfterListener");
1183:
1184: private static Log _logXmlBeforeListener = LogFactory
1185: .getLog(JournalUtil.class.getName() + ".XmlBeforeListener");
1186:
1187: }
|