001    /**
002     * Copyright (c) 2000-2010 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.json.JSONArray;
021    import com.liferay.portal.kernel.search.Indexer;
022    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
023    import com.liferay.portal.kernel.util.ArrayUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.ListUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.Validator;
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.AssetTagProperty;
040    import com.liferay.portlet.asset.service.base.AssetTagLocalServiceBaseImpl;
041    import com.liferay.portlet.asset.util.AssetUtil;
042    import com.liferay.util.Autocomplete;
043    
044    import java.util.ArrayList;
045    import java.util.Date;
046    import java.util.List;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Alvaro del Castillo
051     * @author Jorge Ferrer
052     * @author Bruno Farache
053     */
054    public class AssetTagLocalServiceImpl extends AssetTagLocalServiceBaseImpl {
055    
056            public AssetTag addTag(
057                            long userId, String name, String[] tagProperties,
058                            ServiceContext serviceContext)
059                    throws PortalException, SystemException {
060    
061                    // Tag
062    
063                    User user = userPersistence.findByPrimaryKey(userId);
064                    long groupId = serviceContext.getScopeGroupId();
065    
066                    if (tagProperties == null) {
067                            tagProperties = new String[0];
068                    }
069    
070                    Date now = new Date();
071    
072                    long tagId = counterLocalService.increment();
073    
074                    AssetTag tag = assetTagPersistence.create(tagId);
075    
076                    tag.setGroupId(groupId);
077                    tag.setCompanyId(user.getCompanyId());
078                    tag.setUserId(user.getUserId());
079                    tag.setUserName(user.getFullName());
080                    tag.setCreateDate(now);
081                    tag.setModifiedDate(now);
082    
083                    name = name.trim();
084                    name = name.toLowerCase();
085    
086                    if (hasTag(groupId, name)) {
087                            throw new DuplicateTagException(
088                                    "A tag with the name " + name + " already exists");
089                    }
090    
091                    validate(name);
092    
093                    tag.setName(name);
094    
095                    assetTagPersistence.update(tag, false);
096    
097                    // Resources
098    
099                    if (serviceContext.getAddCommunityPermissions() ||
100                            serviceContext.getAddGuestPermissions()) {
101    
102                            addTagResources(
103                                    tag, serviceContext.getAddCommunityPermissions(),
104                                    serviceContext.getAddGuestPermissions());
105                    }
106                    else {
107                            addTagResources(
108                                    tag, serviceContext.getCommunityPermissions(),
109                                    serviceContext.getGuestPermissions());
110                    }
111    
112                    // Properties
113    
114                    for (int i = 0; i < tagProperties.length; i++) {
115                            String[] tagProperty = StringUtil.split(
116                                    tagProperties[i], StringPool.COLON);
117    
118                            String key = StringPool.BLANK;
119    
120                            if (tagProperty.length > 1) {
121                                    key = GetterUtil.getString(tagProperty[1]);
122                            }
123    
124                            String value = StringPool.BLANK;
125    
126                            if (tagProperty.length > 2) {
127                                    value = GetterUtil.getString(tagProperty[2]);
128                            }
129    
130                            if (Validator.isNotNull(key)) {
131                                    assetTagPropertyLocalService.addTagProperty(
132                                            userId, tagId, key, value);
133                            }
134                    }
135    
136                    return tag;
137            }
138    
139            public void addTagResources(
140                            AssetTag tag, boolean addCommunityPermissions,
141                            boolean addGuestPermissions)
142                    throws PortalException, SystemException {
143    
144                    resourceLocalService.addResources(
145                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
146                            AssetTag.class.getName(), tag.getTagId(), false,
147                            addCommunityPermissions, addGuestPermissions);
148            }
149    
150            public void addTagResources(
151                            AssetTag tag, String[] communityPermissions,
152                            String[] guestPermissions)
153                    throws PortalException, SystemException {
154    
155                    resourceLocalService.addModelResources(
156                            tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
157                            AssetTag.class.getName(), tag.getTagId(), communityPermissions,
158                            guestPermissions);
159            }
160    
161            public void checkTags(long userId, long groupId, String[] names)
162                    throws PortalException, SystemException {
163    
164                    for (String name : names) {
165                            try {
166                                    getTag(groupId, name);
167                            }
168                            catch (NoSuchTagException nste) {
169                                    ServiceContext serviceContext = new ServiceContext();
170    
171                                    serviceContext.setAddCommunityPermissions(true);
172                                    serviceContext.setAddGuestPermissions(true);
173                                    serviceContext.setScopeGroupId(groupId);
174    
175                                    addTag(
176                                            userId, name, PropsValues.ASSET_TAG_PROPERTIES_DEFAULT,
177                                            serviceContext);
178                            }
179                    }
180            }
181    
182            public AssetTag decrementAssetCount(long tagId, long classNameId)
183                    throws PortalException, SystemException {
184    
185                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
186    
187                    tag.setAssetCount(Math.max(0, tag.getAssetCount() - 1));
188    
189                    assetTagPersistence.update(tag, false);
190    
191                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
192    
193                    return tag;
194            }
195    
196            public void deleteTag(AssetTag tag)
197                    throws PortalException, SystemException {
198    
199                    // Entries
200    
201                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
202                            tag.getTagId());
203    
204                    // Tag
205    
206                    assetTagPersistence.remove(tag);
207    
208                    // Resources
209    
210                    resourceLocalService.deleteResource(
211                            tag.getCompanyId(), AssetTag.class.getName(),
212                            ResourceConstants.SCOPE_INDIVIDUAL, tag.getTagId());
213    
214                    // Properties
215    
216                    assetTagPropertyLocalService.deleteTagProperties(tag.getTagId());
217    
218                    // Indexer
219    
220                    reindex(entries);
221            }
222    
223            public void deleteTag(long tagId) throws PortalException, SystemException {
224                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
225    
226                    deleteTag(tag);
227            }
228    
229            public List<AssetTag> getEntryTags(long entryId) throws SystemException {
230                    return assetTagFinder.findByEntryId(entryId);
231            }
232    
233            public List<AssetTag> getGroupTags(long groupId) throws SystemException {
234                    return assetTagPersistence.findByGroupId(groupId);
235            }
236    
237            public AssetTag getTag(long tagId) throws PortalException, SystemException {
238                    return assetTagPersistence.findByPrimaryKey(tagId);
239            }
240    
241            public AssetTag getTag(long groupId, String name)
242                    throws PortalException, SystemException {
243    
244                    return assetTagFinder.findByG_N(groupId, name);
245            }
246    
247            public long[] getTagIds(long groupId, String[] names)
248                    throws PortalException, SystemException {
249    
250                    List<Long> tagIds = new ArrayList<Long>(names.length);
251    
252                    for (String name : names) {
253                            try {
254                                    AssetTag tag = getTag(groupId, name);
255    
256                                    tagIds.add(tag.getTagId());
257                            }
258                            catch (NoSuchTagException nste) {
259                            }
260                    }
261    
262                    return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
263            }
264    
265            public String[] getTagNames() throws SystemException {
266                    return getTagNames(getTags());
267            }
268    
269            public String[] getTagNames(long classNameId, long classPK)
270                    throws SystemException {
271    
272                    return getTagNames(getTags(classNameId, classPK));
273            }
274    
275            public String[] getTagNames(String className, long classPK)
276                    throws SystemException {
277    
278                    return getTagNames(getTags(className, classPK));
279            }
280    
281            public List<AssetTag> getTags() throws SystemException {
282                    return assetTagPersistence.findAll();
283            }
284    
285            public List<AssetTag> getTags(long classNameId, long classPK)
286                    throws SystemException {
287    
288                    return assetTagFinder.findByC_C(classNameId, classPK);
289            }
290    
291            public List<AssetTag> getTags(long groupId, long classNameId, String name)
292                    throws SystemException {
293    
294                    return assetTagFinder.findByG_C_N(groupId, classNameId, name);
295            }
296    
297            public List<AssetTag> getTags(
298                            long groupId, long classNameId, String name, int start, int end)
299                    throws SystemException {
300    
301                    return assetTagFinder.findByG_C_N(
302                            groupId, classNameId, name, start, end);
303            }
304    
305            @ThreadLocalCachable
306            public List<AssetTag> getTags(String className, long classPK)
307                    throws SystemException {
308    
309                    long classNameId = PortalUtil.getClassNameId(className);
310    
311                    return getTags(classNameId, classPK);
312            }
313    
314            public int getTagsSize(long groupId, long classNameId, String name)
315                    throws SystemException {
316    
317                    return assetTagFinder.countByG_C_N(groupId, classNameId, name);
318            }
319    
320            public boolean hasTag(long groupId, String name)
321                    throws PortalException, SystemException {
322    
323                    try {
324                            getTag(groupId, name);
325    
326                            return true;
327                    }
328                    catch (NoSuchTagException nste) {
329                            return false;
330                    }
331            }
332    
333            public AssetTag incrementAssetCount(long tagId, long classNameId)
334                    throws PortalException, SystemException {
335    
336                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
337    
338                    tag.setAssetCount(tag.getAssetCount() + 1);
339    
340                    assetTagPersistence.update(tag, false);
341    
342                    assetTagStatsLocalService.updateTagStats(tagId, classNameId);
343    
344                    return tag;
345            }
346    
347            public void mergeTags(long fromTagId, long toTagId)
348                    throws PortalException, SystemException {
349    
350                    List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
351                            fromTagId);
352    
353                    assetTagPersistence.addAssetEntries(toTagId, entries);
354    
355                    List<AssetTagProperty> tagProperties =
356                            assetTagPropertyPersistence.findByTagId(fromTagId);
357    
358                    for (AssetTagProperty fromTagProperty : tagProperties) {
359                            AssetTagProperty toTagProperty =
360                                    assetTagPropertyPersistence.fetchByT_K(
361                                            toTagId, fromTagProperty.getKey());
362    
363                            if (toTagProperty == null) {
364                                    fromTagProperty.setTagId(toTagId);
365    
366                                    assetTagPropertyPersistence.update(fromTagProperty, false);
367                            }
368                    }
369    
370                    deleteTag(fromTagId);
371            }
372    
373            public JSONArray search(
374                            long groupId, String name, String[] tagProperties, int start,
375                            int end)
376                    throws SystemException {
377    
378                    List<AssetTag> list = assetTagFinder.findByG_N_P(
379                            groupId, name, tagProperties, start, end);
380    
381                    return Autocomplete.listToJson(list, "name", "name");
382            }
383    
384            public AssetTag updateTag(
385                            long userId, long tagId, String name, String[] tagProperties,
386                            ServiceContext serviceContext)
387                    throws PortalException, SystemException {
388    
389                    // Tag
390    
391                    AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
392    
393                    String oldName = tag.getName();
394    
395                    tag.setModifiedDate(new Date());
396    
397                    name = name.trim();
398                    name = name.toLowerCase();
399    
400                    if (tagProperties == null) {
401                            tagProperties = new String[0];
402                    }
403    
404                    if (!tag.getName().equals(name) &&
405                            hasTag(tag.getGroupId(), name)) {
406    
407                            throw new DuplicateTagException(
408                                    "A tag with the name " + name + " already exists");
409                    }
410    
411                    if (!tag.getName().equals(name)) {
412                            try {
413                                    AssetTag existingAssetTag = getTag(tag.getGroupId(), name);
414    
415                                    if (existingAssetTag.getTagId() != tagId) {
416                                            throw new DuplicateTagException(
417                                                    "A tag with the name " + name + " already exists");
418                                    }
419                            }
420                            catch (NoSuchTagException nste) {
421                            }
422                    }
423    
424                    validate(name);
425    
426                    tag.setName(name);
427    
428                    assetTagPersistence.update(tag, false);
429    
430                    // Properties
431    
432                    List<AssetTagProperty> oldTagProperties =
433                            assetTagPropertyPersistence.findByTagId(tagId);
434    
435                    for (AssetTagProperty tagProperty : oldTagProperties) {
436                            assetTagPropertyLocalService.deleteTagProperty(tagProperty);
437                    }
438    
439                    for (int i = 0; i < tagProperties.length; i++) {
440                            String[] tagProperty = StringUtil.split(
441                                    tagProperties[i], StringPool.COLON);
442    
443                            String key = StringPool.BLANK;
444    
445                            if (tagProperty.length > 0) {
446                                    key = GetterUtil.getString(tagProperty[0]);
447                            }
448    
449                            String value = StringPool.BLANK;
450    
451                            if (tagProperty.length > 1) {
452                                    value = GetterUtil.getString(tagProperty[1]);
453                            }
454    
455                            if (Validator.isNotNull(key)) {
456                                    assetTagPropertyLocalService.addTagProperty(
457                                            userId, tagId, key, value);
458                            }
459                    }
460    
461                    // Indexer
462    
463                    if (!oldName.equals(name)) {
464                            List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
465                                    tag.getTagId());
466    
467                            reindex(entries);
468                    }
469    
470                    return tag;
471            }
472    
473            protected String[] getTagNames(List <AssetTag>tags) {
474                    return StringUtil.split(ListUtil.toString(tags, "name"));
475            }
476    
477            protected void reindex(List<AssetEntry> entries) throws PortalException {
478                    for (AssetEntry entry : entries) {
479                            String className = PortalUtil.getClassName(entry.getClassNameId());
480    
481                            Indexer indexer = IndexerRegistryUtil.getIndexer(className);
482    
483                            indexer.reindex(className, entry.getClassPK());
484                    }
485            }
486    
487            protected void validate(String name) throws PortalException {
488                    if (!AssetUtil.isValidWord(name)) {
489                            throw new AssetTagException(AssetTagException.INVALID_CHARACTER);
490                    }
491            }
492    
493    }