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.Group;
029    import com.liferay.portal.model.ResourceConstants;
030    import com.liferay.portal.model.User;
031    import com.liferay.portal.service.ServiceContext;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.PropsValues;
034    import com.liferay.portlet.asset.AssetTagException;
035    import com.liferay.portlet.asset.DuplicateTagException;
036    import com.liferay.portlet.asset.NoSuchTagException;
037    import com.liferay.portlet.asset.model.AssetEntry;
038    import com.liferay.portlet.asset.model.AssetTag;
039    import com.liferay.portlet.asset.model.AssetTagConstants;
040    import com.liferay.portlet.asset.model.AssetTagProperty;
041    import com.liferay.portlet.asset.service.base.AssetTagLocalServiceBaseImpl;
042    import com.liferay.portlet.asset.util.AssetUtil;
043    import com.liferay.portlet.social.util.SocialCounterPeriodUtil;
044    
045    import java.util.ArrayList;
046    import java.util.Collections;
047    import java.util.Date;
048    import java.util.HashSet;
049    import java.util.List;
050    import java.util.Set;
051    
052    /**
053     * Provides the local service for accessing, adding, checking, deleting,
054     * merging, and updating asset tags.
055     *
056     * @author Brian Wing Shun Chan
057     * @author Alvaro del Castillo
058     * @author Jorge Ferrer
059     * @author Bruno Farache
060     */
061    public class AssetTagLocalServiceImpl extends AssetTagLocalServiceBaseImpl {
062    
063            /**
064             * Adds an asset tag.
065             *
066             * @param  userId the primary key of the user adding the asset tag
067             * @param  name the asset tag's name
068             * @param  tagProperties the tag's properties
069             * @param  serviceContext the service context
070             * @return the asset tag that was added
071             * @throws PortalException if a user with the primary key could not be
072             *         found, if an asset tag already exists with the name, or if a
073             *         portal exception occurred
074             * @throws SystemException if a system exception occurred
075             */
076            @Override
077            public AssetTag addTag(
078                            long userId, String name, String[] tagProperties,
079                            ServiceContext serviceContext)
080                    throws PortalException, SystemException {
081    
082                    // Tag
083    
084                    User user = userPersistence.findByPrimaryKey(userId);
085                    long groupId = serviceContext.getScopeGroupId();
086    
087                    if (tagProperties == null) {
088                            tagProperties = new String[0];
089                    }
090    
091                    Date now = new Date();
092    
093                    long tagId = counterLocalService.increment();
094    
095                    AssetTag tag = assetTagPersistence.create(tagId);
096    
097                    tag.setGroupId(groupId);
098                    tag.setCompanyId(user.getCompanyId());
099                    tag.setUserId(user.getUserId());
100                    tag.setUserName(user.getFullName());
101                    tag.setCreateDate(now);
102                    tag.setModifiedDate(now);
103    
104                    name = name.trim();
105                    name = StringUtil.toLowerCase(name);
106    
107                    if (hasTag(groupId, name)) {
108                            throw new DuplicateTagException(
109                                    "A tag with the name " + name + " already exists");
110                    }
111    
112                    validate(name);
113    
114                    tag.setName(name);
115    
116                    assetTagPersistence.update(tag);
117    
118                    // Resources
119    
120                    if (serviceContext.isAddGroupPermissions() ||
121                            serviceContext.isAddGuestPermissions()) {
122    
123                            addTagResources(
124                                    tag, serviceContext.isAddGroupPermissions(),
125                                    serviceContext.isAddGuestPermissions());
126                    }
127                    else {
128                            addTagResources(
129                                    tag, serviceContext.getGroupPermissions(),
130                                    serviceContext.getGuestPermissions());
131                    }
132    
133                    // Properties
134    
135                    for (int i = 0; i < tagProperties.length; i++) {
136                            String[] tagProperty = StringUtil.split(
137                                    tagProperties[i],
138                                    AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR);
139    
140                            if (tagProperty.length <= 1) {
141                                    tagProperty = StringUtil.split(
142                                            tagProperties[i], CharPool.COLON);
143                            }
144    
145                            String key = StringPool.BLANK;
146    
147                            if (tagProperty.length > 0) {
148                                    key = GetterUtil.getString(tagProperty[0]);
149                            }
150    
151                            String value = StringPool.BLANK;
152    
153                            if (tagProperty.length > 1) {
154                                    value = GetterUtil.getString(tagProperty[1]);
155                            }
156    
157                            if (Validator.isNotNull(key)) {
158                                    assetTagPropertyLocalService.addTagProperty(
159                                            userId, tagId, key, value);
160                            }
161                    }
162    
163                    return tag;
164            }
165    
166            /**
167             * Adds resources for the asset tag.
168             *
169             * @param  tag the asset tag for which to add resources
170             * @param  addGroupPermissions whether to add group permissions
171             * @param  addGuestPermissions whether to add guest permissions
172             * @throws PortalException if resources could not be added for the asset tag
173             *         or if a portal exception occurred
174             * @throws SystemException if a system exception occurred
175             */
176            @Override
177            public void addTagResources(
178                            AssetTag tag, boolean addGroupPermissions,
179                            boolean addGuestPermissions)
180                    throws PortalException, SystemException {
181    
182                    resourceLocalService.addResources(
183                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
184                            AssetTag.class.getName(), tag.getTagId(), false,
185                            addGroupPermissions, addGuestPermissions);
186            }
187    
188            /**
189             * Adds resources for the asset tag using the group and guest permissions.
190             *
191             * @param  tag the asset tag for which to add resources
192             * @param  groupPermissions the group permissions to be applied
193             * @param  guestPermissions the guest permissions to be applied
194             * @throws PortalException if resources could not be added for the asset tag
195             *         or if a portal exception occurred
196             * @throws SystemException if a system exception occurred
197             */
198            @Override
199            public void addTagResources(
200                            AssetTag tag, String[] groupPermissions, String[] guestPermissions)
201                    throws PortalException, SystemException {
202    
203                    resourceLocalService.addModelResources(
204                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
205                            AssetTag.class.getName(), tag.getTagId(), groupPermissions,
206                            guestPermissions);
207            }
208    
209            /**
210             * Returns the asset tags matching the group and names, creating new asset
211             * tags matching the names if the group doesn't already have them.
212             *
213             * <p>
214             * For each name, if an asset tag with the name doesn't already exist in the
215             * group, this method creates a new asset tag with the name in the group.
216             * </p>
217             *
218             * @param  userId the primary key of the user checking the asset tags
219             * @param  group the group in which to check the asset tags
220             * @param  names the asset tag names
221             * @return the asset tags matching the group and names and new asset tags
222             *         matching the names that don't already exist in the group
223             * @throws PortalException if a matching group could not be found or if a
224             *         portal exception occurred
225             * @throws SystemException if a system exception occurred
226             */
227            @Override
228            public List<AssetTag> checkTags(long userId, Group group, String[] names)
229                    throws PortalException, SystemException {
230    
231                    List<AssetTag> tags = new ArrayList<AssetTag>();
232    
233                    for (String name : names) {
234                            AssetTag tag = null;
235    
236                            try {
237                                    tag = getTag(group.getGroupId(), name);
238                            }
239                            catch (NoSuchTagException nste1) {
240                                    ServiceContext serviceContext = new ServiceContext();
241    
242                                    serviceContext.setAddGroupPermissions(true);
243                                    serviceContext.setAddGuestPermissions(true);
244                                    serviceContext.setScopeGroupId(group.getGroupId());
245    
246                                    tag = addTag(
247                                            userId, name, PropsValues.ASSET_TAG_PROPERTIES_DEFAULT,
248                                            serviceContext);
249    
250                                    Group companyGroup = groupLocalService.getCompanyGroup(
251                                            group.getCompanyId());
252    
253                                    try {
254                                            AssetTag companyGroupTag = getTag(
255                                                    companyGroup.getGroupId(), name);
256    
257                                            List<AssetTagProperty> tagProperties =
258                                                    assetTagPropertyLocalService.getTagProperties(
259                                                            companyGroupTag.getTagId());
260    
261                                            for (AssetTagProperty tagProperty : tagProperties) {
262                                                    assetTagPropertyLocalService.addTagProperty(
263                                                            userId, tag.getTagId(), tagProperty.getKey(),
264                                                            tagProperty.getValue());
265                                            }
266                                    }
267                                    catch (NoSuchTagException nste2) {
268                                    }
269                            }
270    
271                            if (tag != null) {
272                                    tags.add(tag);
273                            }
274                    }
275    
276                    return tags;
277            }
278    
279            /**
280             * Returns the asset tags matching the group and names, creating new asset
281             * tags matching the names if the group doesn't already have them.
282             *
283             * @param  userId the primary key of the user checking the asset tags
284             * @param  groupId the primary key of the group in which check the asset
285             *         tags
286             * @param  names the asset tag names
287             * @throws PortalException if a matching group could not be found or if a
288             *         portal exception occurred
289             * @throws SystemException if a system exception occurred
290             */
291            @Override
292            public void checkTags(long userId, long groupId, String[] names)
293                    throws PortalException, SystemException {
294    
295                    Group group = groupPersistence.findByPrimaryKey(groupId);
296    
297                    checkTags(userId, group, names);
298            }
299    
300            /**
301             * Decrements the number of assets to which the asset tag has been applied.
302             *
303             * @param  tagId the primary key of the asset tag
304             * @param  classNameId the class name ID of the entity to which the asset
305             *         tag had been applied
306             * @return the asset tag
307             * @throws PortalException if an asset tag with the primary key could not be
308             *         found or if a portal exception occurred
309             * @throws SystemException if a system exception occurred
310             */
311            @Override
312            public AssetTag decrementAssetCount(long tagId, long classNameId)
313                    throws PortalException, SystemException {
314    
315                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
316    
317                    tag.setAssetCount(Math.max(0, tag.getAssetCount() - 1));
318    
319                    assetTagPersistence.update(tag);
320    
321                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
322    
323                    return tag;
324            }
325    
326            /**
327             * Deletes all asset tags in the group.
328             *
329             * @param  groupId the primary key of the group in which to delete all asset
330             *         tags
331             * @throws PortalException if a portal exception occurred
332             * @throws SystemException if a system exception occurred
333             */
334            @Override
335            public void deleteGroupTags(long groupId)
336                    throws PortalException, SystemException {
337    
338                    List<AssetTag> tags = getGroupTags(groupId);
339    
340                    for (AssetTag tag : tags) {
341                            deleteTag(tag);
342                    }
343            }
344    
345            /**
346             * Deletes the asset tag.
347             *
348             * @param  tag the asset tag to be deleted
349             * @throws PortalException if a portal exception occurred
350             * @throws SystemException if a system exception occurred
351             */
352            @Override
353            public void deleteTag(AssetTag tag)
354                    throws PortalException, SystemException {
355    
356                    // Entries
357    
358                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
359                            tag.getTagId());
360    
361                    // Tag
362    
363                    assetTagPersistence.remove(tag);
364    
365                    // Resources
366    
367                    resourceLocalService.deleteResource(
368                            tag.getCompanyId(), AssetTag.class.getName(),
369                            ResourceConstants.SCOPE_INDIVIDUAL, tag.getTagId());
370    
371                    // Properties
372    
373                    assetTagPropertyLocalService.deleteTagProperties(tag.getTagId());
374    
375                    // Indexer
376    
377                    assetEntryLocalService.reindex(entries);
378            }
379    
380            /**
381             * Deletes the asset tag.
382             *
383             * @param  tagId the primary key of the asset tag
384             * @throws PortalException if no asset tag could be found with the primary
385             *         key or if a portal exception occurred
386             * @throws SystemException if a system exception occurred
387             */
388            @Override
389            public void deleteTag(long tagId) throws PortalException, SystemException {
390                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
391    
392                    deleteTag(tag);
393            }
394    
395            /**
396             * Returns the asset tags of the asset entry.
397             *
398             * @param  entryId the primary key of the asset entry
399             * @return the asset tags of the asset entry
400             * @throws SystemException if a system exception occurred
401             */
402            @Override
403            public List<AssetTag> getEntryTags(long entryId) throws SystemException {
404                    return assetEntryPersistence.getAssetTags(entryId);
405            }
406    
407            /**
408             * Returns the asset tags in the groups.
409             *
410             * @param  groupIds the primary keys of the groups
411             * @return the asset tags in the groups
412             * @throws SystemException if a system exception occurred
413             */
414            @Override
415            public List<AssetTag> getGroupsTags(long[] groupIds)
416                    throws SystemException {
417    
418                    List<AssetTag> groupsTags = new ArrayList<AssetTag>();
419    
420                    for (long groupId : groupIds) {
421                            List<AssetTag> groupTags = getGroupTags(groupId);
422    
423                            groupsTags.addAll(groupTags);
424                    }
425    
426                    return groupsTags;
427            }
428    
429            /**
430             * Returns the asset tags in the group.
431             *
432             * @param  groupId the primary key of the group
433             * @return the asset tags in the group
434             * @throws SystemException if a system exception occurred
435             */
436            @Override
437            public List<AssetTag> getGroupTags(long groupId) throws SystemException {
438                    return assetTagPersistence.findByGroupId(groupId);
439            }
440    
441            /**
442             * Returns a range of all the asset tags in the group.
443             *
444             * @param  groupId the primary key of the group
445             * @param  start the lower bound of the range of asset tags
446             * @param  end the upper bound of the range of asset tags (not inclusive)
447             * @return the range of matching asset tags
448             * @throws SystemException if a system exception occurred
449             */
450            @Override
451            public List<AssetTag> getGroupTags(long groupId, int start, int end)
452                    throws SystemException {
453    
454                    return assetTagPersistence.findByGroupId(groupId, start, end);
455            }
456    
457            /**
458             * Returns the number of asset tags in the group.
459             *
460             * @param  groupId the primary key of the group
461             * @return the number of asset tags in the group
462             * @throws SystemException if a system exception occurred
463             */
464            @Override
465            public int getGroupTagsCount(long groupId) throws SystemException {
466                    return assetTagPersistence.countByGroupId(groupId);
467            }
468    
469            @Override
470            public List<AssetTag> getSocialActivityCounterOffsetTags(
471                            long groupId, String socialActivityCounterName, int startOffset,
472                            int endOffset)
473                    throws SystemException {
474    
475                    int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
476                    int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
477    
478                    return getSocialActivityCounterPeriodTags(
479                            groupId, socialActivityCounterName, startPeriod, endPeriod);
480            }
481    
482            @Override
483            public List<AssetTag> getSocialActivityCounterPeriodTags(
484                            long groupId, String socialActivityCounterName, int startPeriod,
485                            int endPeriod)
486                    throws SystemException {
487    
488                    int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
489    
490                    int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
491    
492                    return assetTagFinder.findByG_N_S_E(
493                            groupId, socialActivityCounterName, startPeriod, endPeriod,
494                            periodLength);
495            }
496    
497            /**
498             * Returns the asset tag with the primary key.
499             *
500             * @param  tagId the primary key of the asset tag
501             * @return the asset tag with the primary key
502             * @throws PortalException if an asset tag with the primary key could not be
503             *         found
504             * @throws SystemException if a system exception occurred
505             */
506            @Override
507            public AssetTag getTag(long tagId) throws PortalException, SystemException {
508                    return assetTagPersistence.findByPrimaryKey(tagId);
509            }
510    
511            /**
512             * Returns the asset tag with the name in the group.
513             *
514             * @param  groupId the primary key of the group
515             * @param  name the name of the asset tag
516             * @return the asset tag with the name in the group
517             * @throws PortalException if a matching asset tag could not be found
518             * @throws SystemException if a system exception occurred
519             */
520            @Override
521            public AssetTag getTag(long groupId, String name)
522                    throws PortalException, SystemException {
523    
524                    return assetTagFinder.findByG_N(groupId, name);
525            }
526    
527            /**
528             * Returns the primary keys of the asset tags with the names in the group.
529             *
530             * @param  groupId the primary key of the group
531             * @param  names the names of the asset tags
532             * @return the primary keys of the asset tags with the names in the group
533             * @throws PortalException if a portal exception occurred
534             * @throws SystemException if a system exception occurred
535             */
536            @Override
537            public long[] getTagIds(long groupId, String[] names)
538                    throws PortalException, SystemException {
539    
540                    List<Long> tagIds = new ArrayList<Long>(names.length);
541    
542                    for (String name : names) {
543                            try {
544                                    AssetTag tag = getTag(groupId, name);
545    
546                                    tagIds.add(tag.getTagId());
547                            }
548                            catch (NoSuchTagException nste) {
549                            }
550                    }
551    
552                    return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
553            }
554    
555            /**
556             * Returns the primary keys of the asset tags with the name in the groups.
557             *
558             * @param  groupIds the primary keys of the groups
559             * @param  name the name of the asset tags
560             * @return the primary keys of the asset tags with the name in the groups
561             * @throws PortalException if a portal exception occurred
562             * @throws SystemException if a system exception occurred
563             */
564            @Override
565            public long[] getTagIds(long[] groupIds, String name)
566                    throws PortalException, SystemException {
567    
568                    List<Long> tagIds = new ArrayList<Long>(groupIds.length);
569    
570                    for (long groupId : groupIds) {
571                            try {
572                                    AssetTag tag = getTag(groupId, name);
573    
574                                    tagIds.add(tag.getTagId());
575                            }
576                            catch (NoSuchTagException nste) {
577                            }
578                    }
579    
580                    return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
581            }
582    
583            /**
584             * Returns the primary keys of the asset tags with the names in the groups.
585             *
586             * @param  groupIds the primary keys of the groups
587             * @param  names the names of the asset tags
588             * @return the primary keys of the asset tags with the names in the groups
589             * @throws PortalException if a portal exception occurred
590             * @throws SystemException if a system exception occurred
591             */
592            @Override
593            public long[] getTagIds(long[] groupIds, String[] names)
594                    throws PortalException, SystemException {
595    
596                    long[] tagsIds = new long[0];
597    
598                    for (long groupId : groupIds) {
599                            tagsIds = ArrayUtil.append(tagsIds, getTagIds(groupId, names));
600                    }
601    
602                    return tagsIds;
603            }
604    
605            /**
606             * Returns the names of all the asset tags.
607             *
608             * @return the names of all the asset tags
609             * @throws SystemException if a system exception occurred
610             */
611            @Override
612            public String[] getTagNames() throws SystemException {
613                    return getTagNames(getTags());
614            }
615    
616            /**
617             * Returns the names of the asset tags of the entity.
618             *
619             * @param  classNameId the class name ID of the entity
620             * @param  classPK the primary key of the entity
621             * @return the names of the asset tags of the entity
622             * @throws SystemException if a system exception occurred
623             */
624            @Override
625            public String[] getTagNames(long classNameId, long classPK)
626                    throws SystemException {
627    
628                    return getTagNames(getTags(classNameId, classPK));
629            }
630    
631            /**
632             * Returns the names of the asset tags of the entity
633             *
634             * @param  className the class name of the entity
635             * @param  classPK the primary key of the entity
636             * @return the names of the asset tags of the entity
637             * @throws SystemException if a system exception occurred
638             */
639            @Override
640            public String[] getTagNames(String className, long classPK)
641                    throws SystemException {
642    
643                    return getTagNames(getTags(className, classPK));
644            }
645    
646            /**
647             * Returns all the asset tags.
648             *
649             * @return the asset tags
650             * @throws SystemException if a system exception occurred
651             */
652            @Override
653            public List<AssetTag> getTags() throws SystemException {
654                    return assetTagPersistence.findAll();
655            }
656    
657            /**
658             * Returns the asset tags of the entity.
659             *
660             * @param  classNameId the class name ID of the entity
661             * @param  classPK the primary key of the entity
662             * @return the asset tags of the entity
663             * @throws SystemException if a system exception occurred
664             */
665            @Override
666            public List<AssetTag> getTags(long classNameId, long classPK)
667                    throws SystemException {
668    
669                    AssetEntry entry = assetEntryPersistence.fetchByC_C(
670                            classNameId, classPK);
671    
672                    if (entry == null) {
673                            return Collections.emptyList();
674                    }
675    
676                    return assetEntryPersistence.getAssetTags(entry.getEntryId());
677            }
678    
679            @Override
680            public List<AssetTag> getTags(long groupId, long classNameId, String name)
681                    throws SystemException {
682    
683                    return assetTagFinder.findByG_C_N(
684                            groupId, classNameId, name, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
685                            null);
686            }
687    
688            @Override
689            public List<AssetTag> getTags(
690                            long groupId, long classNameId, String name, int start, int end)
691                    throws SystemException {
692    
693                    return assetTagFinder.findByG_C_N(
694                            groupId, classNameId, name, start, end, null);
695            }
696    
697            /**
698             * Returns the asset tags of the entity.
699             *
700             * @param  className the class name of the entity
701             * @param  classPK the primary key of the entity
702             * @return the asset tags of the entity
703             * @throws SystemException if a system exception occurred
704             */
705            @Override
706            @ThreadLocalCachable
707            public List<AssetTag> getTags(String className, long classPK)
708                    throws SystemException {
709    
710                    long classNameId = PortalUtil.getClassNameId(className);
711    
712                    return getTags(classNameId, classPK);
713            }
714    
715            @Override
716            public int getTagsSize(long groupId, long classNameId, String name)
717                    throws SystemException {
718    
719                    return assetTagFinder.countByG_C_N(groupId, classNameId, name);
720            }
721    
722            /**
723             * Returns <code>true</code> if the group contains an asset tag with the
724             * name.
725             *
726             * @param  groupId the primary key of the group
727             * @param  name the name of the asset tag
728             * @return <code>true</code> if the group contains an asset tag with the
729             *         name; <code>false</code> otherwise.
730             * @throws PortalException if a portal exception occurred
731             * @throws SystemException if a system exception occurred
732             */
733            @Override
734            public boolean hasTag(long groupId, String name)
735                    throws PortalException, SystemException {
736    
737                    try {
738                            getTag(groupId, name);
739    
740                            return true;
741                    }
742                    catch (NoSuchTagException nste) {
743                            return false;
744                    }
745            }
746    
747            /**
748             * Increments the number of assets to which the asset tag has been applied.
749             *
750             * @param  tagId the primary key of the asset tag
751             * @param  classNameId the class name ID of the entity to which the asset
752             *         tag is being applied
753             * @return the asset tag
754             * @throws PortalException if a asset tag with the primary key could not be
755             *         found or if a portal exception occurred
756             * @throws SystemException if a system exception occurred
757             */
758            @Override
759            public AssetTag incrementAssetCount(long tagId, long classNameId)
760                    throws PortalException, SystemException {
761    
762                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
763    
764                    tag.setAssetCount(tag.getAssetCount() + 1);
765    
766                    assetTagPersistence.update(tag);
767    
768                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
769    
770                    return tag;
771            }
772    
773            /**
774             * Replaces all occurrences of the first asset tag with the second asset tag
775             * and deletes the first asset tag.
776             *
777             * @param  fromTagId the primary key of the asset tag to be replaced
778             * @param  toTagId the primary key of the asset tag to apply to the asset
779             *         entries of the other asset tag
780             * @param  overrideProperties whether to override the properties of the
781             *         second asset tag with the properties of the first asset tag
782             * @throws PortalException if a portal exception occurred
783             * @throws SystemException if a system exception occurred
784             */
785            @Override
786            public void mergeTags(
787                            long fromTagId, long toTagId, boolean overrideProperties)
788                    throws PortalException, SystemException {
789    
790                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
791                            fromTagId);
792    
793                    assetTagPersistence.addAssetEntries(toTagId, entries);
794    
795                    List<AssetTagProperty> tagProperties =
796                            assetTagPropertyPersistence.findByTagId(fromTagId);
797    
798                    for (AssetTagProperty fromTagProperty : tagProperties) {
799                            AssetTagProperty toTagProperty =
800                                    assetTagPropertyPersistence.fetchByT_K(
801                                            toTagId, fromTagProperty.getKey());
802    
803                            if (overrideProperties && (toTagProperty != null)) {
804                                    toTagProperty.setValue(fromTagProperty.getValue());
805    
806                                    assetTagPropertyPersistence.update(toTagProperty);
807                            }
808                            else if (toTagProperty == null) {
809                                    fromTagProperty.setTagId(toTagId);
810    
811                                    assetTagPropertyPersistence.update(fromTagProperty);
812                            }
813                    }
814    
815                    deleteTag(fromTagId);
816            }
817    
818            /**
819             * Returns the asset tags in the group whose names match the pattern and the
820             * properties.
821             *
822             * @param  groupId the primary key of the group
823             * @param  name the pattern to match
824             * @param  tagProperties the properties to match
825             * @param  start the lower bound of the range of asset tags
826             * @param  end the upper bound of the range of asset tags (not inclusive)
827             * @return the asset tags in the group whose names match the pattern
828             * @throws SystemException if a system exception occurred
829             */
830            @Override
831            public List<AssetTag> search(
832                            long groupId, String name, String[] tagProperties, int start,
833                            int end)
834                    throws SystemException {
835    
836                    return search(new long[] {groupId}, name, tagProperties, start, end);
837            }
838    
839            /**
840             * Returns the asset tags in the groups whose names match the pattern and
841             * the properties.
842             *
843             * @param  groupIds the primary keys of the groups
844             * @param  name the pattern to match
845             * @param  tagProperties the properties to match
846             * @param  start the lower bound of the range of asset tags
847             * @param  end the upper bound of the range of asset tags (not inclusive)
848             * @return the asset tags in the groups whose names match the pattern
849             * @throws SystemException if a system exception occurred
850             */
851            @Override
852            public List<AssetTag> search(
853                            long[] groupIds, String name, String[] tagProperties, int start,
854                            int end)
855                    throws SystemException {
856    
857                    return assetTagFinder.findByG_N_P(
858                            groupIds, name, tagProperties, start, end, null);
859            }
860    
861            @Override
862            public AssetTag updateTag(
863                            long userId, long tagId, String name, String[] tagProperties,
864                            ServiceContext serviceContext)
865                    throws PortalException, SystemException {
866    
867                    // Tag
868    
869                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
870    
871                    String oldName = tag.getName();
872    
873                    tag.setModifiedDate(new Date());
874    
875                    name = name.trim();
876                    name = StringUtil.toLowerCase(name);
877    
878                    if (tagProperties == null) {
879                            tagProperties = new String[0];
880                    }
881    
882                    if (!name.equals(tag.getName()) && hasTag(tag.getGroupId(), name)) {
883                            throw new DuplicateTagException(
884                                    "A tag with the name " + name + " already exists");
885                    }
886    
887                    if (!tag.getName().equals(name)) {
888                            try {
889                                    AssetTag existingAssetTag = getTag(tag.getGroupId(), name);
890    
891                                    if (existingAssetTag.getTagId() != tagId) {
892                                            throw new DuplicateTagException(
893                                                    "A tag with the name " + name + " already exists");
894                                    }
895                            }
896                            catch (NoSuchTagException nste) {
897                            }
898                    }
899    
900                    validate(name);
901    
902                    tag.setName(name);
903    
904                    assetTagPersistence.update(tag);
905    
906                    // Properties
907    
908                    List<AssetTagProperty> oldTagProperties =
909                            assetTagPropertyPersistence.findByTagId(tagId);
910    
911                    Set<String> newKeys = new HashSet<String>();
912    
913                    for (int i = 0; i < tagProperties.length; i++) {
914                            String[] tagProperty = StringUtil.split(
915                                    tagProperties[i],
916                                    AssetTagConstants.PROPERTY_KEY_VALUE_SEPARATOR);
917    
918                            if (tagProperty.length <= 1) {
919                                    tagProperty = StringUtil.split(
920                                            tagProperties[i], CharPool.COLON);
921                            }
922    
923                            String key = StringPool.BLANK;
924    
925                            if (tagProperty.length > 0) {
926                                    key = GetterUtil.getString(tagProperty[0]);
927                            }
928    
929                            String value = StringPool.BLANK;
930    
931                            if (tagProperty.length > 1) {
932                                    value = GetterUtil.getString(tagProperty[1]);
933                            }
934    
935                            if (Validator.isNotNull(key)) {
936                                    newKeys.add(key);
937    
938                                    AssetTagProperty keyTagProperty =
939                                            assetTagPropertyPersistence.fetchByT_K(tagId, key);
940    
941                                    if (keyTagProperty == null) {
942                                            assetTagPropertyLocalService.addTagProperty(
943                                                    userId, tagId, key, value);
944                                    }
945                                    else {
946                                            assetTagPropertyLocalService.updateTagProperty(
947                                                    keyTagProperty.getTagPropertyId(), key, value);
948                                    }
949                            }
950                    }
951    
952                    for (AssetTagProperty tagProperty : oldTagProperties) {
953                            if (!newKeys.contains(tagProperty.getKey())) {
954                                    assetTagPropertyLocalService.deleteTagProperty(tagProperty);
955                            }
956                    }
957    
958                    // Indexer
959    
960                    if (!oldName.equals(name)) {
961                            List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
962                                    tag.getTagId());
963    
964                            assetEntryLocalService.reindex(entries);
965                    }
966    
967                    return tag;
968            }
969    
970            protected String[] getTagNames(List<AssetTag>tags) {
971                    return StringUtil.split(
972                            ListUtil.toString(tags, AssetTag.NAME_ACCESSOR));
973            }
974    
975            protected void validate(String name) throws PortalException {
976                    if (!AssetUtil.isValidWord(name)) {
977                            throw new AssetTagException(
978                                    StringUtil.merge(
979                                            AssetUtil.INVALID_CHARACTERS, StringPool.SPACE),
980                                    AssetTagException.INVALID_CHARACTER);
981                    }
982            }
983    
984    }