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