001
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.cache.index.IndexEncoder;
020 import com.liferay.portal.kernel.cache.index.PortalCacheIndexer;
021 import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
022 import com.liferay.portal.kernel.cluster.ClusterInvokeThreadLocal;
023 import com.liferay.portal.kernel.cluster.ClusterRequest;
024 import com.liferay.portal.kernel.exception.SystemException;
025 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
026 import com.liferay.portal.kernel.log.Log;
027 import com.liferay.portal.kernel.log.LogFactoryUtil;
028 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.HashUtil;
031 import com.liferay.portal.kernel.util.MethodHandler;
032 import com.liferay.portal.kernel.util.MethodKey;
033 import com.liferay.portal.kernel.util.StringBundler;
034 import com.liferay.portal.kernel.util.StringPool;
035 import com.liferay.portal.kernel.util.StringUtil;
036 import com.liferay.portal.kernel.util.Validator;
037 import com.liferay.portal.model.Layout;
038 import com.liferay.portal.model.LayoutSet;
039 import com.liferay.portal.security.permission.ActionKeys;
040 import com.liferay.portal.theme.ThemeDisplay;
041 import com.liferay.portlet.journal.model.JournalArticleDisplay;
042 import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
043 import com.liferay.portlet.journal.service.permission.JournalArticlePermission;
044
045 import java.io.Serializable;
046
047 import java.util.regex.Matcher;
048 import java.util.regex.Pattern;
049
050 import org.apache.commons.lang.time.StopWatch;
051
052
057 @DoPrivileged
058 public class JournalContentImpl implements JournalContent {
059
060 @Override
061 public void clearCache() {
062 if (ExportImportThreadLocal.isImportInProcess()) {
063 return;
064 }
065
066 _portalCache.removeAll();
067 }
068
069 @Override
070 public void clearCache(
071 long groupId, String articleId, String ddmTemplateKey) {
072
073 _portalCacheIndexer.removeKeys(
074 JournalContentKeyIndexEncoder.encode(
075 groupId, articleId, ddmTemplateKey));
076
077 if (!ClusterInvokeThreadLocal.isEnabled()) {
078 return;
079 }
080
081 MethodHandler methodHandler = new MethodHandler(
082 _clearCacheMethodKey, groupId, articleId, ddmTemplateKey);
083
084 ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
085 methodHandler, true);
086
087 clusterRequest.setFireAndForget(true);
088
089 try {
090 ClusterExecutorUtil.execute(clusterRequest);
091 }
092 catch (SystemException se) {
093 _log.error(se, se);
094 }
095 }
096
097 @Override
098 public String getContent(
099 long groupId, String articleId, String viewMode, String languageId,
100 String xmlRequest) {
101
102 return getContent(
103 groupId, articleId, null, viewMode, languageId, null, xmlRequest);
104 }
105
106 @Override
107 public String getContent(
108 long groupId, String articleId, String ddmTemplateKey, String viewMode,
109 String languageId, String xmlRequest) {
110
111 return getContent(
112 groupId, articleId, ddmTemplateKey, viewMode, languageId, null,
113 xmlRequest);
114 }
115
116 @Override
117 public String getContent(
118 long groupId, String articleId, String ddmTemplateKey, String viewMode,
119 String languageId, ThemeDisplay themeDisplay) {
120
121 return getContent(
122 groupId, articleId, ddmTemplateKey, viewMode, languageId,
123 themeDisplay, null);
124 }
125
126 @Override
127 public String getContent(
128 long groupId, String articleId, String ddmTemplateKey, String viewMode,
129 String languageId, ThemeDisplay themeDisplay, String xmlRequest) {
130
131 JournalArticleDisplay articleDisplay = getDisplay(
132 groupId, articleId, ddmTemplateKey, viewMode, languageId,
133 themeDisplay, 1, xmlRequest);
134
135 if (articleDisplay != null) {
136 return articleDisplay.getContent();
137 }
138 else {
139 return null;
140 }
141 }
142
143 @Override
144 public String getContent(
145 long groupId, String articleId, String viewMode, String languageId,
146 ThemeDisplay themeDisplay) {
147
148 return getContent(
149 groupId, articleId, null, viewMode, languageId, themeDisplay);
150 }
151
152 @Override
153 public JournalArticleDisplay getDisplay(
154 long groupId, String articleId, double version, String ddmTemplateKey,
155 String viewMode, String languageId, ThemeDisplay themeDisplay, int page,
156 String xmlRequest) {
157
158 StopWatch stopWatch = new StopWatch();
159
160 stopWatch.start();
161
162 articleId = StringUtil.toUpperCase(GetterUtil.getString(articleId));
163 ddmTemplateKey = StringUtil.toUpperCase(
164 GetterUtil.getString(ddmTemplateKey));
165
166 long layoutSetId = 0;
167 boolean secure = false;
168
169 if (themeDisplay != null) {
170 try {
171 if (!JournalArticlePermission.contains(
172 themeDisplay.getPermissionChecker(), groupId, articleId,
173 ActionKeys.VIEW)) {
174
175 return null;
176 }
177
178 Layout layout = themeDisplay.getLayout();
179
180 LayoutSet layoutSet = layout.getLayoutSet();
181
182 layoutSetId = layoutSet.getLayoutSetId();
183 }
184 catch (Exception e) {
185 }
186
187 secure = themeDisplay.isSecure();
188 }
189
190 JournalContentKey journalContentKey = new JournalContentKey(
191 groupId, articleId, version, ddmTemplateKey, layoutSetId, viewMode,
192 languageId, page, secure);
193
194 JournalArticleDisplay articleDisplay = _portalCache.get(
195 journalContentKey);
196
197 boolean lifecycleRender = isLifecycleRender(themeDisplay, xmlRequest);
198
199 if ((articleDisplay == null) || !lifecycleRender) {
200 articleDisplay = getArticleDisplay(
201 groupId, articleId, ddmTemplateKey, viewMode, languageId, page,
202 xmlRequest, themeDisplay);
203
204 if ((articleDisplay != null) && articleDisplay.isCacheable() &&
205 lifecycleRender) {
206
207 _portalCache.put(journalContentKey, articleDisplay);
208 }
209 }
210
211 if (_log.isDebugEnabled()) {
212 _log.debug(
213 "getDisplay for {" + groupId + ", " + articleId + ", " +
214 ddmTemplateKey + ", " + viewMode + ", " + languageId +
215 ", " + page + "} takes " + stopWatch.getTime() + " ms");
216 }
217
218 return articleDisplay;
219 }
220
221 @Override
222 public JournalArticleDisplay getDisplay(
223 long groupId, String articleId, String viewMode, String languageId,
224 String xmlRequest) {
225
226 return getDisplay(
227 groupId, articleId, null, viewMode, languageId, null, 1,
228 xmlRequest);
229 }
230
231 @Override
232 public JournalArticleDisplay getDisplay(
233 long groupId, String articleId, String ddmTemplateKey, String viewMode,
234 String languageId, String xmlRequest) {
235
236 return getDisplay(
237 groupId, articleId, ddmTemplateKey, viewMode, languageId, null, 1,
238 xmlRequest);
239 }
240
241 @Override
242 public JournalArticleDisplay getDisplay(
243 long groupId, String articleId, String ddmTemplateKey, String viewMode,
244 String languageId, ThemeDisplay themeDisplay) {
245
246 return getDisplay(
247 groupId, articleId, ddmTemplateKey, viewMode, languageId,
248 themeDisplay, 1, null);
249 }
250
251 @Override
252 public JournalArticleDisplay getDisplay(
253 long groupId, String articleId, String ddmTemplateKey, String viewMode,
254 String languageId, ThemeDisplay themeDisplay, int page,
255 String xmlRequest) {
256
257 return getDisplay(
258 groupId, articleId, 0, ddmTemplateKey, viewMode, languageId,
259 themeDisplay, 1, xmlRequest);
260 }
261
262 @Override
263 public JournalArticleDisplay getDisplay(
264 long groupId, String articleId, String viewMode, String languageId,
265 ThemeDisplay themeDisplay) {
266
267 return getDisplay(
268 groupId, articleId, viewMode, languageId, themeDisplay, 1);
269 }
270
271 @Override
272 public JournalArticleDisplay getDisplay(
273 long groupId, String articleId, String viewMode, String languageId,
274 ThemeDisplay themeDisplay, int page) {
275
276 return getDisplay(
277 groupId, articleId, null, viewMode, languageId, themeDisplay, page,
278 null);
279 }
280
281 protected JournalArticleDisplay getArticleDisplay(
282 long groupId, String articleId, String ddmTemplateKey, String viewMode,
283 String languageId, int page, String xmlRequest,
284 ThemeDisplay themeDisplay) {
285
286 try {
287 if (_log.isInfoEnabled()) {
288 _log.info(
289 "Get article display {" + groupId + ", " + articleId +
290 ", " + ddmTemplateKey + "}");
291 }
292
293 return JournalArticleLocalServiceUtil.getArticleDisplay(
294 groupId, articleId, ddmTemplateKey, viewMode, languageId, page,
295 xmlRequest, themeDisplay);
296 }
297 catch (Exception e) {
298 if (_log.isWarnEnabled()) {
299 _log.warn(
300 "Unable to get display for " + groupId + " " +
301 articleId + " " + languageId);
302 }
303
304 return null;
305 }
306 }
307
308 protected boolean isLifecycleRender(
309 ThemeDisplay themeDisplay, String xmlRequest) {
310
311 if (themeDisplay != null) {
312 return themeDisplay.isLifecycleRender();
313 }
314 else if (Validator.isNotNull(xmlRequest)) {
315 Matcher matcher = lifecycleRenderPhasePattern.matcher(xmlRequest);
316
317 return matcher.find();
318 }
319 else {
320 return false;
321 }
322 }
323
324 protected static final String CACHE_NAME = JournalContent.class.getName();
325
326 protected static Pattern lifecycleRenderPhasePattern = Pattern.compile(
327 "<lifecycle>\\s*RENDER_PHASE\\s*</lifecycle>");
328
329 private static final IndexEncoder<String, JournalContentKey> _indexEncoder =
330 new JournalContentKeyIndexEncoder();
331 private static final PortalCache<JournalContentKey, JournalArticleDisplay>
332 _portalCache = MultiVMPoolUtil.getCache(CACHE_NAME);
333 private static final PortalCacheIndexer
334 <String, JournalContentKey, JournalArticleDisplay> _portalCacheIndexer =
335 new PortalCacheIndexer
336 <String, JournalContentKey, JournalArticleDisplay> (
337 _indexEncoder, _portalCache);
338
339 private static Log _log = LogFactoryUtil.getLog(JournalContentImpl.class);
340
341 private static final MethodKey _clearCacheMethodKey = new MethodKey(
342 JournalContentUtil.class,
343 "clearCache", long.class, String.class, String.class);
344
345 private static class JournalContentKey implements Serializable {
346
347 @Override
348 public boolean equals(Object obj) {
349 JournalContentKey journalContentKey = (JournalContentKey)obj;
350
351 if ((journalContentKey._groupId == _groupId) &&
352 Validator.equals(journalContentKey._articleId, _articleId) &&
353 (journalContentKey._version == _version) &&
354 Validator.equals(
355 journalContentKey._ddmTemplateKey, _ddmTemplateKey) &&
356 (journalContentKey._layoutSetId == _layoutSetId) &&
357 Validator.equals(journalContentKey._viewMode, _viewMode) &&
358 Validator.equals(journalContentKey._languageId, _languageId) &&
359 (journalContentKey._page == _page) &&
360 (journalContentKey._secure == _secure)) {
361
362 return true;
363 }
364
365 return false;
366 }
367
368 @Override
369 public int hashCode() {
370 int hashCode = HashUtil.hash(0, _groupId);
371
372 hashCode = HashUtil.hash(hashCode, _articleId);
373 hashCode = HashUtil.hash(hashCode, _version);
374 hashCode = HashUtil.hash(hashCode, _ddmTemplateKey);
375 hashCode = HashUtil.hash(hashCode, _layoutSetId);
376 hashCode = HashUtil.hash(hashCode, _viewMode);
377 hashCode = HashUtil.hash(hashCode, _languageId);
378 hashCode = HashUtil.hash(hashCode, _page);
379
380 return HashUtil.hash(hashCode, _secure);
381 }
382
383 private JournalContentKey(
384 long groupId, String articleId, double version,
385 String ddmTemplateKey, long layoutSetId, String viewMode,
386 String languageId, int page, boolean secure) {
387
388 _groupId = groupId;
389 _articleId = articleId;
390 _version = version;
391 _ddmTemplateKey = ddmTemplateKey;
392 _layoutSetId = layoutSetId;
393 _viewMode = viewMode;
394 _languageId = languageId;
395 _page = page;
396 _secure = secure;
397 }
398
399 private static final long serialVersionUID = 1L;
400
401 private final String _articleId;
402 private final String _ddmTemplateKey;
403 private final long _groupId;
404 private final String _languageId;
405 private final long _layoutSetId;
406 private final int _page;
407 private final boolean _secure;
408 private final double _version;
409 private final String _viewMode;
410
411 }
412
413 private static class JournalContentKeyIndexEncoder
414 implements IndexEncoder<String, JournalContentKey> {
415
416 public static String encode(
417 long groupId, String articleId, String ddmTemplateKey) {
418
419 StringBundler sb = new StringBundler(5);
420
421 sb.append(groupId);
422 sb.append(StringPool.UNDERLINE);
423 sb.append(articleId);
424 sb.append(StringPool.UNDERLINE);
425 sb.append(ddmTemplateKey);
426
427 return sb.toString();
428 }
429
430 @Override
431 public String encode(JournalContentKey key) {
432 return encode(key._groupId, key._articleId, key._ddmTemplateKey);
433 }
434
435 }
436
437 }