1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portlet.bookmarks.service.impl;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.SystemException;
19  import com.liferay.portal.kernel.search.BooleanClauseOccur;
20  import com.liferay.portal.kernel.search.BooleanQuery;
21  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
22  import com.liferay.portal.kernel.search.Field;
23  import com.liferay.portal.kernel.search.Hits;
24  import com.liferay.portal.kernel.search.SearchEngineUtil;
25  import com.liferay.portal.kernel.search.TermQuery;
26  import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.Validator;
29  import com.liferay.portal.model.Group;
30  import com.liferay.portal.model.ResourceConstants;
31  import com.liferay.portal.model.User;
32  import com.liferay.portal.service.ServiceContext;
33  import com.liferay.portlet.bookmarks.FolderNameException;
34  import com.liferay.portlet.bookmarks.model.BookmarksEntry;
35  import com.liferay.portlet.bookmarks.model.BookmarksFolder;
36  import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderImpl;
37  import com.liferay.portlet.bookmarks.service.base.BookmarksFolderLocalServiceBaseImpl;
38  import com.liferay.portlet.bookmarks.util.Indexer;
39  
40  import java.util.ArrayList;
41  import java.util.Date;
42  import java.util.List;
43  
44  /**
45   * <a href="BookmarksFolderLocalServiceImpl.java.html"><b><i>View Source</i></b>
46   * </a>
47   *
48   * @author Brian Wing Shun Chan
49   */
50  public class BookmarksFolderLocalServiceImpl
51      extends BookmarksFolderLocalServiceBaseImpl {
52  
53      public BookmarksFolder addFolder(
54              long userId, long parentFolderId, String name, String description,
55              ServiceContext serviceContext)
56          throws PortalException, SystemException {
57  
58          return addFolder(
59              null, userId, parentFolderId, name, description, serviceContext);
60      }
61  
62      public BookmarksFolder addFolder(
63              String uuid, long userId, long parentFolderId, String name,
64              String description, ServiceContext serviceContext)
65          throws PortalException, SystemException {
66  
67          // Folder
68  
69          User user = userPersistence.findByPrimaryKey(userId);
70          long groupId = serviceContext.getScopeGroupId();
71          parentFolderId = getParentFolderId(groupId, parentFolderId);
72          Date now = new Date();
73  
74          validate(name);
75  
76          long folderId = counterLocalService.increment();
77  
78          BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
79  
80          folder.setUuid(uuid);
81          folder.setGroupId(groupId);
82          folder.setCompanyId(user.getCompanyId());
83          folder.setUserId(user.getUserId());
84          folder.setCreateDate(serviceContext.getCreateDate(now));
85          folder.setModifiedDate(serviceContext.getModifiedDate(now));
86          folder.setParentFolderId(parentFolderId);
87          folder.setName(name);
88          folder.setDescription(description);
89          folder.setExpandoBridgeAttributes(serviceContext);
90  
91          bookmarksFolderPersistence.update(folder, false);
92  
93          // Resources
94  
95          if (serviceContext.getAddCommunityPermissions() ||
96              serviceContext.getAddGuestPermissions()) {
97  
98              addFolderResources(
99                  folder, serviceContext.getAddCommunityPermissions(),
100                 serviceContext.getAddGuestPermissions());
101         }
102         else {
103             addFolderResources(
104                 folder, serviceContext.getCommunityPermissions(),
105                 serviceContext.getGuestPermissions());
106         }
107 
108         return folder;
109     }
110 
111     public void addFolderResources(
112             BookmarksFolder folder, boolean addCommunityPermissions,
113             boolean addGuestPermissions)
114         throws PortalException, SystemException {
115 
116         resourceLocalService.addResources(
117             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
118             BookmarksFolder.class.getName(), folder.getFolderId(), false,
119             addCommunityPermissions, addGuestPermissions);
120     }
121 
122     public void addFolderResources(
123             BookmarksFolder folder, String[] communityPermissions,
124             String[] guestPermissions)
125         throws PortalException, SystemException {
126 
127         resourceLocalService.addModelResources(
128             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
129             BookmarksFolder.class.getName(), folder.getFolderId(),
130             communityPermissions, guestPermissions);
131     }
132 
133     public void addFolderResources(
134             long folderId, boolean addCommunityPermissions,
135             boolean addGuestPermissions)
136         throws PortalException, SystemException {
137 
138         BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
139             folderId);
140 
141         addFolderResources(
142             folder, addCommunityPermissions, addGuestPermissions);
143     }
144 
145     public void addFolderResources(
146             long folderId, String[] communityPermissions,
147             String[] guestPermissions)
148         throws PortalException, SystemException {
149 
150         BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
151             folderId);
152 
153         addFolderResources(folder, communityPermissions, guestPermissions);
154     }
155 
156     public void deleteFolder(BookmarksFolder folder)
157         throws PortalException, SystemException {
158 
159         // Folders
160 
161         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
162             folder.getGroupId(), folder.getFolderId());
163 
164         for (BookmarksFolder curFolder : folders) {
165             deleteFolder(curFolder);
166         }
167 
168         // Folder
169 
170         bookmarksFolderPersistence.remove(folder);
171 
172         // Resources
173 
174         resourceLocalService.deleteResource(
175             folder.getCompanyId(), BookmarksFolder.class.getName(),
176             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
177 
178         // Entries
179 
180         bookmarksEntryLocalService.deleteEntries(folder.getFolderId());
181 
182         // Expando
183 
184         expandoValueLocalService.deleteValues(
185             BookmarksFolder.class.getName(), folder.getFolderId());
186     }
187 
188     public void deleteFolder(long folderId)
189         throws PortalException, SystemException {
190 
191         BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
192             folderId);
193 
194         deleteFolder(folder);
195     }
196 
197     public void deleteFolders(long groupId)
198         throws PortalException, SystemException {
199 
200         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
201             groupId, BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID);
202 
203         for (BookmarksFolder folder : folders) {
204             deleteFolder(folder);
205         }
206     }
207 
208     public BookmarksFolder getFolder(long folderId)
209         throws PortalException, SystemException {
210 
211         return bookmarksFolderPersistence.findByPrimaryKey(folderId);
212     }
213 
214     public List<BookmarksFolder> getFolders(
215             long groupId, long parentFolderId, int start, int end)
216         throws SystemException {
217 
218         return bookmarksFolderPersistence.findByG_P(
219             groupId, parentFolderId, start, end);
220     }
221 
222     public int getFoldersCount(long groupId, long parentFolderId)
223         throws SystemException {
224 
225         return bookmarksFolderPersistence.countByG_P(groupId, parentFolderId);
226     }
227 
228     public void getSubfolderIds(
229             List<Long> folderIds, long groupId, long folderId)
230         throws SystemException {
231 
232         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
233             groupId, folderId);
234 
235         for (BookmarksFolder folder : folders) {
236             folderIds.add(folder.getFolderId());
237 
238             getSubfolderIds(
239                 folderIds, folder.getGroupId(), folder.getFolderId());
240         }
241     }
242 
243     public void reIndex(String[] ids) throws SystemException {
244         if (SearchEngineUtil.isIndexReadOnly()) {
245             return;
246         }
247 
248         long companyId = GetterUtil.getLong(ids[0]);
249 
250         try {
251             reIndexFolders(companyId);
252         }
253         catch (SystemException se) {
254             throw se;
255         }
256         catch (Exception e) {
257             throw new SystemException(e);
258         }
259     }
260 
261     public Hits search(
262             long companyId, long groupId, long userId, long[] folderIds,
263             String keywords, int start, int end)
264         throws SystemException {
265 
266         try {
267             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
268 
269             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
270 
271             if (groupId > 0) {
272                 Group group = groupLocalService.getGroup(groupId);
273 
274                 if (group.isLayout()) {
275                     contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
276 
277                     groupId = group.getParentGroupId();
278                 }
279 
280                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
281             }
282 
283             if ((folderIds != null) && (folderIds.length > 0)) {
284                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
285 
286                 for (long folderId : folderIds) {
287                     if (userId > 0) {
288                         try {
289                             bookmarksFolderService.getFolder(folderId);
290                         }
291                         catch (Exception e) {
292                             continue;
293                         }
294                     }
295 
296                     TermQuery termQuery = TermQueryFactoryUtil.create(
297                         "folderId", folderId);
298 
299                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
300                 }
301 
302                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
303             }
304 
305             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
306 
307             searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
308 
309             searchQuery.addExactTerm(Field.TAGS_ENTRIES, keywords);
310 
311             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
312 
313             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
314 
315             if (searchQuery.clauses().size() > 0) {
316                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
317             }
318 
319             return SearchEngineUtil.search(
320                 companyId, groupId, userId, BookmarksEntry.class.getName(),
321                 fullQuery, start, end);
322         }
323         catch (Exception e) {
324             throw new SystemException(e);
325         }
326     }
327 
328     public BookmarksFolder updateFolder(
329             long folderId, long parentFolderId, String name,
330             String description, boolean mergeWithParentFolder,
331             ServiceContext serviceContext)
332         throws PortalException, SystemException {
333 
334         // Merge folders
335 
336         BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
337             folderId);
338 
339         parentFolderId = getParentFolderId(folder, parentFolderId);
340 
341         if (mergeWithParentFolder && (folderId != parentFolderId) &&
342             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
343 
344             mergeFolders(folder, parentFolderId);
345 
346             return folder;
347         }
348 
349         // Folder
350 
351         validate(name);
352 
353         folder.setModifiedDate(serviceContext.getModifiedDate(null));
354         folder.setParentFolderId(parentFolderId);
355         folder.setName(name);
356         folder.setDescription(description);
357         folder.setExpandoBridgeAttributes(serviceContext);
358 
359         bookmarksFolderPersistence.update(folder, false);
360 
361         return folder;
362     }
363 
364     protected long getParentFolderId(
365             BookmarksFolder folder, long parentFolderId)
366         throws SystemException {
367 
368         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
369             return parentFolderId;
370         }
371 
372         if (folder.getFolderId() == parentFolderId) {
373             return folder.getParentFolderId();
374         }
375         else {
376             BookmarksFolder parentFolder =
377                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
378 
379             if ((parentFolder == null) ||
380                 (folder.getGroupId() != parentFolder.getGroupId())) {
381 
382                 return folder.getParentFolderId();
383             }
384 
385             List<Long> subfolderIds = new ArrayList<Long>();
386 
387             getSubfolderIds(
388                 subfolderIds, folder.getGroupId(), folder.getFolderId());
389 
390             if (subfolderIds.contains(parentFolderId)) {
391                 return folder.getParentFolderId();
392             }
393 
394             return parentFolderId;
395         }
396     }
397 
398     protected long getParentFolderId(long groupId, long parentFolderId)
399         throws SystemException {
400 
401         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
402             BookmarksFolder parentFolder =
403                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
404 
405             if ((parentFolder == null) ||
406                 (groupId != parentFolder.getGroupId())) {
407 
408                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
409             }
410         }
411 
412         return parentFolderId;
413     }
414 
415     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
416         throws PortalException, SystemException {
417 
418         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
419                 fromFolder.getGroupId(), fromFolder.getFolderId());
420 
421         for (BookmarksFolder folder : folders) {
422             mergeFolders(folder, toFolderId);
423         }
424 
425         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
426             fromFolder.getFolderId());
427 
428         for (BookmarksEntry entry : entries) {
429             entry.setFolderId(toFolderId);
430 
431             bookmarksEntryPersistence.update(entry, false);
432 
433             bookmarksEntryLocalService.reIndex(entry);
434         }
435 
436         deleteFolder(fromFolder);
437     }
438 
439     protected void reIndexEntries(long folderId, int entryStart, int entryEnd)
440         throws SystemException {
441 
442         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
443             folderId, entryStart, entryEnd);
444 
445         for (BookmarksEntry entry : entries) {
446             bookmarksEntryLocalService.reIndex(entry);
447         }
448     }
449 
450     protected void reIndexFolders(long companyId) throws SystemException {
451         int folderCount = bookmarksFolderPersistence.countByCompanyId(
452             companyId);
453 
454         int folderPages = folderCount / Indexer.DEFAULT_INTERVAL;
455 
456         for (int i = 0; i <= folderPages; i++) {
457             int folderStart = (i * Indexer.DEFAULT_INTERVAL);
458             int folderEnd = folderStart + Indexer.DEFAULT_INTERVAL;
459 
460             reIndexFolders(companyId, folderStart, folderEnd);
461         }
462     }
463 
464     protected void reIndexFolders(
465             long companyId, int folderStart, int folderEnd)
466         throws SystemException {
467 
468         List<BookmarksFolder> folders =
469             bookmarksFolderPersistence.findByCompanyId(
470                 companyId, folderStart, folderEnd);
471 
472         for (BookmarksFolder folder : folders) {
473             long folderId = folder.getFolderId();
474 
475             int entryCount = bookmarksEntryPersistence.countByFolderId(
476                 folderId);
477 
478             int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
479 
480             for (int i = 0; i <= entryPages; i++) {
481                 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
482                 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
483 
484                 reIndexEntries(folderId, entryStart, entryEnd);
485             }
486         }
487     }
488 
489     protected void validate(String name) throws PortalException {
490         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
491             (name.indexOf("//") != -1)) {
492 
493             throw new FolderNameException();
494         }
495     }
496 
497     private static final String[] _KEYWORDS_FIELDS = {
498         Field.COMMENTS, Field.TITLE, Field.URL
499     };
500 
501 }