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