001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.asset.service.impl;
016    
017    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.CharPool;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.model.ResourceConstants;
029    import com.liferay.portal.model.User;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.util.PortalUtil;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.portlet.asset.AssetTagException;
034    import com.liferay.portlet.asset.DuplicateTagException;
035    import com.liferay.portlet.asset.NoSuchTagException;
036    import com.liferay.portlet.asset.model.AssetEntry;
037    import com.liferay.portlet.asset.model.AssetTag;
038    import com.liferay.portlet.asset.model.AssetTagProperty;
039    import com.liferay.portlet.asset.service.base.AssetTagLocalServiceBaseImpl;
040    import com.liferay.portlet.asset.util.AssetUtil;
041    import com.liferay.portlet.social.util.SocialCounterPeriodUtil;
042    
043    import java.util.ArrayList;
044    import java.util.Collections;
045    import java.util.Date;
046    import java.util.List;
047    
048    /**
049     * Provides the local service for accessing, adding, checking, deleting,
050     * merging, and updating asset tags.
051     *
052     * @author Brian Wing Shun Chan
053     * @author Alvaro del Castillo
054     * @author Jorge Ferrer
055     * @author Bruno Farache
056     */
057    public class AssetTagLocalServiceImpl extends AssetTagLocalServiceBaseImpl {
058    
059            @Override
060            public AssetTag addTag(
061                            long userId, String name, String[] tagProperties,
062                            ServiceContext serviceContext)
063                    throws PortalException, SystemException {
064    
065                    // Tag
066    
067                    User user = userPersistence.findByPrimaryKey(userId);
068                    long groupId = serviceContext.getScopeGroupId();
069    
070                    if (tagProperties == null) {
071                            tagProperties = new String[0];
072                    }
073    
074                    Date now = new Date();
075    
076                    long tagId = counterLocalService.increment();
077    
078                    AssetTag tag = assetTagPersistence.create(tagId);
079    
080                    tag.setGroupId(groupId);
081                    tag.setCompanyId(user.getCompanyId());
082                    tag.setUserId(user.getUserId());
083                    tag.setUserName(user.getFullName());
084                    tag.setCreateDate(now);
085                    tag.setModifiedDate(now);
086    
087                    name = name.trim();
088                    name = name.toLowerCase();
089    
090                    if (hasTag(groupId, name)) {
091                            throw new DuplicateTagException(
092                                    "A tag with the name " + name + " already exists");
093                    }
094    
095                    validate(name);
096    
097                    tag.setName(name);
098    
099                    assetTagPersistence.update(tag);
100    
101                    // Resources
102    
103                    if (serviceContext.isAddGroupPermissions() ||
104                            serviceContext.isAddGuestPermissions()) {
105    
106                            addTagResources(
107                                    tag, serviceContext.isAddGroupPermissions(),
108                                    serviceContext.isAddGuestPermissions());
109                    }
110                    else {
111                            addTagResources(
112                                    tag, serviceContext.getGroupPermissions(),
113                                    serviceContext.getGuestPermissions());
114                    }
115    
116                    // Properties
117    
118                    for (int i = 0; i < tagProperties.length; i++) {
119                            String[] tagProperty = StringUtil.split(
120                                    tagProperties[i], CharPool.COLON);
121    
122                            String key = StringPool.BLANK;
123    
124                            if (tagProperty.length > 0) {
125                                    key = GetterUtil.getString(tagProperty[0]);
126                            }
127    
128                            String value = StringPool.BLANK;
129    
130                            if (tagProperty.length > 1) {
131                                    value = GetterUtil.getString(tagProperty[1]);
132                            }
133    
134                            if (Validator.isNotNull(key)) {
135                                    assetTagPropertyLocalService.addTagProperty(
136                                            userId, tagId, key, value);
137                            }
138                    }
139    
140                    return tag;
141            }
142    
143            @Override
144            public void addTagResources(
145                            AssetTag tag, boolean addGroupPermissions,
146                            boolean addGuestPermissions)
147                    throws PortalException, SystemException {
148    
149                    resourceLocalService.addResources(
150                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
151                            AssetTag.class.getName(), tag.getTagId(), false,
152                            addGroupPermissions, addGuestPermissions);
153            }
154    
155            @Override
156            public void addTagResources(
157                            AssetTag tag, String[] groupPermissions, String[] guestPermissions)
158                    throws PortalException, SystemException {
159    
160                    resourceLocalService.addModelResources(
161                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
162                            AssetTag.class.getName(), tag.getTagId(), groupPermissions,
163                            guestPermissions);
164            }
165    
166            @Override
167            public void checkTags(long userId, long groupId, String[] names)
168                    throws PortalException, SystemException {
169    
170                    for (String name : names) {
171                            try {
172                                    getTag(groupId, name);
173                            }
174                            catch (NoSuchTagException nste) {
175                                    ServiceContext serviceContext = new ServiceContext();
176    
177                                    serviceContext.setAddGroupPermissions(true);
178                                    serviceContext.setAddGuestPermissions(true);
179                                    serviceContext.setScopeGroupId(groupId);
180    
181                                    addTag(
182                                            userId, name, PropsValues.ASSET_TAG_PROPERTIES_DEFAULT,
183                                            serviceContext);
184                            }
185                    }
186            }
187    
188            @Override
189            public AssetTag decrementAssetCount(long tagId, long classNameId)
190                    throws PortalException, SystemException {
191    
192                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
193    
194                    tag.setAssetCount(Math.max(0, tag.getAssetCount() - 1));
195    
196                    assetTagPersistence.update(tag);
197    
198                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
199    
200                    return tag;
201            }
202    
203            @Override
204            public void deleteGroupTags(long groupId)
205                    throws PortalException, SystemException {
206    
207                    List<AssetTag> tags = getGroupTags(groupId);
208    
209                    for (AssetTag tag : tags) {
210                            deleteTag(tag);
211                    }
212            }
213    
214            @Override
215            public void deleteTag(AssetTag tag)
216                    throws PortalException, SystemException {
217    
218                    // Entries
219    
220                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
221                            tag.getTagId());
222    
223                    // Tag
224    
225                    assetTagPersistence.remove(tag);
226    
227                    // Resources
228    
229                    resourceLocalService.deleteResource(
230                            tag.getCompanyId(), AssetTag.class.getName(),
231                            ResourceConstants.SCOPE_INDIVIDUAL, tag.getTagId());
232    
233                    // Properties
234    
235                    assetTagPropertyLocalService.deleteTagProperties(tag.getTagId());
236    
237                    // Indexer
238    
239                    assetEntryLocalService.reindex(entries);
240            }
241    
242            @Override
243            public void deleteTag(long tagId) throws PortalException, SystemException {
244                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
245    
246                    deleteTag(tag);
247            }
248    
249            @Override
250            public List<AssetTag> getEntryTags(long entryId) throws SystemException {
251                    return assetEntryPersistence.getAssetTags(entryId);
252            }
253    
254            @Override
255            public List<AssetTag> getGroupsTags(long[] groupIds)
256                    throws SystemException {
257    
258                    List<AssetTag> groupsTags = new ArrayList<AssetTag>();
259    
260                    for (long groupId : groupIds) {
261                            List<AssetTag> groupTags = getGroupTags(groupId);
262    
263                            groupsTags.addAll(groupTags);
264                    }
265    
266                    return groupsTags;
267            }
268    
269            @Override
270            public List<AssetTag> getGroupTags(long groupId) throws SystemException {
271                    return assetTagPersistence.findByGroupId(groupId);
272            }
273    
274            @Override
275            public List<AssetTag> getGroupTags(long groupId, int start, int end)
276                    throws SystemException {
277    
278                    return assetTagPersistence.findByGroupId(groupId, start, end);
279            }
280    
281            @Override
282            public int getGroupTagsCount(long groupId) throws SystemException {
283                    return assetTagPersistence.countByGroupId(groupId);
284            }
285    
286            @Override
287            public List<AssetTag> getSocialActivityCounterOffsetTags(
288                            long groupId, String socialActivityCounterName, int startOffset,
289                            int endOffset)
290                    throws SystemException {
291    
292                    int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
293                    int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
294    
295                    return getSocialActivityCounterPeriodTags(
296                            groupId, socialActivityCounterName, startPeriod, endPeriod);
297            }
298    
299            @Override
300            public List<AssetTag> getSocialActivityCounterPeriodTags(
301                            long groupId, String socialActivityCounterName, int startPeriod,
302                            int endPeriod)
303                    throws SystemException {
304    
305                    int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
306    
307                    int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
308    
309                    return assetTagFinder.findByG_N_S_E(
310                            groupId, socialActivityCounterName, startPeriod, endPeriod,
311                            periodLength);
312            }
313    
314            @Override
315            public AssetTag getTag(long tagId) throws PortalException, SystemException {
316                    return assetTagPersistence.findByPrimaryKey(tagId);
317            }
318    
319            @Override
320            public AssetTag getTag(long groupId, String name)
321                    throws PortalException, SystemException {
322    
323                    return assetTagFinder.findByG_N(groupId, name);
324            }
325    
326            @Override
327            public long[] getTagIds(long groupId, String[] names)
328                    throws PortalException, SystemException {
329    
330                    List<Long> tagIds = new ArrayList<Long>(names.length);
331    
332                    for (String name : names) {
333                            try {
334                                    AssetTag tag = getTag(groupId, name);
335    
336                                    tagIds.add(tag.getTagId());
337                            }
338                            catch (NoSuchTagException nste) {
339                            }
340                    }
341    
342                    return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
343            }
344    
345            @Override
346            public long[] getTagIds(long[] groupIds, String name)
347                    throws PortalException, SystemException {
348    
349                    List<Long> tagIds = new ArrayList<Long>(groupIds.length);
350    
351                    for (long groupId : groupIds) {
352                            try {
353                                    AssetTag tag = getTag(groupId, name);
354    
355                                    tagIds.add(tag.getTagId());
356                            }
357                            catch (NoSuchTagException nste) {
358                            }
359                    }
360    
361                    return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
362            }
363    
364            @Override
365            public long[] getTagIds(long[] groupIds, String[] names)
366                    throws PortalException, SystemException {
367    
368                    long[] tagsIds = new long[0];
369    
370                    for (long groupId : groupIds) {
371                            tagsIds = ArrayUtil.append(tagsIds, getTagIds(groupId, names));
372                    }
373    
374                    return tagsIds;
375            }
376    
377            @Override
378            public String[] getTagNames() throws SystemException {
379                    return getTagNames(getTags());
380            }
381    
382            @Override
383            public String[] getTagNames(long classNameId, long classPK)
384                    throws SystemException {
385    
386                    return getTagNames(getTags(classNameId, classPK));
387            }
388    
389            @Override
390            public String[] getTagNames(String className, long classPK)
391                    throws SystemException {
392    
393                    return getTagNames(getTags(className, classPK));
394            }
395    
396            @Override
397            public List<AssetTag> getTags() throws SystemException {
398                    return assetTagPersistence.findAll();
399            }
400    
401            @Override
402            public List<AssetTag> getTags(long classNameId, long classPK)
403                    throws SystemException {
404    
405                    AssetEntry entry = assetEntryPersistence.fetchByC_C(
406                            classNameId, classPK);
407    
408                    if (entry == null) {
409                            return Collections.emptyList();
410                    }
411    
412                    return assetEntryPersistence.getAssetTags(entry.getEntryId());
413            }
414    
415            @Override
416            public List<AssetTag> getTags(long groupId, long classNameId, String name)
417                    throws SystemException {
418    
419                    return assetTagFinder.findByG_C_N(
420                            groupId, classNameId, name, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
421                            null);
422            }
423    
424            @Override
425            public List<AssetTag> getTags(
426                            long groupId, long classNameId, String name, int start, int end)
427                    throws SystemException {
428    
429                    return assetTagFinder.findByG_C_N(
430                            groupId, classNameId, name, start, end, null);
431            }
432    
433            @Override
434            @ThreadLocalCachable
435            public List<AssetTag> getTags(String className, long classPK)
436                    throws SystemException {
437    
438                    long classNameId = PortalUtil.getClassNameId(className);
439    
440                    return getTags(classNameId, classPK);
441            }
442    
443            @Override
444            public int getTagsSize(long groupId, long classNameId, String name)
445                    throws SystemException {
446    
447                    return assetTagFinder.countByG_C_N(groupId, classNameId, name);
448            }
449    
450            @Override
451            public boolean hasTag(long groupId, String name)
452                    throws PortalException, SystemException {
453    
454                    try {
455                            getTag(groupId, name);
456    
457                            return true;
458                    }
459                    catch (NoSuchTagException nste) {
460                            return false;
461                    }
462            }
463    
464            @Override
465            public AssetTag incrementAssetCount(long tagId, long classNameId)
466                    throws PortalException, SystemException {
467    
468                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
469    
470                    tag.setAssetCount(tag.getAssetCount() + 1);
471    
472                    assetTagPersistence.update(tag);
473    
474                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
475    
476                    return tag;
477            }
478    
479            @Override
480            public void mergeTags(
481                            long fromTagId, long toTagId, boolean overrideProperties)
482                    throws PortalException, SystemException {
483    
484                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
485                            fromTagId);
486    
487                    assetTagPersistence.addAssetEntries(toTagId, entries);
488    
489                    List<AssetTagProperty> tagProperties =
490                            assetTagPropertyPersistence.findByTagId(fromTagId);
491    
492                    for (AssetTagProperty fromTagProperty : tagProperties) {
493                            AssetTagProperty toTagProperty =
494                                    assetTagPropertyPersistence.fetchByT_K(
495                                            toTagId, fromTagProperty.getKey());
496    
497                            if (overrideProperties && (toTagProperty != null)) {
498                                    toTagProperty.setValue(fromTagProperty.getValue());
499    
500                                    assetTagPropertyPersistence.update(toTagProperty);
501                            }
502                            else if (toTagProperty == null) {
503                                    fromTagProperty.setTagId(toTagId);
504    
505                                    assetTagPropertyPersistence.update(fromTagProperty);
506                            }
507                    }
508    
509                    deleteTag(fromTagId);
510            }
511    
512            @Override
513            public List<AssetTag> search(
514                            long groupId, String name, String[] tagProperties, int start,
515                            int end)
516                    throws SystemException {
517    
518                    return search(new long[] {groupId}, name, tagProperties, start, end);
519            }
520    
521            @Override
522            public List<AssetTag> search(
523                            long[] groupIds, String name, String[] tagProperties, int start,
524                            int end)
525                    throws SystemException {
526    
527                    return assetTagFinder.findByG_N_P(
528                            groupIds, name, tagProperties, start, end, null);
529            }
530    
531            @Override
532            public AssetTag updateTag(
533                            long userId, long tagId, String name, String[] tagProperties,
534                            ServiceContext serviceContext)
535                    throws PortalException, SystemException {
536    
537                    // Tag
538    
539                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
540    
541                    String oldName = tag.getName();
542    
543                    tag.setModifiedDate(new Date());
544    
545                    name = name.trim();
546                    name = name.toLowerCase();
547    
548                    if (tagProperties == null) {
549                            tagProperties = new String[0];
550                    }
551    
552                    if (!name.equals(tag.getName()) && hasTag(tag.getGroupId(), name)) {
553                            throw new DuplicateTagException(
554                                    "A tag with the name " + name + " already exists");
555                    }
556    
557                    if (!tag.getName().equals(name)) {
558                            try {
559                                    AssetTag existingAssetTag = getTag(tag.getGroupId(), name);
560    
561                                    if (existingAssetTag.getTagId() != tagId) {
562                                            throw new DuplicateTagException(
563                                                    "A tag with the name " + name + " already exists");
564                                    }
565                            }
566                            catch (NoSuchTagException nste) {
567                            }
568                    }
569    
570                    validate(name);
571    
572                    tag.setName(name);
573    
574                    assetTagPersistence.update(tag);
575    
576                    // Properties
577    
578                    List<AssetTagProperty> oldTagProperties =
579                            assetTagPropertyPersistence.findByTagId(tagId);
580    
581                    for (AssetTagProperty tagProperty : oldTagProperties) {
582                            assetTagPropertyLocalService.deleteTagProperty(tagProperty);
583                    }
584    
585                    for (int i = 0; i < tagProperties.length; i++) {
586                            String[] tagProperty = StringUtil.split(
587                                    tagProperties[i], CharPool.COLON);
588    
589                            String key = StringPool.BLANK;
590    
591                            if (tagProperty.length > 0) {
592                                    key = GetterUtil.getString(tagProperty[0]);
593                            }
594    
595                            String value = StringPool.BLANK;
596    
597                            if (tagProperty.length > 1) {
598                                    value = GetterUtil.getString(tagProperty[1]);
599                            }
600    
601                            if (Validator.isNotNull(key)) {
602                                    assetTagPropertyLocalService.addTagProperty(
603                                            userId, tagId, key, value);
604                            }
605                    }
606    
607                    // Indexer
608    
609                    if (!oldName.equals(name)) {
610                            List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
611                                    tag.getTagId());
612    
613                            assetEntryLocalService.reindex(entries);
614                    }
615    
616                    return tag;
617            }
618    
619            protected String[] getTagNames(List<AssetTag>tags) {
620                    return StringUtil.split(
621                            ListUtil.toString(tags, AssetTag.NAME_ACCESSOR));
622            }
623    
624            protected void validate(String name) throws PortalException {
625                    if (!AssetUtil.isValidWord(name)) {
626                            throw new AssetTagException(
627                                    StringUtil.merge(
628                                            AssetUtil.INVALID_CHARACTERS, StringPool.SPACE),
629                                    AssetTagException.INVALID_CHARACTER);
630                    }
631            }
632    
633    }