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