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