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.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.StringPool;
026    import com.liferay.portal.security.permission.ActionKeys;
027    import com.liferay.portal.security.permission.PermissionChecker;
028    import com.liferay.portal.util.PropsValues;
029    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
030    import com.liferay.portlet.asset.model.AssetEntry;
031    import com.liferay.portlet.asset.model.AssetRendererFactory;
032    import com.liferay.portlet.asset.service.base.AssetEntryServiceBaseImpl;
033    import com.liferay.portlet.asset.service.permission.AssetEntryPermission;
034    import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
035    import com.liferay.portlet.asset.util.AssetUtil;
036    
037    import java.util.ArrayList;
038    import java.util.Date;
039    import java.util.List;
040    
041    /**
042     * Provides the remote service for accessing and updating asset entries. Its
043     * methods include permission checks.
044     *
045     * @author Brian Wing Shun Chan
046     * @author Jorge Ferrer
047     * @author Bruno Farache
048     * @author Raymond Aug??
049     */
050    public class AssetEntryServiceImpl extends AssetEntryServiceBaseImpl {
051    
052            @Override
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            @Override
081            public int getCompanyEntriesCount(long companyId) throws SystemException {
082                    return assetEntryLocalService.getCompanyEntriesCount(companyId);
083            }
084    
085            @Override
086            public List<AssetEntry> getEntries(AssetEntryQuery entryQuery)
087                    throws PortalException, SystemException {
088    
089                    AssetEntryQuery filteredEntryQuery = buildFilteredEntryQuery(
090                            entryQuery);
091    
092                    if (hasEntryQueryResults(entryQuery, filteredEntryQuery)) {
093                            return new ArrayList<AssetEntry>();
094                    }
095    
096                    Object[] results = filterEntryQuery(filteredEntryQuery, false);
097    
098                    return (List<AssetEntry>)results[0];
099            }
100    
101            @Override
102            public int getEntriesCount(AssetEntryQuery entryQuery)
103                    throws PortalException, SystemException {
104    
105                    AssetEntryQuery filteredEntryQuery = buildFilteredEntryQuery(
106                            entryQuery);
107    
108                    if (hasEntryQueryResults(entryQuery, filteredEntryQuery)) {
109                            return 0;
110                    }
111    
112                    Object[] results = filterEntryQuery(filteredEntryQuery, true);
113    
114                    return (Integer)results[1];
115            }
116    
117            @Override
118            public AssetEntry getEntry(long entryId)
119                    throws PortalException, SystemException {
120    
121                    AssetEntryPermission.check(
122                            getPermissionChecker(), entryId, ActionKeys.VIEW);
123    
124                    return assetEntryLocalService.getEntry(entryId);
125            }
126    
127            @Override
128            public AssetEntry incrementViewCounter(String className, long classPK)
129                    throws PortalException, SystemException {
130    
131                    AssetEntryPermission.check(
132                            getPermissionChecker(), className, classPK, ActionKeys.VIEW);
133    
134                    return assetEntryLocalService.incrementViewCounter(
135                            getGuestOrUserId(), className, classPK);
136            }
137    
138            @Override
139            public AssetEntry updateEntry(
140                            long groupId, Date createDate, Date modifiedDate, String className,
141                            long classPK, String classUuid, long classTypeId,
142                            long[] categoryIds, String[] tagNames, boolean visible,
143                            Date startDate, Date endDate, Date expirationDate, String mimeType,
144                            String title, String description, String summary, String url,
145                            String layoutUuid, int height, int width, Integer priority,
146                            boolean sync)
147                    throws PortalException, SystemException {
148    
149                    AssetEntryPermission.check(
150                            getPermissionChecker(), className, classPK, ActionKeys.UPDATE);
151    
152                    return assetEntryLocalService.updateEntry(
153                            getUserId(), groupId, createDate, modifiedDate, className, classPK,
154                            classUuid, classTypeId, categoryIds, tagNames, visible, startDate,
155                            endDate, expirationDate, mimeType, title, description, summary, url,
156                            layoutUuid, height, width, priority, sync);
157            }
158    
159            /**
160             * @deprecated As of 6.2.0, replaced by {@link #updateEntry(long, String,
161             *             long, String, long, long[], String[], boolean, Date, Date,
162             *             Date, String, String, String, String, String, String, int,
163             *             int, Integer, boolean)}
164             */
165            @Override
166            public AssetEntry updateEntry(
167                            long groupId, String className, long classPK, String classUuid,
168                            long classTypeId, long[] categoryIds, String[] tagNames,
169                            boolean visible, Date startDate, Date endDate, Date publishDate,
170                            Date expirationDate, String mimeType, String title,
171                            String description, String summary, String url, String layoutUuid,
172                            int height, int width, Integer priority, boolean sync)
173                    throws PortalException, SystemException {
174    
175                    AssetEntryPermission.check(
176                            getPermissionChecker(), className, classPK, ActionKeys.UPDATE);
177    
178                    return assetEntryLocalService.updateEntry(
179                            getUserId(), groupId, className, classPK, classUuid, classTypeId,
180                            categoryIds, tagNames, visible, startDate, endDate, expirationDate,
181                            mimeType, title, description, summary, url, layoutUuid, height,
182                            width, priority, sync);
183            }
184    
185            /**
186             * @deprecated As of 6.2.0, replaced by {@link #updateEntry(long, Date,
187             *             Date, String, long, String, long, long[], String[], boolean,
188             *             Date, Date, Date, String, String, String, String, String,
189             *             String, int, int, Integer, boolean)}
190             */
191            @Override
192            public AssetEntry updateEntry(
193                            long groupId, String className, long classPK, String classUuid,
194                            long classTypeId, long[] categoryIds, String[] tagNames,
195                            boolean visible, Date startDate, Date endDate, Date expirationDate,
196                            String mimeType, String title, String description, String summary,
197                            String url, String layoutUuid, int height, int width,
198                            Integer priority, boolean sync)
199                    throws PortalException, SystemException {
200    
201                    return assetEntryLocalService.updateEntry(
202                            getUserId(), groupId, null, null, className, classPK, classUuid,
203                            classTypeId, categoryIds, tagNames, visible, startDate, endDate,
204                            expirationDate, mimeType, title, description, summary, url,
205                            layoutUuid, height, width, priority, sync);
206            }
207    
208            protected AssetEntryQuery buildFilteredEntryQuery(
209                            AssetEntryQuery entryQuery)
210                    throws PortalException, SystemException {
211    
212                    // Return an entry query with only the category ids and tag ids that the
213                    // user has access to
214    
215                    AssetEntryQuery filteredEntryQuery = new AssetEntryQuery(entryQuery);
216    
217                    filteredEntryQuery.setAllCategoryIds(
218                            AssetUtil.filterCategoryIds(
219                                    getPermissionChecker(), entryQuery.getAllCategoryIds()));
220                    filteredEntryQuery.setAllTagIdsArray(
221                            AssetUtil.filterTagIdsArray(
222                                    getPermissionChecker(), entryQuery.getAllTagIdsArray()));
223                    filteredEntryQuery.setAnyCategoryIds(
224                            AssetUtil.filterCategoryIds(
225                                    getPermissionChecker(), entryQuery.getAnyCategoryIds()));
226                    filteredEntryQuery.setAnyTagIds(
227                            AssetUtil.filterTagIds(
228                                    getPermissionChecker(), entryQuery.getAnyTagIds()));
229    
230                    return filteredEntryQuery;
231            }
232    
233            protected Object[] filterEntryQuery(
234                            AssetEntryQuery entryQuery, boolean returnEntriesCountOnly)
235                    throws PortalException, SystemException {
236    
237                    ThreadLocalCache<Object[]> threadLocalCache =
238                            ThreadLocalCacheManager.getThreadLocalCache(
239                                    Lifecycle.REQUEST, AssetEntryServiceImpl.class.getName());
240    
241                    String key = entryQuery.toString();
242    
243                    key = key.concat(StringPool.POUND).concat(
244                            Boolean.toString(returnEntriesCountOnly));
245    
246                    Object[] results = threadLocalCache.get(key);
247    
248                    if (results != null) {
249                            return results;
250                    }
251    
252                    if (returnEntriesCountOnly && !entryQuery.isEnablePermissions() &&
253                            !PropsValues.ASSET_PUBLISHER_FILTER_UNLISTABLE_ENTRIES) {
254    
255                            int entriesCount = assetEntryLocalService.getEntriesCount(
256                                    entryQuery);
257    
258                            results = new Object[] {null, entriesCount};
259    
260                            threadLocalCache.put(key, results);
261    
262                            return results;
263                    }
264    
265                    int end = entryQuery.getEnd();
266                    int start = entryQuery.getStart();
267    
268                    if (entryQuery.isEnablePermissions() ||
269                            PropsValues.ASSET_PUBLISHER_FILTER_UNLISTABLE_ENTRIES) {
270    
271                            entryQuery.setEnd(end + PropsValues.ASSET_FILTER_SEARCH_LIMIT);
272                            entryQuery.setStart(0);
273                    }
274    
275                    List<AssetEntry> entries = assetEntryLocalService.getEntries(
276                            entryQuery);
277    
278                    List<AssetEntry> filteredEntries = null;
279                    int filteredEntriesCount = 0;
280    
281                    if (entryQuery.isEnablePermissions() ||
282                            PropsValues.ASSET_PUBLISHER_FILTER_UNLISTABLE_ENTRIES) {
283    
284                            PermissionChecker permissionChecker = getPermissionChecker();
285    
286                            filteredEntries = new ArrayList<AssetEntry>();
287    
288                            for (AssetEntry entry : entries) {
289                                    String className = entry.getClassName();
290                                    long classPK = entry.getClassPK();
291    
292                                    AssetRendererFactory assetRendererFactory =
293                                            AssetRendererFactoryRegistryUtil.
294                                                    getAssetRendererFactoryByClassName(className);
295    
296                                    try {
297                                            if ((!entryQuery.isEnablePermissions() ||
298                                                     assetRendererFactory.hasPermission(
299                                                            permissionChecker, classPK, ActionKeys.VIEW)) &&
300                                                    (!PropsValues.
301                                                            ASSET_PUBLISHER_FILTER_UNLISTABLE_ENTRIES ||
302                                                     assetRendererFactory.isListable(classPK))) {
303    
304                                                    filteredEntries.add(entry);
305                                            }
306                                    }
307                                    catch (Exception e) {
308                                    }
309    
310                                    if ((end != QueryUtil.ALL_POS) &&
311                                            (filteredEntries.size() > end)) {
312    
313                                            break;
314                                    }
315                            }
316    
317                            filteredEntriesCount = filteredEntries.size();
318    
319                            if ((end != QueryUtil.ALL_POS) && (start != QueryUtil.ALL_POS)) {
320                                    if (end > filteredEntriesCount) {
321                                            end = filteredEntriesCount;
322                                    }
323    
324                                    if (start > filteredEntriesCount) {
325                                            start = filteredEntriesCount;
326                                    }
327    
328                                    filteredEntries = filteredEntries.subList(start, end);
329                            }
330    
331                            entryQuery.setEnd(end);
332                            entryQuery.setStart(start);
333                    }
334                    else {
335                            filteredEntries = entries;
336                            filteredEntriesCount = filteredEntries.size();
337                    }
338    
339                    results = new Object[] {filteredEntries, filteredEntriesCount};
340    
341                    threadLocalCache.put(key, results);
342    
343                    return results;
344            }
345    
346            protected boolean hasEntryQueryResults(
347                    AssetEntryQuery originalEntryQuery,
348                    AssetEntryQuery filteredEntryQuery) {
349    
350                    if (originalEntryQuery.getAllCategoryIds().length >
351                                    filteredEntryQuery.getAllCategoryIds().length) {
352    
353                            // No results will be available if the user must have access to all
354                            // category ids, but the user has access to fewer category ids in
355                            // the filtered entry query than what was specified in the original
356                            // entry query
357    
358                            return true;
359                    }
360    
361                    if (originalEntryQuery.getAllTagIds().length >
362                                    filteredEntryQuery.getAllTagIds().length) {
363    
364                            // No results will be available if the user must have access to all
365                            // tag ids, but the user has access to fewer tag ids in the filtered
366                            // entry query than what was specified in the original entry query
367    
368                            return true;
369                    }
370    
371                    if ((originalEntryQuery.getAnyCategoryIds().length > 0) &&
372                            (filteredEntryQuery.getAnyCategoryIds().length == 0)) {
373    
374                            // No results will be available if the original entry query
375                            // specified at least one category id, but the filtered entry query
376                            // shows that the user does not have access to any category ids
377    
378                            return true;
379                    }
380    
381                    if ((originalEntryQuery.getAnyTagIds().length > 0) &&
382                            (filteredEntryQuery.getAnyTagIds().length == 0)) {
383    
384                            // No results will be available if the original entry query
385                            // specified at least one tag id, but the filtered entry query shows
386                            // that the user does not have access to any tag ids
387    
388                            return true;
389                    }
390    
391                    return false;
392            }
393    
394            private static Log _log = LogFactoryUtil.getLog(
395                    AssetEntryServiceImpl.class);
396    
397    }