1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.asset.service.impl;
16  
17  import com.liferay.portal.kernel.exception.PortalException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.json.JSONArray;
20  import com.liferay.portal.kernel.search.Indexer;
21  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
22  import com.liferay.portal.kernel.util.ArrayUtil;
23  import com.liferay.portal.kernel.util.GetterUtil;
24  import com.liferay.portal.kernel.util.ListUtil;
25  import com.liferay.portal.kernel.util.StringPool;
26  import com.liferay.portal.kernel.util.StringUtil;
27  import com.liferay.portal.kernel.util.Validator;
28  import com.liferay.portal.model.ResourceConstants;
29  import com.liferay.portal.model.User;
30  import com.liferay.portal.service.ServiceContext;
31  import com.liferay.portal.util.PortalUtil;
32  import com.liferay.portal.util.PropsValues;
33  import com.liferay.portlet.asset.AssetTagException;
34  import com.liferay.portlet.asset.DuplicateTagException;
35  import com.liferay.portlet.asset.NoSuchTagException;
36  import com.liferay.portlet.asset.model.AssetEntry;
37  import com.liferay.portlet.asset.model.AssetTag;
38  import com.liferay.portlet.asset.model.AssetTagProperty;
39  import com.liferay.portlet.asset.service.base.AssetTagLocalServiceBaseImpl;
40  import com.liferay.portlet.asset.util.AssetUtil;
41  import com.liferay.util.Autocomplete;
42  
43  import java.util.ArrayList;
44  import java.util.Date;
45  import java.util.List;
46  
47  /**
48   * <a href="AssetTagLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Brian Wing Shun Chan
51   * @author Alvaro del Castillo
52   * @author Jorge Ferrer
53   * @author Bruno Farache
54   */
55  public class AssetTagLocalServiceImpl extends AssetTagLocalServiceBaseImpl {
56  
57      public AssetTag addTag(
58              long userId, String name, String[] tagProperties,
59              ServiceContext serviceContext)
60          throws PortalException, SystemException {
61  
62          // Tag
63  
64          User user = userPersistence.findByPrimaryKey(userId);
65          long groupId = serviceContext.getScopeGroupId();
66  
67          if (tagProperties == null) {
68              tagProperties = new String[0];
69          }
70  
71          Date now = new Date();
72  
73          long tagId = counterLocalService.increment();
74  
75          AssetTag tag = assetTagPersistence.create(tagId);
76  
77          tag.setGroupId(groupId);
78          tag.setCompanyId(user.getCompanyId());
79          tag.setUserId(user.getUserId());
80          tag.setUserName(user.getFullName());
81          tag.setCreateDate(now);
82          tag.setModifiedDate(now);
83  
84          name = name.trim();
85          name = name.toLowerCase();
86  
87          if (hasTag(groupId, name)) {
88              throw new DuplicateTagException(
89                  "A tag with the name " + name + " already exists");
90          }
91  
92          validate(name);
93  
94          tag.setName(name);
95  
96          assetTagPersistence.update(tag, false);
97  
98          // Resources
99  
100         if (serviceContext.getAddCommunityPermissions() ||
101             serviceContext.getAddGuestPermissions()) {
102 
103             addTagResources(
104                 tag, serviceContext.getAddCommunityPermissions(),
105                 serviceContext.getAddGuestPermissions());
106         }
107         else {
108             addTagResources(
109                 tag, serviceContext.getCommunityPermissions(),
110                 serviceContext.getGuestPermissions());
111         }
112 
113         // Properties
114 
115         for (int i = 0; i < tagProperties.length; i++) {
116             String[] tagProperty = StringUtil.split(
117                 tagProperties[i], StringPool.COLON);
118 
119             String key = StringPool.BLANK;
120 
121             if (tagProperty.length > 1) {
122                 key = GetterUtil.getString(tagProperty[1]);
123             }
124 
125             String value = StringPool.BLANK;
126 
127             if (tagProperty.length > 2) {
128                 value = GetterUtil.getString(tagProperty[2]);
129             }
130 
131             if (Validator.isNotNull(key)) {
132                 assetTagPropertyLocalService.addTagProperty(
133                     userId, tagId, key, value);
134             }
135         }
136 
137         return tag;
138     }
139 
140     public void addTagResources(
141             AssetTag tag, boolean addCommunityPermissions,
142             boolean addGuestPermissions)
143         throws PortalException, SystemException {
144 
145         resourceLocalService.addResources(
146             tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
147             AssetTag.class.getName(), tag.getTagId(), false,
148             addCommunityPermissions, addGuestPermissions);
149     }
150 
151     public void addTagResources(
152             AssetTag tag, String[] communityPermissions,
153             String[] guestPermissions)
154         throws PortalException, SystemException {
155 
156         resourceLocalService.addModelResources(
157             tag.getCompanyId(), tag.getGroupId(), tag.getUserId(),
158             AssetTag.class.getName(), tag.getTagId(), communityPermissions,
159             guestPermissions);
160     }
161 
162     public void checkTags(long userId, long groupId, String[] names)
163         throws PortalException, SystemException {
164 
165         for (String name : names) {
166             try {
167                 getTag(groupId, name);
168             }
169             catch (NoSuchTagException nste) {
170                 ServiceContext serviceContext = new ServiceContext();
171 
172                 serviceContext.setAddCommunityPermissions(true);
173                 serviceContext.setAddGuestPermissions(true);
174                 serviceContext.setScopeGroupId(groupId);
175 
176                 addTag(
177                     userId, name, PropsValues.ASSET_TAG_PROPERTIES_DEFAULT,
178                     serviceContext);
179             }
180         }
181     }
182 
183     public AssetTag decrementAssetCount(long tagId, long classNameId)
184         throws PortalException, SystemException {
185 
186         AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
187 
188         tag.setAssetCount(Math.max(0, tag.getAssetCount() - 1));
189 
190         assetTagPersistence.update(tag, false);
191 
192         assetTagStatsLocalService.updateTagStats(tagId, classNameId);
193 
194         return tag;
195     }
196 
197     public void deleteTag(AssetTag tag)
198         throws PortalException, SystemException {
199 
200         // Entries
201 
202         List<AssetEntry> entries = assetTagPersistence.getAssetEntries(
203             tag.getTagId());
204 
205         // Tag
206 
207         assetTagPersistence.remove(tag);
208 
209         // Resources
210 
211         resourceLocalService.deleteResource(
212             tag.getCompanyId(), AssetTag.class.getName(),
213             ResourceConstants.SCOPE_INDIVIDUAL, tag.getTagId());
214 
215         // Properties
216 
217         assetTagPropertyLocalService.deleteTagProperties(tag.getTagId());
218 
219         // Indexer
220 
221         reindex(entries);
222     }
223 
224     public void deleteTag(long tagId) throws PortalException, SystemException {
225         AssetTag tag = assetTagPersistence.findByPrimaryKey(tagId);
226 
227         deleteTag(tag);
228     }
229 
230     public List<AssetTag> getEntryTags(long entryId) throws SystemException {
231         return assetTagFinder.findByEntryId(entryId);
232     }
233 
234     public List<AssetTag> getGroupTags(long groupId) throws SystemException {
235         return assetTagPersistence.findByGroupId(groupId);
236     }
237 
238     public AssetTag getTag(long tagId) throws PortalException, SystemException {
239         return assetTagPersistence.findByPrimaryKey(tagId);
240     }
241 
242     public AssetTag getTag(long groupId, String name)
243         throws PortalException, SystemException {
244 
245         return assetTagFinder.findByG_N(groupId, name);
246     }
247 
248     public long[] getTagIds(long groupId, String[] names)
249         throws PortalException, SystemException {
250 
251         List<Long> tagIds = new ArrayList<Long>(names.length);
252 
253         for (String name : names) {
254             try {
255                 AssetTag tag = getTag(groupId, name);
256 
257                 tagIds.add(tag.getTagId());
258             }
259             catch (NoSuchTagException nste) {
260             }
261         }
262 
263         return ArrayUtil.toArray(tagIds.toArray(new Long[tagIds.size()]));
264     }
265 
266     public String[] getTagNames() throws SystemException {
267         return getTagNames(getTags());
268     }
269 
270     public String[] getTagNames(long classNameId, long classPK)
271         throws SystemException {
272 
273         return getTagNames(getTags(classNameId, classPK));
274     }
275 
276     public String[] getTagNames(String className, long classPK)
277         throws SystemException {
278 
279         return getTagNames(getTags(className, classPK));
280     }
281 
282     public List<AssetTag> getTags() throws SystemException {
283         return getTags();
284     }
285 
286     public List<AssetTag> getTags(long classNameId, long classPK)
287         throws SystemException {
288 
289         return assetTagFinder.findByC_C(classNameId, classPK);
290     }
291 
292     public List<AssetTag> getTags(long groupId, long classNameId, String name)
293         throws SystemException {
294 
295         return assetTagFinder.findByG_C_N(groupId, classNameId, name);
296     }
297 
298     public List<AssetTag> getTags(
299             long groupId, long classNameId, String name, int start, int end)
300         throws SystemException {
301 
302         return assetTagFinder.findByG_C_N(
303             groupId, classNameId, name, start, end);
304     }
305 
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 }