001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journalcontent.util;
016    
017    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
018    import com.liferay.portal.kernel.cache.PortalCache;
019    import com.liferay.portal.kernel.lar.ImportExportThreadLocal;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.Layout;
027    import com.liferay.portal.model.LayoutSet;
028    import com.liferay.portal.security.permission.ActionKeys;
029    import com.liferay.portal.theme.ThemeDisplay;
030    import com.liferay.portal.util.PropsValues;
031    import com.liferay.portlet.journal.model.JournalArticleDisplay;
032    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
033    import com.liferay.portlet.journal.service.permission.JournalArticlePermission;
034    
035    import java.util.regex.Matcher;
036    import java.util.regex.Pattern;
037    
038    import org.apache.commons.lang.time.StopWatch;
039    
040    /**
041     * @author Brian Wing Shun Chan
042     * @author Raymond Augé
043     * @author Michael Young
044     */
045    public class JournalContentImpl implements JournalContent {
046    
047            public void clearCache() {
048                    if (ImportExportThreadLocal.isImportInProcess()) {
049                            return;
050                    }
051    
052                    portalCache.removeAll();
053            }
054    
055            public void clearCache(long groupId, String articleId, String templateId) {
056                    clearCache();
057            }
058    
059            public String getContent(
060                    long groupId, String articleId, String viewMode, String languageId,
061                    String xmlRequest) {
062    
063                    return getContent(
064                            groupId, articleId, null, viewMode, languageId, null, xmlRequest);
065            }
066    
067            public String getContent(
068                    long groupId, String articleId, String templateId, String viewMode,
069                    String languageId, String xmlRequest) {
070    
071                    return getContent(
072                            groupId, articleId, templateId, viewMode, languageId, null,
073                            xmlRequest);
074            }
075    
076            public String getContent(
077                    long groupId, String articleId, String templateId, String viewMode,
078                    String languageId, ThemeDisplay themeDisplay) {
079    
080                    return getContent(
081                            groupId, articleId, templateId, viewMode, languageId, themeDisplay,
082                            null);
083            }
084    
085            public String getContent(
086                    long groupId, String articleId, String templateId, String viewMode,
087                    String languageId, ThemeDisplay themeDisplay, String xmlRequest) {
088    
089                    JournalArticleDisplay articleDisplay = getDisplay(
090                            groupId, articleId, templateId, viewMode, languageId, themeDisplay,
091                            1, xmlRequest);
092    
093                    if (articleDisplay != null) {
094                            return articleDisplay.getContent();
095                    }
096                    else {
097                            return null;
098                    }
099            }
100    
101            public String getContent(
102                    long groupId, String articleId, String viewMode, String languageId,
103                    ThemeDisplay themeDisplay) {
104    
105                    return getContent(
106                            groupId, articleId, null, viewMode, languageId, themeDisplay);
107            }
108    
109            public JournalArticleDisplay getDisplay(
110                    long groupId, String articleId, double version, String templateId,
111                    String viewMode, String languageId, ThemeDisplay themeDisplay, int page,
112                    String xmlRequest) {
113    
114                    StopWatch stopWatch = null;
115    
116                    if (_log.isDebugEnabled()) {
117                            stopWatch = new StopWatch();
118    
119                            stopWatch.start();
120                    }
121    
122                    articleId = GetterUtil.getString(articleId).toUpperCase();
123                    templateId = GetterUtil.getString(templateId).toUpperCase();
124    
125                    long layoutSetId = 0;
126                    boolean secure = false;
127    
128                    if (themeDisplay != null) {
129                            try {
130                                    Layout layout = themeDisplay.getLayout();
131    
132                                    LayoutSet layoutSet = layout.getLayoutSet();
133    
134                                    layoutSetId = layoutSet.getLayoutSetId();
135                            }
136                            catch (Exception e) {
137                            }
138    
139                            secure = themeDisplay.isSecure();
140                    }
141    
142                    String key = encodeKey(
143                            groupId, articleId, version, templateId, layoutSetId, viewMode,
144                            languageId, page, secure);
145    
146                    JournalArticleDisplay articleDisplay =
147                            (JournalArticleDisplay)portalCache.get(key);
148    
149                    boolean lifecycleRender = isLifecycleRender(themeDisplay, xmlRequest);
150    
151                    if ((articleDisplay == null) || !lifecycleRender) {
152                            articleDisplay = getArticleDisplay(
153                                    groupId, articleId, templateId, viewMode, languageId, page,
154                                    xmlRequest, themeDisplay);
155    
156                            if ((articleDisplay != null) && (articleDisplay.isCacheable()) &&
157                                    (lifecycleRender)) {
158    
159                                    portalCache.put(key, articleDisplay);
160                            }
161                    }
162    
163                    try {
164                            if ((PropsValues.JOURNAL_ARTICLE_VIEW_PERMISSION_CHECK_ENABLED) &&
165                                    (articleDisplay != null) && (themeDisplay != null) &&
166                                    (!JournalArticlePermission.contains(
167                                            themeDisplay.getPermissionChecker(), groupId, articleId,
168                                            ActionKeys.VIEW))) {
169    
170                                    articleDisplay = null;
171                            }
172                    }
173                    catch (Exception e) {
174                    }
175    
176                    if (_log.isDebugEnabled()) {
177                            _log.debug(
178                                    "getDisplay for {" + groupId + ", " + articleId + ", " +
179                                            templateId + ", " + viewMode + ", " + languageId + ", " +
180                                                    page + "} takes " + stopWatch.getTime() + " ms");
181                    }
182    
183                    return articleDisplay;
184            }
185    
186            public JournalArticleDisplay getDisplay(
187                    long groupId, String articleId, String viewMode, String languageId,
188                    String xmlRequest) {
189    
190                    return getDisplay(
191                            groupId, articleId, null, viewMode, languageId, null, 1,
192                            xmlRequest);
193            }
194    
195            public JournalArticleDisplay getDisplay(
196                    long groupId, String articleId, String templateId, String viewMode,
197                    String languageId, String xmlRequest) {
198    
199                    return getDisplay(
200                            groupId, articleId, templateId, viewMode, languageId, null, 1,
201                            xmlRequest);
202            }
203    
204            public JournalArticleDisplay getDisplay(
205                    long groupId, String articleId, String templateId, String viewMode,
206                    String languageId, ThemeDisplay themeDisplay) {
207    
208                    return getDisplay(
209                            groupId, articleId, templateId, viewMode, languageId, themeDisplay,
210                            1, null);
211            }
212    
213            public JournalArticleDisplay getDisplay(
214                    long groupId, String articleId, String templateId, String viewMode,
215                    String languageId, ThemeDisplay themeDisplay, int page,
216                    String xmlRequest) {
217    
218                    return getDisplay(
219                            groupId, articleId, 0, templateId, viewMode, languageId,
220                            themeDisplay, 1, xmlRequest);
221            }
222    
223            public JournalArticleDisplay getDisplay(
224                    long groupId, String articleId, String viewMode, String languageId,
225                    ThemeDisplay themeDisplay) {
226    
227                    return getDisplay(
228                            groupId, articleId, viewMode, languageId, themeDisplay, 1);
229            }
230    
231            public JournalArticleDisplay getDisplay(
232                    long groupId, String articleId, String viewMode, String languageId,
233                    ThemeDisplay themeDisplay, int page) {
234    
235                    return getDisplay(
236                            groupId, articleId, null, viewMode, languageId, themeDisplay, page,
237                            null);
238            }
239    
240            protected String encodeKey(
241                    long groupId, String articleId, double version, String templateId,
242                    long layoutSetId, String viewMode, String languageId, int page,
243                    boolean secure) {
244    
245                    StringBundler sb = new StringBundler();
246    
247                    sb.append(StringUtil.toHexString(groupId));
248                    sb.append(ARTICLE_SEPARATOR);
249                    sb.append(articleId);
250                    sb.append(VERSION_SEPARATOR);
251                    sb.append(version);
252                    sb.append(TEMPLATE_SEPARATOR);
253                    sb.append(templateId);
254    
255                    if (layoutSetId > 0) {
256                            sb.append(LAYOUT_SET_SEPARATOR);
257                            sb.append(StringUtil.toHexString(layoutSetId));
258                    }
259    
260                    if (Validator.isNotNull(viewMode)) {
261                            sb.append(VIEW_MODE_SEPARATOR);
262                            sb.append(viewMode);
263                    }
264    
265                    if (Validator.isNotNull(languageId)) {
266                            sb.append(LANGUAGE_SEPARATOR);
267                            sb.append(languageId);
268                    }
269    
270                    if (page > 0) {
271                            sb.append(PAGE_SEPARATOR);
272                            sb.append(StringUtil.toHexString(page));
273                    }
274    
275                    sb.append(SECURE_SEPARATOR);
276                    sb.append(secure);
277    
278                    return sb.toString();
279            }
280            protected JournalArticleDisplay getArticleDisplay(
281                    long groupId, String articleId, String templateId, String viewMode,
282                    String languageId, int page, String xmlRequest,
283                    ThemeDisplay themeDisplay) {
284    
285                    try {
286                            if (_log.isInfoEnabled()) {
287                                    _log.info(
288                                            "Get article display {" + groupId + ", " + articleId +
289                                                    ", " + templateId + "}");
290                            }
291    
292                            return JournalArticleLocalServiceUtil.getArticleDisplay(
293                                    groupId, articleId, templateId, viewMode, languageId, page,
294                                    xmlRequest, themeDisplay);
295                    }
296                    catch (Exception e) {
297                            if (_log.isWarnEnabled()) {
298                                    _log.warn(
299                                            "Unable to get display for " + groupId + " " +
300                                                    articleId + " " + languageId);
301                            }
302    
303                            return null;
304                    }
305            }
306    
307            protected boolean isLifecycleRender(
308                    ThemeDisplay themeDisplay, String xmlRequest) {
309    
310                    if (themeDisplay != null) {
311                            return themeDisplay.isLifecycleRender();
312                    }
313                    else if (Validator.isNotNull(xmlRequest)) {
314                            Matcher matcher = lifecycleRenderPhasePattern.matcher(xmlRequest);
315    
316                            return matcher.find();
317                    }
318                    else {
319                            return false;
320                    }
321            }
322    
323            protected static final String CACHE_NAME = JournalContent.class.getName();
324    
325            protected static Pattern lifecycleRenderPhasePattern = Pattern.compile(
326                    "<lifecycle>\\s*RENDER_PHASE\\s*</lifecycle>");
327            protected static PortalCache portalCache = MultiVMPoolUtil.getCache(
328                    CACHE_NAME);
329    
330            private static Log _log = LogFactoryUtil.getLog(JournalContentImpl.class);
331    
332    }