1
14
15 package com.liferay.portlet.tags.service.impl;
16
17 import com.liferay.portal.PortalException;
18 import com.liferay.portal.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.tags.DuplicateEntryException;
34 import com.liferay.portlet.tags.NoSuchEntryException;
35 import com.liferay.portlet.tags.NoSuchVocabularyException;
36 import com.liferay.portlet.tags.TagsEntryException;
37 import com.liferay.portlet.tags.model.TagsAsset;
38 import com.liferay.portlet.tags.model.TagsEntry;
39 import com.liferay.portlet.tags.model.TagsEntryConstants;
40 import com.liferay.portlet.tags.model.TagsProperty;
41 import com.liferay.portlet.tags.model.TagsVocabulary;
42 import com.liferay.portlet.tags.service.base.TagsEntryLocalServiceBaseImpl;
43 import com.liferay.portlet.tags.util.TagsUtil;
44 import com.liferay.util.Autocomplete;
45
46 import java.util.ArrayList;
47 import java.util.Date;
48 import java.util.List;
49
50
58 public class TagsEntryLocalServiceImpl extends TagsEntryLocalServiceBaseImpl {
59
60 public TagsEntry addEntry(
61 long userId, String parentEntryName, String name,
62 String vocabularyName, String[] properties,
63 ServiceContext serviceContext)
64 throws PortalException, SystemException {
65
66
68 User user = userPersistence.findByPrimaryKey(userId);
69 long groupId = serviceContext.getScopeGroupId();
70
71 if (Validator.isNull(vocabularyName)) {
72 vocabularyName = PropsValues.TAGS_VOCABULARY_DEFAULT;
73 }
74
75 if (properties == null) {
76 properties = new String[0];
77 }
78
79 Date now = new Date();
80
81 long entryId = counterLocalService.increment();
82
83 TagsEntry entry = tagsEntryPersistence.create(entryId);
84
85 entry.setGroupId(groupId);
86 entry.setCompanyId(user.getCompanyId());
87 entry.setUserId(user.getUserId());
88 entry.setUserName(user.getFullName());
89 entry.setCreateDate(now);
90 entry.setModifiedDate(now);
91
92 TagsVocabulary vocabulary = null;
93
94 try {
95 vocabulary = tagsVocabularyPersistence.findByG_N(
96 groupId, vocabularyName);
97 }
98 catch (NoSuchVocabularyException nsve) {
99 if (vocabularyName.equals(PropsValues.TAGS_VOCABULARY_DEFAULT)) {
100 ServiceContext vocabularyServiceContext = new ServiceContext();
101
102 vocabularyServiceContext.setAddCommunityPermissions(true);
103 vocabularyServiceContext.setAddGuestPermissions(true);
104 vocabularyServiceContext.setScopeGroupId(groupId);
105
106 vocabulary = tagsVocabularyLocalService.addVocabulary(
107 userId, vocabularyName, TagsEntryConstants.FOLKSONOMY_TAG,
108 vocabularyServiceContext);
109 }
110 else {
111 throw nsve;
112 }
113 }
114
115 entry.setVocabularyId(vocabulary.getVocabularyId());
116
117 boolean folksonomy = vocabulary.isFolksonomy();
118
119 name = name.trim();
120
121 if (folksonomy) {
122 name = name.toLowerCase();
123 }
124
125 if (hasEntry(groupId, name, folksonomy)) {
126 throw new DuplicateEntryException(
127 "A tag entry with the name " + name + " already exists");
128 }
129
130 validate(name);
131
132 entry.setName(name);
133
134 if (Validator.isNotNull(parentEntryName)) {
135 TagsEntry parentEntry = getEntry(
136 groupId, parentEntryName, folksonomy);
137
138 entry.setParentEntryId(parentEntry.getEntryId());
139 }
140 else {
141 entry.setParentEntryId(TagsEntryConstants.DEFAULT_PARENT_ENTRY_ID);
142 }
143
144 tagsEntryPersistence.update(entry, false);
145
146
148 if (serviceContext.getAddCommunityPermissions() ||
149 serviceContext.getAddGuestPermissions()) {
150
151 addEntryResources(
152 entry, serviceContext.getAddCommunityPermissions(),
153 serviceContext.getAddGuestPermissions());
154 }
155 else {
156 addEntryResources(
157 entry, serviceContext.getCommunityPermissions(),
158 serviceContext.getGuestPermissions());
159 }
160
161
163 for (int i = 0; i < properties.length; i++) {
164 String[] property = StringUtil.split(
165 properties[i], StringPool.COLON);
166
167 String key = StringPool.BLANK;
168
169 if (property.length > 1) {
170 key = GetterUtil.getString(property[1]);
171 }
172
173 String value = StringPool.BLANK;
174
175 if (property.length > 2) {
176 value = GetterUtil.getString(property[2]);
177 }
178
179 if (Validator.isNotNull(key)) {
180 tagsPropertyLocalService.addProperty(
181 userId, entryId, key, value);
182 }
183 }
184
185 return entry;
186 }
187
188 public void addEntryResources(
189 TagsEntry entry, boolean addCommunityPermissions,
190 boolean addGuestPermissions)
191 throws PortalException, SystemException {
192
193 resourceLocalService.addResources(
194 entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
195 TagsEntry.class.getName(), entry.getEntryId(), false,
196 addCommunityPermissions, addGuestPermissions);
197 }
198
199 public void addEntryResources(
200 TagsEntry entry, String[] communityPermissions,
201 String[] guestPermissions)
202 throws PortalException, SystemException {
203
204 resourceLocalService.addModelResources(
205 entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
206 TagsEntry.class.getName(), entry.getEntryId(), communityPermissions,
207 guestPermissions);
208 }
209
210 public void checkEntries(long userId, long groupId, String[] names)
211 throws PortalException, SystemException {
212
213 for (String name : names) {
214 try {
215 getEntry(groupId, name, TagsEntryConstants.FOLKSONOMY_TAG);
216 }
217 catch (NoSuchEntryException nsee) {
218 ServiceContext serviceContext = new ServiceContext();
219
220 serviceContext.setAddCommunityPermissions(true);
221 serviceContext.setAddGuestPermissions(true);
222 serviceContext.setScopeGroupId(groupId);
223
224 addEntry(
225 userId, null, name, null,
226 PropsValues.TAGS_PROPERTIES_DEFAULT, serviceContext);
227 }
228 }
229 }
230
231 public void deleteEntry(long entryId)
232 throws PortalException, SystemException {
233
234 TagsEntry entry = tagsEntryPersistence.findByPrimaryKey(entryId);
235
236 deleteEntry(entry);
237 }
238
239 public void deleteEntry(TagsEntry entry)
240 throws PortalException, SystemException {
241
242
244 List<TagsAsset> assets = tagsEntryPersistence.getTagsAssets(
245 entry.getEntryId());
246
247
249 tagsEntryPersistence.remove(entry);
250
251
253 resourceLocalService.deleteResource(
254 entry.getCompanyId(), TagsEntry.class.getName(),
255 ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
256
257
259 List<TagsEntry> childEntries = tagsEntryPersistence.findByP_V(
260 entry.getEntryId(), entry.getVocabularyId());
261
262 for (TagsEntry childEntry : childEntries) {
263 deleteEntry(childEntry);
264 }
265
266
268 tagsPropertyLocalService.deleteProperties(entry.getEntryId());
269
270
272 reIndex(assets);
273 }
274
275 public void deleteVocabularyEntries(long vocabularyId)
276 throws PortalException, SystemException {
277
278 List<TagsEntry> entries = tagsEntryPersistence.findByVocabularyId(
279 vocabularyId);
280
281 for (TagsEntry entry : entries) {
282 deleteEntry(entry);
283 }
284 }
285
286 public List<TagsEntry> getAssetEntries(long assetId, boolean folksonomy)
287 throws SystemException {
288
289 return tagsEntryFinder.findByA_F(assetId, folksonomy);
290 }
291
292 public List<TagsEntry> getEntries() throws SystemException {
293 return getEntries(TagsEntryConstants.FOLKSONOMY_TAG);
294 }
295
296 public List<TagsEntry> getEntries(boolean folksonomy)
297 throws SystemException {
298
299 return tagsEntryFinder.findByFolksonomy(folksonomy);
300 }
301
302 public List<TagsEntry> getEntries(long classNameId, long classPK)
303 throws SystemException {
304
305 return getEntries(
306 classNameId, classPK, TagsEntryConstants.FOLKSONOMY_TAG);
307 }
308
309 public List<TagsEntry> getEntries(
310 long classNameId, long classPK, boolean folksonomy)
311 throws SystemException {
312
313 return tagsEntryFinder.findByC_C_F(classNameId, classPK, folksonomy);
314 }
315
316 public List<TagsEntry> getEntries(
317 long groupId, long classNameId, String name)
318 throws SystemException {
319
320 return tagsEntryFinder.findByG_C_N_F(
321 groupId, classNameId, name, TagsEntryConstants.FOLKSONOMY_TAG);
322 }
323
324 public List<TagsEntry> getEntries(
325 long groupId, long classNameId, String name, int start, int end)
326 throws SystemException {
327
328 return tagsEntryFinder.findByG_C_N_F(
329 groupId, classNameId, name,
330 TagsEntryConstants.FOLKSONOMY_TAG, start, end);
331 }
332
333 public List<TagsEntry> getEntries(String className, long classPK)
334 throws SystemException {
335
336 return getEntries(
337 className, classPK, TagsEntryConstants.FOLKSONOMY_TAG);
338 }
339
340 public List<TagsEntry> getEntries(
341 String className, long classPK, boolean folksonomy)
342 throws SystemException {
343
344 long classNameId = PortalUtil.getClassNameId(className);
345
346 return getEntries(classNameId, classPK, folksonomy);
347 }
348
349 public int getEntriesSize(long groupId, long classNameId, String name)
350 throws SystemException {
351
352 return tagsEntryFinder.countByG_C_N_F(
353 groupId, classNameId, name, TagsEntryConstants.FOLKSONOMY_TAG);
354 }
355
356 public TagsEntry getEntry(long entryId)
357 throws PortalException, SystemException {
358
359 return tagsEntryPersistence.findByPrimaryKey(entryId);
360 }
361
362 public TagsEntry getEntry(long groupId, String name)
363 throws PortalException, SystemException {
364
365 return getEntry(groupId, name, TagsEntryConstants.FOLKSONOMY_TAG);
366 }
367
368 public TagsEntry getEntry(long groupId, String name, boolean folksonomy)
369 throws PortalException, SystemException {
370
371 return tagsEntryFinder.findByG_N_F(groupId, name, folksonomy);
372 }
373
374 public long[] getEntryIds(long groupId, String[] names)
375 throws PortalException, SystemException {
376
377 return getEntryIds(groupId, names, TagsEntryConstants.FOLKSONOMY_TAG);
378 }
379
380 public long[] getEntryIds(long groupId, String[] names, boolean folksonomy)
381 throws PortalException, SystemException {
382
383 List<Long> entryIds = new ArrayList<Long>(names.length);
384
385 for (String name : names) {
386 try {
387 TagsEntry entry = getEntry(groupId, name, folksonomy);
388
389 entryIds.add(entry.getEntryId());
390 }
391 catch (NoSuchEntryException nsee) {
392 }
393 }
394
395 return ArrayUtil.toArray(entryIds.toArray(new Long[entryIds.size()]));
396 }
397
398 public String[] getEntryNames() throws SystemException {
399 return getEntryNames(TagsEntryConstants.FOLKSONOMY_TAG);
400 }
401
402 public String[] getEntryNames(boolean folksonomy) throws SystemException {
403 return getEntryNames(getEntries(folksonomy));
404 }
405
406 public String[] getEntryNames(long classNameId, long classPK)
407 throws SystemException {
408
409 return getEntryNames(
410 classNameId, classPK, TagsEntryConstants.FOLKSONOMY_TAG);
411 }
412
413 public String[] getEntryNames(
414 long classNameId, long classPK, boolean folksonomy)
415 throws SystemException {
416
417 return getEntryNames(getEntries(classNameId, classPK, folksonomy));
418 }
419
420 public String[] getEntryNames(String className, long classPK)
421 throws SystemException {
422
423 return getEntryNames(
424 className, classPK, TagsEntryConstants.FOLKSONOMY_TAG);
425 }
426
427 public String[] getEntryNames(
428 String className, long classPK, boolean folksonomy)
429 throws SystemException {
430
431 return getEntryNames(getEntries(className, classPK, folksonomy));
432 }
433
434 public List<TagsEntry> getGroupVocabularyEntries(
435 long groupId, String vocabularyName)
436 throws PortalException, SystemException {
437
438 TagsVocabulary vocabulary =
439 tagsVocabularyLocalService.getGroupVocabulary(
440 groupId, vocabularyName);
441
442 return tagsEntryPersistence.findByVocabularyId(
443 vocabulary.getVocabularyId());
444 }
445
446 public List<TagsEntry> getGroupVocabularyEntries(
447 long groupId, String parentEntryName, String vocabularyName)
448 throws PortalException, SystemException {
449
450 TagsVocabulary vocabulary =
451 tagsVocabularyLocalService.getGroupVocabulary(
452 groupId, vocabularyName);
453
454 TagsEntry entry = getEntry(
455 groupId, parentEntryName, vocabulary.isFolksonomy());
456
457 return tagsEntryPersistence.findByP_V(
458 entry.getEntryId(), vocabulary.getVocabularyId());
459 }
460
461 public List<TagsEntry> getGroupVocabularyRootEntries(
462 long groupId, String vocabularyName)
463 throws PortalException, SystemException {
464
465 TagsVocabulary vocabulary =
466 tagsVocabularyLocalService.getGroupVocabulary(
467 groupId, vocabularyName);
468
469 return tagsEntryPersistence.findByP_V(
470 TagsEntryConstants.DEFAULT_PARENT_ENTRY_ID,
471 vocabulary.getVocabularyId());
472 }
473
474 public boolean hasEntry(long groupId, String name, boolean folksonomy)
475 throws PortalException, SystemException {
476
477 try {
478 getEntry(groupId, name, folksonomy);
479
480 return true;
481 }
482 catch (NoSuchEntryException nsee) {
483 return false;
484 }
485 }
486
487 public void mergeEntries(long fromEntryId, long toEntryId)
488 throws PortalException, SystemException {
489
490 List<TagsAsset> assets = tagsEntryPersistence.getTagsAssets(
491 fromEntryId);
492
493 tagsEntryPersistence.addTagsAssets(toEntryId, assets);
494
495 List<TagsProperty> properties = tagsPropertyPersistence.findByEntryId(
496 fromEntryId);
497
498 for (TagsProperty fromProperty : properties) {
499 TagsProperty toProperty = tagsPropertyPersistence.fetchByE_K(
500 toEntryId, fromProperty.getKey());
501
502 if (toProperty == null) {
503 fromProperty.setEntryId(toEntryId);
504
505 tagsPropertyPersistence.update(fromProperty, false);
506 }
507 }
508
509 deleteEntry(fromEntryId);
510 }
511
512 public JSONArray search(
513 long groupId, String name, String[] properties, int start, int end)
514 throws SystemException {
515
516 List<TagsEntry> list = tagsEntryFinder.findByG_N_F_P(
517 groupId, name, TagsEntryConstants.FOLKSONOMY_TAG, properties, start,
518 end);
519
520 return Autocomplete.listToJson(list, "name", "name");
521 }
522
523 public TagsEntry updateEntry(
524 long userId, long entryId, String parentEntryName, String name,
525 String vocabularyName, String[] properties)
526 throws PortalException, SystemException {
527
528
530 if (Validator.isNull(vocabularyName)) {
531 vocabularyName = PropsValues.TAGS_VOCABULARY_DEFAULT;
532 }
533
534 TagsEntry entry = tagsEntryPersistence.findByPrimaryKey(entryId);
535
536 String oldName = entry.getName();
537
538 entry.setModifiedDate(new Date());
539
540 TagsVocabulary vocabulary = null;
541
542 try {
543 vocabulary = tagsVocabularyPersistence.findByG_N(
544 entry.getGroupId(), vocabularyName);
545 }
546 catch (NoSuchVocabularyException nsve) {
547 if (vocabularyName.equals(PropsValues.TAGS_VOCABULARY_DEFAULT)) {
548 ServiceContext vocabularyServiceContext = new ServiceContext();
549
550 vocabularyServiceContext.setAddCommunityPermissions(true);
551 vocabularyServiceContext.setAddGuestPermissions(true);
552 vocabularyServiceContext.setScopeGroupId(entry.getGroupId());
553
554 vocabulary = tagsVocabularyLocalService.addVocabulary(
555 userId, vocabularyName, TagsEntryConstants.FOLKSONOMY_TAG,
556 vocabularyServiceContext);
557 }
558 else {
559 throw nsve;
560 }
561 }
562
563 entry.setVocabularyId(vocabulary.getVocabularyId());
564
565 boolean folksonomy = vocabulary.isFolksonomy();
566
567 name = name.trim();
568
569 if (folksonomy) {
570 name = name.toLowerCase();
571
572 if (!entry.getName().equals(name) &&
573 hasEntry(entry.getGroupId(), name, folksonomy)) {
574
575 throw new DuplicateEntryException(
576 "A tag entry with the name " + name + " already exists");
577 }
578 }
579
580 if (!entry.getName().equals(name)) {
581 try {
582 TagsEntry existingEntry = getEntry(
583 entry.getGroupId(), name, folksonomy);
584
585 if (existingEntry.getEntryId() != entryId) {
586 throw new DuplicateEntryException(
587 "A tag entry with the name " + name +
588 " already exists");
589 }
590 }
591 catch (NoSuchEntryException nsee) {
592 }
593 }
594
595 validate(name);
596
597 entry.setName(name);
598
599 if (Validator.isNotNull(parentEntryName)) {
600 TagsEntry parentEntry = getEntry(
601 entry.getGroupId(), parentEntryName, folksonomy);
602
603 entry.setParentEntryId(parentEntry.getEntryId());
604 }
605 else {
606 entry.setParentEntryId(TagsEntryConstants.DEFAULT_PARENT_ENTRY_ID);
607 }
608
609 tagsEntryPersistence.update(entry, false);
610
611
613 List<TagsProperty> oldProperties =
614 tagsPropertyPersistence.findByEntryId(entryId);
615
616 for (TagsProperty property : oldProperties) {
617 tagsPropertyLocalService.deleteProperty(property);
618 }
619
620 for (int i = 0; i < properties.length; i++) {
621 String[] property = StringUtil.split(
622 properties[i], StringPool.COLON);
623
624 String key = StringPool.BLANK;
625
626 if (property.length > 0) {
627 key = GetterUtil.getString(property[0]);
628 }
629
630 String value = StringPool.BLANK;
631
632 if (property.length > 1) {
633 value = GetterUtil.getString(property[1]);
634 }
635
636 if (Validator.isNotNull(key)) {
637 tagsPropertyLocalService.addProperty(
638 userId, entryId, key, value);
639 }
640 }
641
642
644 if (!oldName.equals(name)) {
645 List<TagsAsset> assets = tagsEntryPersistence.getTagsAssets(
646 entry.getEntryId());
647
648 reIndex(assets);
649 }
650
651 return entry;
652 }
653
654 protected String[] getEntryNames(List <TagsEntry>entries) {
655 return StringUtil.split(ListUtil.toString(entries, "name"));
656 }
657
658 protected void reIndex(List<TagsAsset> assets) throws PortalException {
659 for (TagsAsset asset : assets) {
660 String className = PortalUtil.getClassName(asset.getClassNameId());
661
662 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
663
664 indexer.reIndex(className, asset.getClassPK());
665 }
666 }
667
668 protected void validate(String name) throws PortalException {
669 if (!TagsUtil.isValidWord(name)) {
670 throw new TagsEntryException(TagsEntryException.INVALID_CHARACTER);
671 }
672 }
673
674 }