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