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