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 = StringUtil.toUpperCase(GetterUtil.getString(articleId));
135                    ddmTemplateKey = StringUtil.toUpperCase(
136                            GetterUtil.getString(ddmTemplateKey));
137    
138                    long layoutSetId = 0;
139                    boolean secure = false;
140    
141                    if (themeDisplay != null) {
142                            try {
143                                    Layout layout = themeDisplay.getLayout();
144    
145                                    LayoutSet layoutSet = layout.getLayoutSet();
146    
147                                    layoutSetId = layoutSet.getLayoutSetId();
148                            }
149                            catch (Exception e) {
150                            }
151    
152                            secure = themeDisplay.isSecure();
153                    }
154    
155                    String key = encodeKey(
156                            groupId, articleId, version, ddmTemplateKey, layoutSetId, viewMode,
157                            languageId, page, secure);
158    
159                    JournalArticleDisplay articleDisplay = portalCache.get(key);
160    
161                    boolean lifecycleRender = isLifecycleRender(themeDisplay, xmlRequest);
162    
163                    if ((articleDisplay == null) || !lifecycleRender) {
164                            articleDisplay = getArticleDisplay(
165                                    groupId, articleId, ddmTemplateKey, viewMode, languageId, page,
166                                    xmlRequest, themeDisplay);
167    
168                            if ((articleDisplay != null) && articleDisplay.isCacheable() &&
169                                    lifecycleRender) {
170    
171                                    portalCache.put(key, articleDisplay);
172                            }
173                    }
174    
175                    try {
176                            if (PropsValues.JOURNAL_ARTICLE_VIEW_PERMISSION_CHECK_ENABLED &&
177                                    (articleDisplay != null) && (themeDisplay != null) &&
178                                    !JournalArticlePermission.contains(
179                                            themeDisplay.getPermissionChecker(), groupId, articleId,
180                                            ActionKeys.VIEW)) {
181    
182                                    articleDisplay = null;
183                            }
184                    }
185                    catch (Exception e) {
186                    }
187    
188                    if (_log.isDebugEnabled()) {
189                            _log.debug(
190                                    "getDisplay for {" + groupId + ", " + articleId + ", " +
191                                            ddmTemplateKey + ", " + viewMode + ", " + languageId +
192                                                    ", " + page + "} takes " + stopWatch.getTime() + " ms");
193                    }
194    
195                    return articleDisplay;
196            }
197    
198            @Override
199            public JournalArticleDisplay getDisplay(
200                    long groupId, String articleId, String viewMode, String languageId,
201                    String xmlRequest) {
202    
203                    return getDisplay(
204                            groupId, articleId, null, viewMode, languageId, null, 1,
205                            xmlRequest);
206            }
207    
208            @Override
209            public JournalArticleDisplay getDisplay(
210                    long groupId, String articleId, String ddmTemplateKey, String viewMode,
211                    String languageId, String xmlRequest) {
212    
213                    return getDisplay(
214                            groupId, articleId, ddmTemplateKey, viewMode, languageId, null, 1,
215                            xmlRequest);
216            }
217    
218            @Override
219            public JournalArticleDisplay getDisplay(
220                    long groupId, String articleId, String ddmTemplateKey, String viewMode,
221                    String languageId, ThemeDisplay themeDisplay) {
222    
223                    return getDisplay(
224                            groupId, articleId, ddmTemplateKey, viewMode, languageId,
225                            themeDisplay, 1, null);
226            }
227    
228            @Override
229            public JournalArticleDisplay getDisplay(
230                    long groupId, String articleId, String ddmTemplateKey, String viewMode,
231                    String languageId, ThemeDisplay themeDisplay, int page,
232                    String xmlRequest) {
233    
234                    return getDisplay(
235                            groupId, articleId, 0, ddmTemplateKey, viewMode, languageId,
236                            themeDisplay, 1, xmlRequest);
237            }
238    
239            @Override
240            public JournalArticleDisplay getDisplay(
241                    long groupId, String articleId, String viewMode, String languageId,
242                    ThemeDisplay themeDisplay) {
243    
244                    return getDisplay(
245                            groupId, articleId, viewMode, languageId, themeDisplay, 1);
246            }
247    
248            @Override
249            public JournalArticleDisplay getDisplay(
250                    long groupId, String articleId, String viewMode, String languageId,
251                    ThemeDisplay themeDisplay, int page) {
252    
253                    return getDisplay(
254                            groupId, articleId, null, viewMode, languageId, themeDisplay, page,
255                            null);
256            }
257    
258            protected String encodeKey(
259                    long groupId, String articleId, double version, String ddmTemplateKey,
260                    long layoutSetId, String viewMode, String languageId, int page,
261                    boolean secure) {
262    
263                    StringBundler sb = new StringBundler();
264    
265                    sb.append(StringUtil.toHexString(groupId));
266                    sb.append(ARTICLE_SEPARATOR);
267                    sb.append(articleId);
268                    sb.append(VERSION_SEPARATOR);
269                    sb.append(version);
270                    sb.append(TEMPLATE_SEPARATOR);
271                    sb.append(ddmTemplateKey);
272    
273                    if (layoutSetId > 0) {
274                            sb.append(LAYOUT_SET_SEPARATOR);
275                            sb.append(StringUtil.toHexString(layoutSetId));
276                    }
277    
278                    if (Validator.isNotNull(viewMode)) {
279                            sb.append(VIEW_MODE_SEPARATOR);
280                            sb.append(viewMode);
281                    }
282    
283                    if (Validator.isNotNull(languageId)) {
284                            sb.append(LANGUAGE_SEPARATOR);
285                            sb.append(languageId);
286                    }
287    
288                    if (page > 0) {
289                            sb.append(PAGE_SEPARATOR);
290                            sb.append(StringUtil.toHexString(page));
291                    }
292    
293                    sb.append(SECURE_SEPARATOR);
294                    sb.append(secure);
295    
296                    return sb.toString();
297            }
298    
299            protected JournalArticleDisplay getArticleDisplay(
300                    long groupId, String articleId, String ddmTemplateKey, String viewMode,
301                    String languageId, int page, String xmlRequest,
302                    ThemeDisplay themeDisplay) {
303    
304                    try {
305                            if (_log.isInfoEnabled()) {
306                                    _log.info(
307                                            "Get article display {" + groupId + ", " + articleId +
308                                                    ", " + ddmTemplateKey + "}");
309                            }
310    
311                            return JournalArticleLocalServiceUtil.getArticleDisplay(
312                                    groupId, articleId, ddmTemplateKey, viewMode, languageId, page,
313                                    xmlRequest, themeDisplay);
314                    }
315                    catch (Exception e) {
316                            if (_log.isWarnEnabled()) {
317                                    _log.warn(
318                                            "Unable to get display for " + groupId + " " +
319                                                    articleId + " " + languageId);
320                            }
321    
322                            return null;
323                    }
324            }
325    
326            protected boolean isLifecycleRender(
327                    ThemeDisplay themeDisplay, String xmlRequest) {
328    
329                    if (themeDisplay != null) {
330                            return themeDisplay.isLifecycleRender();
331                    }
332                    else if (Validator.isNotNull(xmlRequest)) {
333                            Matcher matcher = lifecycleRenderPhasePattern.matcher(xmlRequest);
334    
335                            return matcher.find();
336                    }
337                    else {
338                            return false;
339                    }
340            }
341    
342            protected static final String CACHE_NAME = JournalContent.class.getName();
343    
344            protected static Pattern lifecycleRenderPhasePattern = Pattern.compile(
345                    "<lifecycle>\\s*RENDER_PHASE\\s*</lifecycle>");
346            protected static PortalCache<String, JournalArticleDisplay> portalCache =
347                    MultiVMPoolUtil.getCache(CACHE_NAME);
348    
349            private static Log _log = LogFactoryUtil.getLog(JournalContentImpl.class);
350    
351    }