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