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                            int entriesCount = assetEntryLocalService.getEntriesCount(
254                                    entryQuery);
255    
256                            results = new Object[] {null, entriesCount};
257    
258                            threadLocalCache.put(key, results);
259    
260                            return results;
261                    }
262    
263                    int end = entryQuery.getEnd();
264                    int start = entryQuery.getStart();
265    
266                    if (entryQuery.isEnablePermissions()) {
267                            entryQuery.setEnd(end + PropsValues.ASSET_FILTER_SEARCH_LIMIT);
268                            entryQuery.setStart(0);
269                    }
270    
271                    List<AssetEntry> entries = assetEntryLocalService.getEntries(
272                            entryQuery);
273    
274                    List<AssetEntry> filteredEntries = null;
275                    int filteredEntriesCount = 0;
276    
277                    if (entryQuery.isEnablePermissions()) {
278                            PermissionChecker permissionChecker = getPermissionChecker();
279    
280                            filteredEntries = new ArrayList<AssetEntry>();
281    
282                            for (AssetEntry entry : entries) {
283                                    String className = entry.getClassName();
284                                    long classPK = entry.getClassPK();
285    
286                                    AssetRendererFactory assetRendererFactory =
287                                            AssetRendererFactoryRegistryUtil.
288                                                    getAssetRendererFactoryByClassName(className);
289    
290                                    try {
291                                            if (assetRendererFactory.hasPermission(
292                                                            permissionChecker, classPK, ActionKeys.VIEW)) {
293    
294                                                    filteredEntries.add(entry);
295                                            }
296                                    }
297                                    catch (Exception e) {
298                                    }
299    
300                                    if ((end != QueryUtil.ALL_POS) &&
301                                            (filteredEntries.size() > end)) {
302    
303                                            break;
304                                    }
305                            }
306    
307                            filteredEntriesCount = filteredEntries.size();
308    
309                            if ((end != QueryUtil.ALL_POS) && (start != QueryUtil.ALL_POS)) {
310                                    if (end > filteredEntriesCount) {
311                                            end = filteredEntriesCount;
312                                    }
313    
314                                    if (start > filteredEntriesCount) {
315                                            start = filteredEntriesCount;
316                                    }
317    
318                                    filteredEntries = filteredEntries.subList(start, end);
319                            }
320    
321                            entryQuery.setEnd(end);
322                            entryQuery.setStart(start);
323                    }
324                    else {
325                            filteredEntries = entries;
326                            filteredEntriesCount = filteredEntries.size();
327                    }
328    
329                    results = new Object[] {filteredEntries, filteredEntriesCount};
330    
331                    threadLocalCache.put(key, results);
332    
333                    return results;
334            }
335    
336            protected boolean hasEntryQueryResults(
337                    AssetEntryQuery originalEntryQuery,
338                    AssetEntryQuery filteredEntryQuery) {
339    
340                    if (originalEntryQuery.getAllCategoryIds().length >
341                                    filteredEntryQuery.getAllCategoryIds().length) {
342    
343                            // No results will be available if the user must have access to all
344                            // category ids, but the user has access to fewer category ids in
345                            // the filtered entry query than what was specified in the original
346                            // entry query
347    
348                            return true;
349                    }
350    
351                    if (originalEntryQuery.getAllTagIds().length >
352                                    filteredEntryQuery.getAllTagIds().length) {
353    
354                            // No results will be available if the user must have access to all
355                            // tag ids, but the user has access to fewer tag ids in the filtered
356                            // entry query than what was specified in the original entry query
357    
358                            return true;
359                    }
360    
361                    if ((originalEntryQuery.getAnyCategoryIds().length > 0) &&
362                            (filteredEntryQuery.getAnyCategoryIds().length == 0)) {
363    
364                            // No results will be available if the original entry query
365                            // specified at least one category id, but the filtered entry query
366                            // shows that the user does not have access to any category ids
367    
368                            return true;
369                    }
370    
371                    if ((originalEntryQuery.getAnyTagIds().length > 0) &&
372                            (filteredEntryQuery.getAnyTagIds().length == 0)) {
373    
374                            // No results will be available if the original entry query
375                            // specified at least one tag id, but the filtered entry query shows
376                            // that the user does not have access to any tag ids
377    
378                            return true;
379                    }
380    
381                    return false;
382            }
383    
384            private static Log _log = LogFactoryUtil.getLog(
385                    AssetEntryServiceImpl.class);
386    
387    }