001    /**
002     * Copyright (c) 2000-present 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.exception.PortalException;
018    import com.liferay.portal.kernel.search.BaseModelSearchResult;
019    import com.liferay.portal.kernel.search.Document;
020    import com.liferay.portal.kernel.search.Field;
021    import com.liferay.portal.kernel.search.Hits;
022    import com.liferay.portal.kernel.search.Indexable;
023    import com.liferay.portal.kernel.search.IndexableType;
024    import com.liferay.portal.kernel.search.Indexer;
025    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026    import com.liferay.portal.kernel.search.QueryConfig;
027    import com.liferay.portal.kernel.search.SearchContext;
028    import com.liferay.portal.kernel.search.SearchException;
029    import com.liferay.portal.kernel.systemevent.SystemEvent;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.LocaleUtil;
032    import com.liferay.portal.kernel.util.OrderByComparator;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.ResourceConstants;
037    import com.liferay.portal.model.SystemEventConstants;
038    import com.liferay.portal.model.User;
039    import com.liferay.portal.service.ServiceContext;
040    import com.liferay.portal.util.PropsValues;
041    import com.liferay.portlet.asset.DuplicateVocabularyException;
042    import com.liferay.portlet.asset.VocabularyNameException;
043    import com.liferay.portlet.asset.model.AssetCategoryConstants;
044    import com.liferay.portlet.asset.model.AssetVocabulary;
045    import com.liferay.portlet.asset.service.base.AssetVocabularyLocalServiceBaseImpl;
046    import com.liferay.portlet.asset.util.AssetUtil;
047    
048    import java.util.ArrayList;
049    import java.util.HashMap;
050    import java.util.List;
051    import java.util.Locale;
052    import java.util.Map;
053    
054    /**
055     * Provides the local service for accessing, adding, deleting, and updating
056     * asset vocabularies.
057     *
058     * @author Alvaro del Castillo
059     * @author Eduardo Lundgren
060     * @author Jorge Ferrer
061     * @author Juan Fern??ndez
062     */
063    public class AssetVocabularyLocalServiceImpl
064            extends AssetVocabularyLocalServiceBaseImpl {
065    
066            @Override
067            public AssetVocabulary addDefaultVocabulary(long groupId)
068                    throws PortalException {
069    
070                    Group group = groupLocalService.getGroup(groupId);
071    
072                    long defaultUserId = userLocalService.getDefaultUserId(
073                            group.getCompanyId());
074    
075                    Map<Locale, String> titleMap = new HashMap<>();
076    
077                    titleMap.put(
078                            LocaleUtil.getSiteDefault(), PropsValues.ASSET_VOCABULARY_DEFAULT);
079    
080                    ServiceContext serviceContext = new ServiceContext();
081    
082                    serviceContext.setScopeGroupId(groupId);
083    
084                    return assetVocabularyLocalService.addVocabulary(
085                            defaultUserId, groupId, StringPool.BLANK, titleMap, null,
086                            StringPool.BLANK, serviceContext);
087            }
088    
089            @Indexable(type = IndexableType.REINDEX)
090            @Override
091            public AssetVocabulary addVocabulary(
092                            long userId, long groupId, String title,
093                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
094                            String settings, ServiceContext serviceContext)
095                    throws PortalException {
096    
097                    // Vocabulary
098    
099                    User user = userPersistence.findByPrimaryKey(userId);
100                    String name = titleMap.get(LocaleUtil.getSiteDefault());
101    
102                    validate(groupId, name);
103    
104                    long vocabularyId = counterLocalService.increment();
105    
106                    AssetVocabulary vocabulary = assetVocabularyPersistence.create(
107                            vocabularyId);
108    
109                    vocabulary.setUuid(serviceContext.getUuid());
110                    vocabulary.setGroupId(groupId);
111                    vocabulary.setCompanyId(user.getCompanyId());
112                    vocabulary.setUserId(user.getUserId());
113                    vocabulary.setUserName(user.getFullName());
114                    vocabulary.setName(name);
115    
116                    if (Validator.isNotNull(title)) {
117                            vocabulary.setTitle(title);
118                    }
119                    else {
120                            vocabulary.setTitleMap(titleMap);
121                    }
122    
123                    vocabulary.setDescriptionMap(descriptionMap);
124                    vocabulary.setSettings(settings);
125    
126                    assetVocabularyPersistence.update(vocabulary);
127    
128                    // Resources
129    
130                    if (serviceContext.isAddGroupPermissions() ||
131                            serviceContext.isAddGuestPermissions()) {
132    
133                            addVocabularyResources(
134                                    vocabulary, serviceContext.isAddGroupPermissions(),
135                                    serviceContext.isAddGuestPermissions());
136                    }
137                    else {
138                            addVocabularyResources(
139                                    vocabulary, serviceContext.getGroupPermissions(),
140                                    serviceContext.getGuestPermissions());
141                    }
142    
143                    return vocabulary;
144            }
145    
146            @Override
147            public AssetVocabulary addVocabulary(
148                            long userId, long groupId, String title,
149                            ServiceContext serviceContext)
150                    throws PortalException {
151    
152                    Map<Locale, String> titleMap = new HashMap<>();
153    
154                    Locale locale = LocaleUtil.getSiteDefault();
155    
156                    titleMap.put(locale, title);
157    
158                    Map<Locale, String> descriptionMap = new HashMap<>();
159    
160                    descriptionMap.put(locale, StringPool.BLANK);
161    
162                    return assetVocabularyLocalService.addVocabulary(
163                            userId, groupId, title, titleMap, descriptionMap, null,
164                            serviceContext);
165            }
166    
167            @Override
168            public void addVocabularyResources(
169                            AssetVocabulary vocabulary, boolean addGroupPermissions,
170                            boolean addGuestPermissions)
171                    throws PortalException {
172    
173                    resourceLocalService.addResources(
174                            vocabulary.getCompanyId(), vocabulary.getGroupId(),
175                            vocabulary.getUserId(), AssetVocabulary.class.getName(),
176                            vocabulary.getVocabularyId(), false, addGroupPermissions,
177                            addGuestPermissions);
178            }
179    
180            @Override
181            public void addVocabularyResources(
182                            AssetVocabulary vocabulary, String[] groupPermissions,
183                            String[] guestPermissions)
184                    throws PortalException {
185    
186                    resourceLocalService.addModelResources(
187                            vocabulary.getCompanyId(), vocabulary.getGroupId(),
188                            vocabulary.getUserId(), AssetVocabulary.class.getName(),
189                            vocabulary.getVocabularyId(), groupPermissions, guestPermissions);
190            }
191    
192            @Override
193            public void deleteVocabularies(long groupId) throws PortalException {
194                    List<AssetVocabulary> vocabularies =
195                            assetVocabularyPersistence.findByGroupId(groupId);
196    
197                    for (AssetVocabulary vocabulary : vocabularies) {
198                            assetVocabularyLocalService.deleteVocabulary(vocabulary);
199                    }
200            }
201    
202            @Indexable(type = IndexableType.DELETE)
203            @Override
204            @SystemEvent(
205                    action = SystemEventConstants.ACTION_SKIP,
206                    type = SystemEventConstants.TYPE_DELETE
207            )
208            public void deleteVocabulary(AssetVocabulary vocabulary)
209                    throws PortalException {
210    
211                    // Vocabulary
212    
213                    assetVocabularyPersistence.remove(vocabulary);
214    
215                    // Resources
216    
217                    resourceLocalService.deleteResource(
218                            vocabulary.getCompanyId(), AssetVocabulary.class.getName(),
219                            ResourceConstants.SCOPE_INDIVIDUAL, vocabulary.getVocabularyId());
220    
221                    // Categories
222    
223                    assetCategoryLocalService.deleteVocabularyCategories(
224                            vocabulary.getVocabularyId());
225            }
226    
227            @Override
228            public void deleteVocabulary(long vocabularyId) throws PortalException {
229                    AssetVocabulary vocabulary =
230                            assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
231    
232                    assetVocabularyLocalService.deleteVocabulary(vocabulary);
233            }
234    
235            @Override
236            public List<AssetVocabulary> getCompanyVocabularies(long companyId) {
237                    return assetVocabularyPersistence.findByCompanyId(companyId);
238            }
239    
240            @Override
241            public List<AssetVocabulary> getGroupsVocabularies(long[] groupIds) {
242                    return getGroupsVocabularies(groupIds, null);
243            }
244    
245            @Override
246            public List<AssetVocabulary> getGroupsVocabularies(
247                    long[] groupIds, String className) {
248    
249                    return getGroupsVocabularies(
250                            groupIds, className, AssetCategoryConstants.ALL_CLASS_TYPE_PK);
251            }
252    
253            @Override
254            public List<AssetVocabulary> getGroupsVocabularies(
255                    long[] groupIds, String className, long classTypePK) {
256    
257                    List<AssetVocabulary> vocabularies =
258                            assetVocabularyPersistence.findByGroupId(groupIds);
259    
260                    if (Validator.isNull(className)) {
261                            return vocabularies;
262                    }
263    
264                    return AssetUtil.filterVocabularies(
265                            vocabularies, className, classTypePK);
266            }
267    
268            @Override
269            public List<AssetVocabulary> getGroupVocabularies(long groupId)
270                    throws PortalException {
271    
272                    return getGroupVocabularies(groupId, true);
273            }
274    
275            @Override
276            public List<AssetVocabulary> getGroupVocabularies(
277                            long groupId, boolean addDefaultVocabulary)
278                    throws PortalException {
279    
280                    List<AssetVocabulary> vocabularies =
281                            assetVocabularyPersistence.findByGroupId(groupId);
282    
283                    if (!vocabularies.isEmpty() || !addDefaultVocabulary) {
284                            return vocabularies;
285                    }
286    
287                    AssetVocabulary vocabulary = addDefaultVocabulary(groupId);
288    
289                    vocabularies = new ArrayList<>();
290    
291                    vocabularies.add(vocabulary);
292    
293                    return vocabularies;
294            }
295    
296            @Override
297            public List<AssetVocabulary> getGroupVocabularies(
298                    long groupId, String name, int start, int end,
299                    OrderByComparator<AssetVocabulary> obc) {
300    
301                    return assetVocabularyFinder.findByG_N(groupId, name, start, end, obc);
302            }
303    
304            @Override
305            public List<AssetVocabulary> getGroupVocabularies(long[] groupIds) {
306                    return assetVocabularyPersistence.findByGroupId(groupIds);
307            }
308    
309            @Override
310            public int getGroupVocabulariesCount(long[] groupIds) {
311                    return assetVocabularyPersistence.countByGroupId(groupIds);
312            }
313    
314            @Override
315            public AssetVocabulary getGroupVocabulary(long groupId, String name)
316                    throws PortalException {
317    
318                    return assetVocabularyPersistence.findByG_N(groupId, name);
319            }
320    
321            @Override
322            public List<AssetVocabulary> getVocabularies(Hits hits)
323                    throws PortalException {
324    
325                    List<Document> documents = hits.toList();
326    
327                    List<AssetVocabulary> vocabularies = new ArrayList<>(documents.size());
328    
329                    for (Document document : documents) {
330                            long vocabularyId = GetterUtil.getLong(
331                                    document.get(Field.ASSET_VOCABULARY_ID));
332    
333                            AssetVocabulary vocabulary = fetchAssetVocabulary(vocabularyId);
334    
335                            if (vocabulary == null) {
336                                    vocabularies = null;
337    
338                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
339                                            AssetVocabulary.class);
340    
341                                    long companyId = GetterUtil.getLong(
342                                            document.get(Field.COMPANY_ID));
343    
344                                    indexer.delete(companyId, document.getUID());
345                            }
346                            else if (vocabularies != null) {
347                                    vocabularies.add(vocabulary);
348                            }
349                    }
350    
351                    return vocabularies;
352            }
353    
354            @Override
355            public List<AssetVocabulary> getVocabularies(long[] vocabularyIds)
356                    throws PortalException {
357    
358                    List<AssetVocabulary> vocabularies = new ArrayList<>();
359    
360                    for (long vocabularyId : vocabularyIds) {
361                            AssetVocabulary vocabulary = getVocabulary(vocabularyId);
362    
363                            vocabularies.add(vocabulary);
364                    }
365    
366                    return vocabularies;
367            }
368    
369            @Override
370            public AssetVocabulary getVocabulary(long vocabularyId)
371                    throws PortalException {
372    
373                    return assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
374            }
375    
376            @Override
377            public BaseModelSearchResult<AssetVocabulary> searchVocabularies(
378                            long companyId, long groupId, String title, int start, int end)
379                    throws PortalException {
380    
381                    SearchContext searchContext = buildSearchContext(
382                            companyId, groupId, title, start, end);
383    
384                    return searchVocabularies(searchContext);
385            }
386    
387            @Indexable(type = IndexableType.REINDEX)
388            @Override
389            public AssetVocabulary updateVocabulary(
390                            long vocabularyId, String title, Map<Locale, String> titleMap,
391                            Map<Locale, String> descriptionMap, String settings,
392                            ServiceContext serviceContext)
393                    throws PortalException {
394    
395                    String name = titleMap.get(LocaleUtil.getSiteDefault());
396    
397                    AssetVocabulary vocabulary =
398                            assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
399    
400                    if (!vocabulary.getName().equals(name)) {
401                            validate(vocabulary.getGroupId(), name);
402                    }
403    
404                    vocabulary.setName(name);
405                    vocabulary.setTitleMap(titleMap);
406    
407                    if (Validator.isNotNull(title)) {
408                            vocabulary.setTitle(title);
409                    }
410    
411                    vocabulary.setDescriptionMap(descriptionMap);
412                    vocabulary.setSettings(settings);
413    
414                    assetVocabularyPersistence.update(vocabulary);
415    
416                    return vocabulary;
417            }
418    
419            protected SearchContext buildSearchContext(
420                    long companyId, long groupId, String title, int start, int end) {
421    
422                    SearchContext searchContext = new SearchContext();
423    
424                    searchContext.setAttribute(Field.TITLE, title);
425                    searchContext.setCompanyId(companyId);
426                    searchContext.setEnd(end);
427                    searchContext.setGroupIds(new long[] {groupId});
428                    searchContext.setKeywords(title);
429                    searchContext.setStart(start);
430    
431                    QueryConfig queryConfig = searchContext.getQueryConfig();
432    
433                    queryConfig.setHighlightEnabled(false);
434                    queryConfig.setScoreEnabled(false);
435    
436                    return searchContext;
437            }
438    
439            protected boolean hasVocabulary(long groupId, String name) {
440                    if (assetVocabularyPersistence.countByG_N(groupId, name) == 0) {
441                            return false;
442                    }
443                    else {
444                            return true;
445                    }
446            }
447    
448            protected BaseModelSearchResult<AssetVocabulary> searchVocabularies(
449                            SearchContext searchContext)
450                    throws PortalException {
451    
452                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
453                            AssetVocabulary.class);
454    
455                    for (int i = 0; i < 10; i++) {
456                            Hits hits = indexer.search(searchContext);
457    
458                            List<AssetVocabulary> vocabularies = getVocabularies(hits);
459    
460                            if (vocabularies != null) {
461                                    return new BaseModelSearchResult<>(
462                                            vocabularies, hits.getLength());
463                            }
464                    }
465    
466                    throw new SearchException(
467                            "Unable to fix the search index after 10 attempts");
468            }
469    
470            protected void validate(long groupId, String name) throws PortalException {
471                    if (Validator.isNull(name)) {
472                            throw new VocabularyNameException(
473                                    "Category vocabulary name cannot be null for group " + groupId);
474                    }
475    
476                    if (hasVocabulary(groupId, name)) {
477                            throw new DuplicateVocabularyException(
478                                    "A category vocabulary with the name " + name +
479                                            " already exists");
480                    }
481            }
482    
483    }