001    /**
002     * Copyright (c) 2000-2012 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.ThreadLocalCachable;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.ListUtil;
024    import com.liferay.portal.kernel.util.LocaleUtil;
025    import com.liferay.portal.kernel.util.OrderByComparator;
026    import com.liferay.portal.kernel.util.StringBundler;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.model.ModelHintsUtil;
031    import com.liferay.portal.model.ResourceConstants;
032    import com.liferay.portal.model.User;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.asset.AssetCategoryNameException;
036    import com.liferay.portlet.asset.DuplicateCategoryException;
037    import com.liferay.portlet.asset.model.AssetCategory;
038    import com.liferay.portlet.asset.model.AssetCategoryConstants;
039    import com.liferay.portlet.asset.model.AssetCategoryProperty;
040    import com.liferay.portlet.asset.model.AssetEntry;
041    import com.liferay.portlet.asset.service.base.AssetCategoryLocalServiceBaseImpl;
042    
043    import java.util.Date;
044    import java.util.Iterator;
045    import java.util.List;
046    import java.util.Locale;
047    import java.util.Map;
048    import java.util.concurrent.Callable;
049    
050    /**
051     * @author Brian Wing Shun Chan
052     * @author Alvaro del Castillo
053     * @author Jorge Ferrer
054     * @author Bruno Farache
055     */
056    public class AssetCategoryLocalServiceImpl
057            extends AssetCategoryLocalServiceBaseImpl {
058    
059            public AssetCategory addCategory(
060                            long userId, long parentCategoryId, Map<Locale, String> titleMap,
061                            Map<Locale, String> descriptionMap, long vocabularyId,
062                            String[] categoryProperties, ServiceContext serviceContext)
063                    throws PortalException, SystemException {
064    
065                    // Category
066    
067                    User user = userPersistence.findByPrimaryKey(userId);
068                    long groupId = serviceContext.getScopeGroupId();
069    
070                    String name = titleMap.get(LocaleUtil.getDefault());
071    
072                    name = ModelHintsUtil.trimString(
073                            AssetCategory.class.getName(), "name", name);
074    
075                    if (categoryProperties == null) {
076                            categoryProperties = new String[0];
077                    }
078    
079                    Date now = new Date();
080    
081                    validate(0, parentCategoryId, name, vocabularyId);
082    
083                    if (parentCategoryId > 0) {
084                            assetCategoryPersistence.findByPrimaryKey(parentCategoryId);
085                    }
086    
087                    assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
088    
089                    long categoryId = counterLocalService.increment();
090    
091                    AssetCategory category = assetCategoryPersistence.create(categoryId);
092    
093                    category.setUuid(serviceContext.getUuid());
094                    category.setGroupId(groupId);
095                    category.setCompanyId(user.getCompanyId());
096                    category.setUserId(user.getUserId());
097                    category.setUserName(user.getFullName());
098                    category.setCreateDate(now);
099                    category.setModifiedDate(now);
100                    category.setParentCategoryId(parentCategoryId);
101                    category.setName(name);
102                    category.setTitleMap(titleMap);
103                    category.setDescriptionMap(descriptionMap);
104                    category.setVocabularyId(vocabularyId);
105    
106                    assetCategoryPersistence.update(category);
107    
108                    // Resources
109    
110                    if (serviceContext.isAddGroupPermissions() ||
111                            serviceContext.isAddGuestPermissions()) {
112    
113                            addCategoryResources(
114                                    category, serviceContext.isAddGroupPermissions(),
115                                    serviceContext.isAddGuestPermissions());
116                    }
117                    else {
118                            addCategoryResources(
119                                    category, serviceContext.getGroupPermissions(),
120                                    serviceContext.getGuestPermissions());
121                    }
122    
123                    // Properties
124    
125                    for (int i = 0; i < categoryProperties.length; i++) {
126                            String[] categoryProperty = StringUtil.split(
127                                    categoryProperties[i], CharPool.COLON);
128    
129                            String key = StringPool.BLANK;
130                            String value = StringPool.BLANK;
131    
132                            if (categoryProperty.length > 1) {
133                                    key = GetterUtil.getString(categoryProperty[0]);
134                                    value = GetterUtil.getString(categoryProperty[1]);
135                            }
136    
137                            if (Validator.isNotNull(key)) {
138                                    assetCategoryPropertyLocalService.addCategoryProperty(
139                                            userId, categoryId, key, value);
140                            }
141                    }
142    
143                    return category;
144            }
145    
146            public void addCategoryResources(
147                            AssetCategory category, boolean addGroupPermissions,
148                            boolean addGuestPermissions)
149                    throws PortalException, SystemException {
150    
151                    resourceLocalService.addResources(
152                            category.getCompanyId(), category.getGroupId(),
153                            category.getUserId(), AssetCategory.class.getName(),
154                            category.getCategoryId(), false, addGroupPermissions,
155                            addGuestPermissions);
156            }
157    
158            public void addCategoryResources(
159                            AssetCategory category, String[] groupPermissions,
160                            String[] guestPermissions)
161                    throws PortalException, SystemException {
162    
163                    resourceLocalService.addModelResources(
164                            category.getCompanyId(), category.getGroupId(),
165                            category.getUserId(), AssetCategory.class.getName(),
166                            category.getCategoryId(), groupPermissions, guestPermissions);
167            }
168    
169            public void deleteCategory(AssetCategory category)
170                    throws PortalException, SystemException {
171    
172                    deleteCategory(category, false);
173            }
174    
175            public void deleteCategory(long categoryId)
176                    throws PortalException, SystemException {
177    
178                    AssetCategory category = assetCategoryPersistence.findByPrimaryKey(
179                            categoryId);
180    
181                    deleteCategory(category);
182            }
183    
184            public void deleteVocabularyCategories(long vocabularyId)
185                    throws PortalException, SystemException {
186    
187                    List<AssetCategory> categories =
188                            assetCategoryPersistence.findByVocabularyId(vocabularyId);
189    
190                    for (AssetCategory category : categories) {
191                            if (category.getParentCategoryId() ==
192                                            AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
193    
194                                    deleteCategory(category.getCategoryId());
195                            }
196                    }
197            }
198    
199            public AssetCategory fetchCategory(long categoryId) throws SystemException {
200                    return assetCategoryPersistence.fetchByPrimaryKey(categoryId);
201            }
202    
203            public List<AssetCategory> getCategories() throws SystemException {
204                    return assetCategoryPersistence.findAll();
205            }
206    
207            @ThreadLocalCachable
208            public List<AssetCategory> getCategories(long classNameId, long classPK)
209                    throws SystemException {
210    
211                    return assetCategoryFinder.findByC_C(classNameId, classPK);
212            }
213    
214            public List<AssetCategory> getCategories(String className, long classPK)
215                    throws SystemException {
216    
217                    long classNameId = PortalUtil.getClassNameId(className);
218    
219                    return getCategories(classNameId, classPK);
220            }
221    
222            public AssetCategory getCategory(long categoryId)
223                    throws PortalException, SystemException {
224    
225                    return assetCategoryPersistence.findByPrimaryKey(categoryId);
226            }
227    
228            public AssetCategory getCategory(String uuid, long groupId)
229                    throws PortalException, SystemException {
230    
231                    return assetCategoryPersistence.findByUUID_G(uuid, groupId);
232            }
233    
234            public long[] getCategoryIds(String className, long classPK)
235                    throws SystemException {
236    
237                    return getCategoryIds(getCategories(className, classPK));
238            }
239    
240            public String[] getCategoryNames() throws SystemException {
241                    return getCategoryNames(getCategories());
242            }
243    
244            public String[] getCategoryNames(long classNameId, long classPK)
245                    throws SystemException {
246    
247                    return getCategoryNames(getCategories(classNameId, classPK));
248            }
249    
250            public String[] getCategoryNames(String className, long classPK)
251                    throws SystemException {
252    
253                    return getCategoryNames(getCategories(className, classPK));
254            }
255    
256            public List<AssetCategory> getChildCategories(long parentCategoryId)
257                    throws SystemException {
258    
259                    return assetCategoryPersistence.findByParentCategoryId(
260                            parentCategoryId);
261            }
262    
263            public List<AssetCategory> getChildCategories(
264                            long parentCategoryId, int start, int end, OrderByComparator obc)
265                    throws SystemException {
266    
267                    return assetCategoryPersistence.findByParentCategoryId(
268                            parentCategoryId, start, end, obc);
269            }
270    
271            public int getChildCategoriesCount(long parentCategoryId)
272                    throws SystemException {
273    
274                    return assetCategoryPersistence.countByParentCategoryId(
275                            parentCategoryId);
276            }
277    
278            public List<AssetCategory> getEntryCategories(long entryId)
279                    throws SystemException {
280    
281                    return assetCategoryFinder.findByEntryId(entryId);
282            }
283    
284            public List<AssetCategory> getVocabularyCategories(
285                            long vocabularyId, int start, int end, OrderByComparator obc)
286                    throws SystemException {
287    
288                    return assetCategoryPersistence.findByVocabularyId(
289                            vocabularyId, start, end, obc);
290            }
291    
292            public List<AssetCategory> getVocabularyCategories(
293                            long parentCategoryId, long vocabularyId, int start, int end,
294                            OrderByComparator obc)
295                    throws SystemException {
296    
297                    return assetCategoryPersistence.findByP_V(
298                            parentCategoryId, vocabularyId, start, end, obc);
299            }
300    
301            public int getVocabularyCategoriesCount(long vocabularyId)
302                    throws SystemException {
303    
304                    return assetCategoryPersistence.countByVocabularyId(vocabularyId);
305            }
306    
307            public List<AssetCategory> getVocabularyRootCategories(
308                            long vocabularyId, int start, int end, OrderByComparator obc)
309                    throws SystemException {
310    
311                    return getVocabularyCategories(
312                            AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID, vocabularyId,
313                            start, end, obc);
314            }
315    
316            public void mergeCategories(long fromCategoryId, long toCategoryId)
317                    throws PortalException, SystemException {
318    
319                    List<AssetEntry> entries = assetCategoryPersistence.getAssetEntries(
320                            fromCategoryId);
321    
322                    assetCategoryPersistence.addAssetEntries(toCategoryId, entries);
323    
324                    List<AssetCategoryProperty> categoryProperties =
325                            assetCategoryPropertyPersistence.findByCategoryId(fromCategoryId);
326    
327                    for (AssetCategoryProperty fromCategoryProperty : categoryProperties) {
328                            AssetCategoryProperty toCategoryProperty =
329                                    assetCategoryPropertyPersistence.fetchByCA_K(
330                                            toCategoryId, fromCategoryProperty.getKey());
331    
332                            if (toCategoryProperty == null) {
333                                    fromCategoryProperty.setCategoryId(toCategoryId);
334    
335                                    assetCategoryPropertyPersistence.update(fromCategoryProperty);
336                            }
337                    }
338    
339                    deleteCategory(fromCategoryId);
340            }
341    
342            public AssetCategory moveCategory(
343                            long categoryId, long parentCategoryId, long vocabularyId,
344                            ServiceContext serviceContext)
345                    throws PortalException, SystemException {
346    
347                    AssetCategory category = assetCategoryPersistence.findByPrimaryKey(
348                            categoryId);
349    
350                    validate(
351                            categoryId, parentCategoryId, category.getName(), vocabularyId);
352    
353                    if (parentCategoryId > 0) {
354                            assetCategoryPersistence.findByPrimaryKey(parentCategoryId);
355                    }
356    
357                    if (vocabularyId != category.getVocabularyId()) {
358                            assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
359    
360                            category.setVocabularyId(vocabularyId);
361    
362                            updateChildrenVocabularyId(category, vocabularyId);
363                    }
364    
365                    category.setModifiedDate(new Date());
366                    category.setParentCategoryId(parentCategoryId);
367    
368                    assetCategoryPersistence.update(category);
369    
370                    return category;
371            }
372    
373            public void rebuildTree(long groupId, boolean force)
374                    throws SystemException {
375    
376                    assetCategoryPersistence.rebuildTree(groupId, force);
377            }
378    
379            public List<AssetCategory> search(
380                            long groupId, String name, String[] categoryProperties, int start,
381                            int end)
382                    throws SystemException {
383    
384                    return assetCategoryFinder.findByG_N_P(
385                            groupId, name, categoryProperties, start, end);
386            }
387    
388            public AssetCategory updateCategory(
389                            long userId, long categoryId, long parentCategoryId,
390                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
391                            long vocabularyId, String[] categoryProperties,
392                            ServiceContext serviceContext)
393                    throws PortalException, SystemException {
394    
395                    // Category
396    
397                    String name = titleMap.get(LocaleUtil.getDefault());
398    
399                    name = ModelHintsUtil.trimString(
400                            AssetCategory.class.getName(), "name", name);
401    
402                    if (categoryProperties == null) {
403                            categoryProperties = new String[0];
404                    }
405    
406                    validate(categoryId, parentCategoryId, name, vocabularyId);
407    
408                    if (parentCategoryId > 0) {
409                            assetCategoryPersistence.findByPrimaryKey(parentCategoryId);
410                    }
411    
412                    AssetCategory category = assetCategoryPersistence.findByPrimaryKey(
413                            categoryId);
414    
415                    String oldName = category.getName();
416    
417                    if (vocabularyId != category.getVocabularyId()) {
418                            assetVocabularyPersistence.findByPrimaryKey(vocabularyId);
419    
420                            parentCategoryId =
421                                    AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
422    
423                            category.setVocabularyId(vocabularyId);
424    
425                            updateChildrenVocabularyId(category, vocabularyId);
426                    }
427    
428                    category.setModifiedDate(new Date());
429                    category.setParentCategoryId(parentCategoryId);
430                    category.setName(name);
431                    category.setTitleMap(titleMap);
432                    category.setDescriptionMap(descriptionMap);
433    
434                    assetCategoryPersistence.update(category);
435    
436                    // Properties
437    
438                    List<AssetCategoryProperty> oldCategoryProperties =
439                            assetCategoryPropertyPersistence.findByCategoryId(categoryId);
440    
441                    for (int i = 0; i < categoryProperties.length; i++) {
442                            String[] categoryProperty = StringUtil.split(
443                                    categoryProperties[i], CharPool.COLON);
444    
445                            String key = StringPool.BLANK;
446    
447                            if (categoryProperty.length > 0) {
448                                    key = GetterUtil.getString(categoryProperty[0]);
449                            }
450    
451                            String value = StringPool.BLANK;
452    
453                            if (categoryProperty.length > 1) {
454                                    value = GetterUtil.getString(categoryProperty[1]);
455                            }
456    
457                            if (Validator.isNotNull(key)) {
458                                    boolean addCategoryProperty = true;
459    
460                                    Iterator<AssetCategoryProperty> iterator =
461                                            oldCategoryProperties.iterator();
462    
463                                    while (iterator.hasNext()) {
464                                            AssetCategoryProperty oldCategoryProperty = iterator.next();
465    
466                                            if ((userId == oldCategoryProperty.getUserId()) &&
467                                                    (categoryId == oldCategoryProperty.getCategoryId()) &&
468                                                    key.equals(oldCategoryProperty.getKey()) &&
469                                                    value.equals(oldCategoryProperty.getValue())) {
470    
471                                                    addCategoryProperty = false;
472    
473                                                    iterator.remove();
474    
475                                                    break;
476                                            }
477                                    }
478    
479                                    if (addCategoryProperty) {
480                                            assetCategoryPropertyLocalService.addCategoryProperty(
481                                                    userId, categoryId, key, value);
482                                    }
483                            }
484                    }
485    
486                    for (AssetCategoryProperty categoryProperty : oldCategoryProperties) {
487                            assetCategoryPropertyLocalService.deleteAssetCategoryProperty(
488                                    categoryProperty);
489                    }
490    
491                    // Indexer
492    
493                    if (!oldName.equals(name)) {
494                            List<AssetEntry> entries = assetCategoryPersistence.getAssetEntries(
495                                    category.getCategoryId());
496    
497                            assetEntryLocalService.reindex(entries);
498                    }
499    
500                    return category;
501            }
502    
503            protected void deleteCategory(AssetCategory category, boolean childCategory)
504                    throws PortalException, SystemException {
505    
506                    // Categories
507    
508                    List<AssetCategory> categories =
509                            assetCategoryPersistence.findByParentCategoryId(
510                                    category.getCategoryId());
511    
512                    for (AssetCategory curCategory : categories) {
513                            deleteCategory(curCategory, true);
514                    }
515    
516                    if (!categories.isEmpty() && !childCategory) {
517                            final long groupId = category.getGroupId();
518    
519                            TransactionCommitCallbackRegistryUtil.registerCallback(
520                                    new Callable<Void>() {
521    
522                                            public Void call() throws Exception {
523                                                    assetCategoryLocalService.rebuildTree(groupId, true);
524    
525                                                    return null;
526                                            }
527    
528                                    });
529                    }
530    
531                    // Category
532    
533                    assetCategoryPersistence.remove(category);
534    
535                    // Resources
536    
537                    resourceLocalService.deleteResource(
538                            category.getCompanyId(), AssetCategory.class.getName(),
539                            ResourceConstants.SCOPE_INDIVIDUAL, category.getCategoryId());
540    
541                    // Entries
542    
543                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
544                            category.getCategoryId());
545    
546                    // Properties
547    
548                    assetCategoryPropertyLocalService.deleteCategoryProperties(
549                            category.getCategoryId());
550    
551                    // Indexer
552    
553                    assetEntryLocalService.reindex(entries);
554            }
555    
556            protected long[] getCategoryIds(List<AssetCategory> categories) {
557                    return StringUtil.split(
558                            ListUtil.toString(categories, AssetCategory.CATEGORY_ID_ACCESSOR),
559                            0L);
560            }
561    
562            protected String[] getCategoryNames(List<AssetCategory> categories) {
563                    return StringUtil.split(
564                            ListUtil.toString(categories, AssetCategory.NAME_ACCESSOR));
565            }
566    
567            protected void updateChildrenVocabularyId(
568                            AssetCategory category, long vocabularyId)
569                    throws SystemException {
570    
571                    List<AssetCategory> childrenCategories =
572                            assetCategoryPersistence.findByParentCategoryId(
573                                    category.getCategoryId());
574    
575                    if (!childrenCategories.isEmpty()) {
576                            for (AssetCategory childCategory : childrenCategories) {
577                                    childCategory.setVocabularyId(vocabularyId);
578                                    childCategory.setModifiedDate(new Date());
579    
580                                    assetCategoryPersistence.update(childCategory);
581    
582                                    updateChildrenVocabularyId (childCategory, vocabularyId);
583                            }
584                    }
585            }
586    
587            protected void validate(
588                            long categoryId, long parentCategoryId, String name,
589                            long vocabularyId)
590                    throws PortalException, SystemException {
591    
592                    if (Validator.isNull(name)) {
593                            throw new AssetCategoryNameException();
594                    }
595    
596                    AssetCategory category = assetCategoryPersistence.fetchByP_N_V(
597                            parentCategoryId, name, vocabularyId);
598    
599                    if ((category != null) && (category.getCategoryId() != categoryId)) {
600                            StringBundler sb = new StringBundler(4);
601    
602                            sb.append("There is another category named ");
603                            sb.append(name);
604                            sb.append(" as a child of category ");
605                            sb.append(parentCategoryId);
606    
607                            throw new DuplicateCategoryException(sb.toString());
608                    }
609            }
610    
611    }