001    /**
002     * Copyright (c) 2000-2012 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.asset.service.impl;
016    
017    import com.liferay.portal.kernel.cache.Lifecycle;
018    import com.liferay.portal.kernel.cache.ThreadLocalCache;
019    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
020    import com.liferay.portal.kernel.dao.orm.QueryUtil;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.util.ArrayUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.security.permission.ActionKeys;
029    import com.liferay.portal.security.permission.PermissionChecker;
030    import com.liferay.portal.util.PropsValues;
031    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
032    import com.liferay.portlet.asset.model.AssetEntry;
033    import com.liferay.portlet.asset.model.AssetRendererFactory;
034    import com.liferay.portlet.asset.service.base.AssetEntryServiceBaseImpl;
035    import com.liferay.portlet.asset.service.permission.AssetCategoryPermission;
036    import com.liferay.portlet.asset.service.permission.AssetEntryPermission;
037    import com.liferay.portlet.asset.service.permission.AssetTagPermission;
038    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
039    import com.liferay.portlet.social.model.SocialActivityConstants;
040    
041    import java.util.ArrayList;
042    import java.util.Date;
043    import java.util.List;
044    
045    /**
046     * @author Brian Wing Shun Chan
047     * @author Jorge Ferrer
048     * @author Bruno Farache
049     * @author Raymond Augé
050     */
051    public class AssetEntryServiceImpl extends AssetEntryServiceBaseImpl {
052    
053            public List<AssetEntry> getCompanyEntries(
054                            long companyId, int start, int end)
055                    throws SystemException {
056    
057                    List<AssetEntry> entries = new ArrayList<AssetEntry>();
058    
059                    List<AssetEntry> companyEntries =
060                            assetEntryLocalService.getCompanyEntries(companyId, start, end);
061    
062                    for (AssetEntry entry : companyEntries) {
063                            try {
064                                    if (AssetEntryPermission.contains(
065                                                    getPermissionChecker(), entry, ActionKeys.VIEW)) {
066    
067                                            entries.add(entry);
068                                    }
069                            }
070                            catch (PortalException pe) {
071                                    if (_log.isWarnEnabled()) {
072                                            _log.warn(pe, pe);
073                                    }
074                            }
075                    }
076    
077                    return entries;
078            }
079    
080            public int getCompanyEntriesCount(long companyId) throws SystemException {
081                    return assetEntryLocalService.getCompanyEntriesCount(companyId);
082            }
083    
084            public List<AssetEntry> getEntries(AssetEntryQuery entryQuery)
085                    throws PortalException, SystemException {
086    
087                    AssetEntryQuery filteredEntryQuery = buildFilteredEntryQuery(
088                            entryQuery);
089    
090                    if (hasEntryQueryResults(entryQuery, filteredEntryQuery)) {
091                            return new ArrayList<AssetEntry>();
092                    }
093    
094                    Object[] results = filterEntryQuery(filteredEntryQuery, false);
095    
096                    return (List<AssetEntry>)results[0];
097            }
098    
099            public int getEntriesCount(AssetEntryQuery entryQuery)
100                    throws PortalException, SystemException {
101    
102                    AssetEntryQuery filteredEntryQuery = buildFilteredEntryQuery(
103                            entryQuery);
104    
105                    if (hasEntryQueryResults(entryQuery, filteredEntryQuery)) {
106                            return 0;
107                    }
108    
109                    Object[] results = filterEntryQuery(filteredEntryQuery, true);
110    
111                    return (Integer)results[1];
112            }
113    
114            public AssetEntry getEntry(long entryId)
115                    throws PortalException, SystemException {
116    
117                    AssetEntryPermission.check(
118                            getPermissionChecker(), entryId, ActionKeys.VIEW);
119    
120                    return assetEntryLocalService.getEntry(entryId);
121            }
122    
123            public AssetEntry incrementViewCounter(String className, long classPK)
124                    throws PortalException, SystemException {
125    
126                    AssetEntryPermission.check(
127                            getPermissionChecker(), className, classPK, ActionKeys.VIEW);
128    
129                    User user = getGuestOrUser();
130    
131                    assetEntryLocalService.incrementViewCounter(
132                            user.getUserId(), className, classPK, 1);
133    
134                    AssetEntry assetEntry = assetEntryLocalService.getEntry(
135                            className, classPK);
136    
137                    if (!user.isDefaultUser()) {
138                            socialActivityLocalService.addActivity(
139                                    user.getUserId(), assetEntry.getGroupId(), className, classPK,
140                                    SocialActivityConstants.TYPE_VIEW, StringPool.BLANK, 0);
141                    }
142    
143                    return assetEntry;
144            }
145    
146            public AssetEntry updateEntry(
147                            long groupId, Date createDate, Date modifiedDate, String className,
148                            long classPK, String classUuid, long classTypeId,
149                            long[] categoryIds, String[] tagNames, boolean visible,
150                            Date startDate, Date endDate, Date expirationDate, String mimeType,
151                            String title, String description, String summary, String url,
152                            String layoutUuid, int height, int width, Integer priority,
153                            boolean sync)
154                    throws PortalException, SystemException {
155    
156                    AssetEntryPermission.check(
157                            getPermissionChecker(), className, classPK, ActionKeys.UPDATE);
158    
159                    return assetEntryLocalService.updateEntry(
160                            getUserId(), groupId, createDate, modifiedDate, className, classPK,
161                            classUuid, classTypeId, categoryIds, tagNames, visible, startDate,
162                            endDate, expirationDate, mimeType, title, description, summary, url,
163                            layoutUuid, height, width, priority, sync);
164            }
165    
166            /**
167             * @deprecated {@link #updateEntry(long, String, long, String, long, long[],
168             *             String[], boolean, Date, Date, Date, String, String, String,
169             *             String, String, String, int, int, Integer, boolean)}
170             */
171            public AssetEntry updateEntry(
172                            long groupId, String className, long classPK, String classUuid,
173                            long classTypeId, long[] categoryIds, String[] tagNames,
174                            boolean visible, Date startDate, Date endDate, Date publishDate,
175                            Date expirationDate, String mimeType, String title,
176                            String description, String summary, String url, String layoutUuid,
177                            int height, int width, Integer priority, boolean sync)
178                    throws PortalException, SystemException {
179    
180                    AssetEntryPermission.check(
181                            getPermissionChecker(), className, classPK, ActionKeys.UPDATE);
182    
183                    return assetEntryLocalService.updateEntry(
184                            getUserId(), groupId, className, classPK, classUuid, classTypeId,
185                            categoryIds, tagNames, visible, startDate, endDate, expirationDate,
186                            mimeType, title, description, summary, url, layoutUuid, height,
187                            width, priority, sync);
188            }
189    
190            /**
191             * @deprecated {@link #updateEntry(long, Date, Date. String, long, String,
192             *             long, long[], String[], boolean, Date, Date, Date, String,
193             *             String, String, String, String, String, int, int, Integer,
194             *             boolean)}
195             */
196            public AssetEntry updateEntry(
197                            long groupId, String className, long classPK, String classUuid,
198                            long classTypeId, long[] categoryIds, String[] tagNames,
199                            boolean visible, Date startDate, Date endDate, Date expirationDate,
200                            String mimeType, String title, String description, String summary,
201                            String url, String layoutUuid, int height, int width,
202                            Integer priority, boolean sync)
203                    throws PortalException, SystemException {
204    
205                    return assetEntryLocalService.updateEntry(
206                            getUserId(), groupId, null, null, className, classPK, classUuid,
207                            classTypeId, categoryIds, tagNames, visible, startDate, endDate,
208                            expirationDate, mimeType, title, description, summary, url,
209                            layoutUuid, height, width, priority, sync);
210            }
211    
212            protected AssetEntryQuery buildFilteredEntryQuery(
213                            AssetEntryQuery entryQuery)
214                    throws PortalException, SystemException {
215    
216                    // Return an entry query with only the category ids and tag ids that the
217                    // user has access to
218    
219                    AssetEntryQuery filteredEntryQuery = new AssetEntryQuery(entryQuery);
220    
221                    filteredEntryQuery.setAllCategoryIds(
222                            filterCategoryIds(entryQuery.getAllCategoryIds()));
223                    filteredEntryQuery.setAllTagIdsArray(
224                            filterTagIdsArray(entryQuery.getAllTagIdsArray()));
225                    filteredEntryQuery.setAnyCategoryIds(
226                            filterCategoryIds(entryQuery.getAnyCategoryIds()));
227                    filteredEntryQuery.setAnyTagIds(
228                            filterTagIds(entryQuery.getAnyTagIds()));
229    
230                    return filteredEntryQuery;
231            }
232    
233            protected long[] filterCategoryIds(long[] categoryIds)
234                    throws PortalException, SystemException {
235    
236                    List<Long> viewableCategoryIds = new ArrayList<Long>();
237    
238                    for (long categoryId : categoryIds) {
239                            if (AssetCategoryPermission.contains(
240                                            getPermissionChecker(), categoryId, ActionKeys.VIEW)) {
241    
242                                    viewableCategoryIds.add(categoryId);
243                            }
244                    }
245    
246                    return ArrayUtil.toArray(
247                            viewableCategoryIds.toArray(new Long[viewableCategoryIds.size()]));
248            }
249    
250            protected Object[] filterEntryQuery(
251                            AssetEntryQuery entryQuery, boolean returnEntriesCountOnly)
252                    throws PortalException, SystemException {
253    
254                    ThreadLocalCache<Object[]> threadLocalCache =
255                            ThreadLocalCacheManager.getThreadLocalCache(
256                                    Lifecycle.REQUEST, AssetEntryServiceImpl.class.getName());
257    
258                    String key = entryQuery.toString();
259    
260                    key = key.concat(StringPool.POUND).concat(
261                            Boolean.toString(returnEntriesCountOnly));
262    
263                    Object[] results = threadLocalCache.get(key);
264    
265                    if (results != null) {
266                            return results;
267                    }
268    
269                    if (returnEntriesCountOnly && !entryQuery.isEnablePermissions()) {
270                            int entriesCount = assetEntryLocalService.getEntriesCount(
271                                    entryQuery);
272    
273                            results = new Object[] {null, entriesCount};
274    
275                            threadLocalCache.put(key, results);
276    
277                            return results;
278                    }
279    
280                    int end = entryQuery.getEnd();
281                    int start = entryQuery.getStart();
282    
283                    if (entryQuery.isEnablePermissions()) {
284                            entryQuery.setEnd(end + PropsValues.ASSET_FILTER_SEARCH_LIMIT);
285                            entryQuery.setStart(0);
286                    }
287    
288                    List<AssetEntry> entries = assetEntryLocalService.getEntries(
289                            entryQuery);
290    
291                    List<AssetEntry> filteredEntries = null;
292                    int filteredEntriesCount = 0;
293    
294                    if (entryQuery.isEnablePermissions()) {
295                            PermissionChecker permissionChecker = getPermissionChecker();
296    
297                            filteredEntries = new ArrayList<AssetEntry>();
298    
299                            for (AssetEntry entry : entries) {
300                                    String className = entry.getClassName();
301                                    long classPK = entry.getClassPK();
302    
303                                    AssetRendererFactory assetRendererFactory =
304                                            AssetRendererFactoryRegistryUtil.
305                                                    getAssetRendererFactoryByClassName(className);
306    
307                                    try {
308                                            if (assetRendererFactory.hasPermission(
309                                                            permissionChecker, classPK, ActionKeys.VIEW)) {
310    
311                                                    filteredEntries.add(entry);
312                                            }
313                                    }
314                                    catch (Exception e) {
315                                    }
316    
317                                    if ((end != QueryUtil.ALL_POS) &&
318                                            (filteredEntries.size() > end)) {
319    
320                                            break;
321                                    }
322                            }
323    
324                            filteredEntriesCount = filteredEntries.size();
325    
326                            if ((end != QueryUtil.ALL_POS) && (start != QueryUtil.ALL_POS)) {
327                                    if (end > filteredEntriesCount) {
328                                            end = filteredEntriesCount;
329                                    }
330    
331                                    if (start > filteredEntriesCount) {
332                                            start = filteredEntriesCount;
333                                    }
334    
335                                    filteredEntries = filteredEntries.subList(start, end);
336                            }
337    
338                            entryQuery.setEnd(end);
339                            entryQuery.setStart(start);
340                    }
341                    else {
342                            filteredEntries = entries;
343                            filteredEntriesCount = filteredEntries.size();
344                    }
345    
346                    results = new Object[] {filteredEntries, filteredEntriesCount};
347    
348                    threadLocalCache.put(key, results);
349    
350                    return results;
351            }
352    
353            protected long[] filterTagIds(long[] tagIds)
354                    throws PortalException, SystemException {
355    
356                    List<Long> viewableTagIds = new ArrayList<Long>();
357    
358                    for (long tagId : tagIds) {
359                            if (AssetTagPermission.contains(
360                                            getPermissionChecker(), tagId, ActionKeys.VIEW)) {
361    
362                                    viewableTagIds.add(tagId);
363                            }
364                    }
365    
366                    return ArrayUtil.toArray(
367                            viewableTagIds.toArray(new Long[viewableTagIds.size()]));
368            }
369    
370            protected long[][] filterTagIdsArray(long[][] tagIdsArray)
371                    throws PortalException, SystemException {
372    
373                    List<long[]> viewableTagIdsArray = new ArrayList<long[]>();
374    
375                    for (int i = 0; i< tagIdsArray.length; i++) {
376                            long[] tagIds = tagIdsArray[i];
377    
378                            List<Long> viewableTagIds = new ArrayList<Long>();
379    
380                            for (long tagId : tagIds) {
381                                    if (AssetTagPermission.contains(
382                                                    getPermissionChecker(), tagId, ActionKeys.VIEW)) {
383    
384                                            viewableTagIds.add(tagId);
385                                    }
386                            }
387    
388                            viewableTagIdsArray.add(
389                                    ArrayUtil.toArray(
390                                            viewableTagIds.toArray(new Long[viewableTagIds.size()])));
391                    }
392    
393                    return viewableTagIdsArray.toArray(
394                            new long[viewableTagIdsArray.size()][]);
395            }
396    
397            protected boolean hasEntryQueryResults(
398                    AssetEntryQuery originalEntryQuery,
399                    AssetEntryQuery filteredEntryQuery) {
400    
401                    if (originalEntryQuery.getAllCategoryIds().length >
402                                    filteredEntryQuery.getAllCategoryIds().length) {
403    
404                            // No results will be available if the user must have access to all
405                            // category ids, but the user has access to fewer category ids in
406                            // the filtered entry query than what was specified in the original
407                            // entry query
408    
409                            return true;
410                    }
411    
412                    if (originalEntryQuery.getAllTagIds().length >
413                                    filteredEntryQuery.getAllTagIds().length) {
414    
415                            // No results will be available if the user must have access to all
416                            // tag ids, but the user has access to fewer tag ids in the filtered
417                            // entry query than what was specified in the original entry query
418    
419                            return true;
420                    }
421    
422                    if ((originalEntryQuery.getAnyCategoryIds().length > 0) &&
423                            (filteredEntryQuery.getAnyCategoryIds().length == 0)) {
424    
425                            // No results will be available if the original entry query
426                            // specified at least one category id, but the filtered entry query
427                            // shows that the user does not have access to any category ids
428    
429                            return true;
430                    }
431    
432                    if ((originalEntryQuery.getAnyTagIds().length > 0) &&
433                            (filteredEntryQuery.getAnyTagIds().length == 0)) {
434    
435                            // No results will be available if the original entry query
436                            // specified at least one tag id, but the filtered entry query
437                            // shows that the user does not have access to any tag ids
438    
439                            return true;
440                    }
441    
442                    return false;
443            }
444    
445            private static Log _log = LogFactoryUtil.getLog(
446                    AssetEntryServiceImpl.class);
447    
448    }