1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.bookmarks.service.impl;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.search.BooleanClauseOccur;
30  import com.liferay.portal.kernel.search.BooleanQuery;
31  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
32  import com.liferay.portal.kernel.search.Field;
33  import com.liferay.portal.kernel.search.Hits;
34  import com.liferay.portal.kernel.search.SearchEngineUtil;
35  import com.liferay.portal.kernel.search.TermQuery;
36  import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
37  import com.liferay.portal.kernel.util.GetterUtil;
38  import com.liferay.portal.kernel.util.Validator;
39  import com.liferay.portal.model.ResourceConstants;
40  import com.liferay.portal.model.User;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portlet.bookmarks.FolderNameException;
43  import com.liferay.portlet.bookmarks.model.BookmarksEntry;
44  import com.liferay.portlet.bookmarks.model.BookmarksFolder;
45  import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderImpl;
46  import com.liferay.portlet.bookmarks.service.base.BookmarksFolderLocalServiceBaseImpl;
47  import com.liferay.portlet.bookmarks.util.Indexer;
48  
49  import java.util.ArrayList;
50  import java.util.Date;
51  import java.util.List;
52  
53  /**
54   * <a href="BookmarksFolderLocalServiceImpl.java.html"><b><i>View Source</i></b>
55   * </a>
56   *
57   * @author Brian Wing Shun Chan
58   *
59   */
60  public class BookmarksFolderLocalServiceImpl
61      extends BookmarksFolderLocalServiceBaseImpl {
62  
63      public BookmarksFolder addFolder(
64              long userId, long plid, long parentFolderId, String name,
65              String description, boolean addCommunityPermissions,
66              boolean addGuestPermissions)
67          throws PortalException, SystemException {
68  
69          return addFolder(
70              null, userId, plid, parentFolderId, name, description,
71              Boolean.valueOf(addCommunityPermissions),
72              Boolean.valueOf(addGuestPermissions), null, null);
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              long userId, long plid, long parentFolderId, String name,
89              String description, String[] communityPermissions,
90              String[] guestPermissions)
91          throws PortalException, SystemException {
92  
93          return addFolder(
94              null, userId, plid, parentFolderId, name, description, null, null,
95              communityPermissions, guestPermissions);
96      }
97  
98      public BookmarksFolder addFolder(
99              String uuid, long userId, long plid, long parentFolderId,
100             String name, String description, Boolean addCommunityPermissions,
101             Boolean addGuestPermissions, String[] communityPermissions,
102             String[] guestPermissions)
103         throws PortalException, SystemException {
104 
105         // Folder
106 
107         User user = userPersistence.findByPrimaryKey(userId);
108         long groupId = PortalUtil.getScopeGroupId(plid);
109         parentFolderId = getParentFolderId(groupId, parentFolderId);
110         Date now = new Date();
111 
112         validate(name);
113 
114         long folderId = counterLocalService.increment();
115 
116         BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
117 
118         folder.setUuid(uuid);
119         folder.setGroupId(groupId);
120         folder.setCompanyId(user.getCompanyId());
121         folder.setUserId(user.getUserId());
122         folder.setCreateDate(now);
123         folder.setModifiedDate(now);
124         folder.setParentFolderId(parentFolderId);
125         folder.setName(name);
126         folder.setDescription(description);
127 
128         bookmarksFolderPersistence.update(folder, false);
129 
130         // Resources
131 
132         if ((addCommunityPermissions != null) &&
133             (addGuestPermissions != null)) {
134 
135             addFolderResources(
136                 folder, addCommunityPermissions.booleanValue(),
137                 addGuestPermissions.booleanValue());
138         }
139         else {
140             addFolderResources(folder, communityPermissions, guestPermissions);
141         }
142 
143         return folder;
144     }
145 
146     public void addFolderResources(
147             long folderId, boolean addCommunityPermissions,
148             boolean addGuestPermissions)
149         throws PortalException, SystemException {
150 
151         BookmarksFolder folder =
152             bookmarksFolderPersistence.findByPrimaryKey(folderId);
153 
154         addFolderResources(
155             folder, addCommunityPermissions, addGuestPermissions);
156     }
157 
158     public void addFolderResources(
159             BookmarksFolder folder, boolean addCommunityPermissions,
160             boolean addGuestPermissions)
161         throws PortalException, SystemException {
162 
163         resourceLocalService.addResources(
164             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
165             BookmarksFolder.class.getName(), folder.getFolderId(), false,
166             addCommunityPermissions, addGuestPermissions);
167     }
168 
169     public void addFolderResources(
170             long folderId, String[] communityPermissions,
171             String[] guestPermissions)
172         throws PortalException, SystemException {
173 
174         BookmarksFolder folder =
175             bookmarksFolderPersistence.findByPrimaryKey(folderId);
176 
177         addFolderResources(folder, communityPermissions, guestPermissions);
178     }
179 
180     public void addFolderResources(
181             BookmarksFolder folder, String[] communityPermissions,
182             String[] guestPermissions)
183         throws PortalException, SystemException {
184 
185         resourceLocalService.addModelResources(
186             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
187             BookmarksFolder.class.getName(), folder.getFolderId(),
188             communityPermissions, guestPermissions);
189     }
190 
191     public void deleteFolder(long folderId)
192         throws PortalException, SystemException {
193 
194         BookmarksFolder folder =
195             bookmarksFolderPersistence.findByPrimaryKey(folderId);
196 
197         deleteFolder(folder);
198     }
199 
200     public void deleteFolder(BookmarksFolder folder)
201         throws PortalException, SystemException {
202 
203         // Folders
204 
205         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
206             folder.getGroupId(), folder.getFolderId());
207 
208         for (BookmarksFolder curFolder : folders) {
209             deleteFolder(curFolder);
210         }
211 
212         // Entries
213 
214         bookmarksEntryLocalService.deleteEntries(folder.getFolderId());
215 
216         // Resources
217 
218         resourceLocalService.deleteResource(
219             folder.getCompanyId(), BookmarksFolder.class.getName(),
220             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
221 
222         // Folder
223 
224         bookmarksFolderPersistence.remove(folder);
225     }
226 
227     public void deleteFolders(long groupId)
228         throws PortalException, SystemException {
229 
230         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
231             groupId, BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID);
232 
233         for (BookmarksFolder folder : folders) {
234             deleteFolder(folder);
235         }
236     }
237 
238     public BookmarksFolder getFolder(long folderId)
239         throws PortalException, SystemException {
240 
241         return bookmarksFolderPersistence.findByPrimaryKey(folderId);
242     }
243 
244     public List<BookmarksFolder> getFolders(
245             long groupId, long parentFolderId, int start, int end)
246         throws SystemException {
247 
248         return bookmarksFolderPersistence.findByG_P(
249             groupId, parentFolderId, start, end);
250     }
251 
252     public int getFoldersCount(long groupId, long parentFolderId)
253         throws SystemException {
254 
255         return bookmarksFolderPersistence.countByG_P(groupId, parentFolderId);
256     }
257 
258     public void getSubfolderIds(
259             List<Long> folderIds, long groupId, long folderId)
260         throws SystemException {
261 
262         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
263             groupId, folderId);
264 
265         for (BookmarksFolder folder : folders) {
266             folderIds.add(folder.getFolderId());
267 
268             getSubfolderIds(
269                 folderIds, folder.getGroupId(), folder.getFolderId());
270         }
271     }
272 
273     public void reIndex(String[] ids) throws SystemException {
274         if (SearchEngineUtil.isIndexReadOnly()) {
275             return;
276         }
277 
278         long companyId = GetterUtil.getLong(ids[0]);
279 
280         try {
281             reIndexFolders(companyId);
282         }
283         catch (SystemException se) {
284             throw se;
285         }
286         catch (Exception e) {
287             throw new SystemException(e);
288         }
289     }
290 
291     public Hits search(
292             long companyId, long groupId, long[] folderIds, String keywords,
293             int start, int end)
294         throws SystemException {
295 
296         try {
297             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
298 
299             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
300 
301             if (groupId > 0) {
302                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
303             }
304 
305             if ((folderIds != null) && (folderIds.length > 0)) {
306                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
307 
308                 for (long folderId : folderIds) {
309                     TermQuery termQuery = TermQueryFactoryUtil.create(
310                         "folderId", folderId);
311 
312                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
313                 }
314 
315                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
316             }
317 
318             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
319 
320             if (Validator.isNotNull(keywords)) {
321                 searchQuery.addTerm(Field.TITLE, keywords);
322                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
323                 searchQuery.addTerm(Field.URL, keywords);
324                 searchQuery.addTerm(Field.COMMENTS, keywords);
325             }
326 
327             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
328 
329             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
330 
331             if (searchQuery.clauses().size() > 0) {
332                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
333             }
334 
335             return SearchEngineUtil.search(companyId, fullQuery, start, end);
336         }
337         catch (Exception e) {
338             throw new SystemException(e);
339         }
340     }
341 
342     public BookmarksFolder updateFolder(
343             long folderId, long parentFolderId, String name,
344             String description, boolean mergeWithParentFolder)
345         throws PortalException, SystemException {
346 
347         // Folder
348 
349         BookmarksFolder folder =
350             bookmarksFolderPersistence.findByPrimaryKey(folderId);
351 
352         parentFolderId = getParentFolderId(folder, parentFolderId);
353 
354         validate(name);
355 
356         folder.setModifiedDate(new Date());
357         folder.setParentFolderId(parentFolderId);
358         folder.setName(name);
359         folder.setDescription(description);
360 
361         bookmarksFolderPersistence.update(folder, false);
362 
363         // Merge folders
364 
365         if (mergeWithParentFolder && (folderId != parentFolderId) &&
366             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
367 
368             mergeFolders(folder, parentFolderId);
369         }
370 
371         return folder;
372     }
373 
374     protected long getParentFolderId(long groupId, long parentFolderId)
375         throws SystemException {
376 
377         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
378             BookmarksFolder parentFolder =
379                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
380 
381             if ((parentFolder == null) ||
382                 (groupId != parentFolder.getGroupId())) {
383 
384                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
385             }
386         }
387 
388         return parentFolderId;
389     }
390 
391     protected long getParentFolderId(
392             BookmarksFolder folder, long parentFolderId)
393         throws SystemException {
394 
395         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
396             return parentFolderId;
397         }
398 
399         if (folder.getFolderId() == parentFolderId) {
400             return folder.getParentFolderId();
401         }
402         else {
403             BookmarksFolder parentFolder =
404                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
405 
406             if ((parentFolder == null) ||
407                 (folder.getGroupId() != parentFolder.getGroupId())) {
408 
409                 return folder.getParentFolderId();
410             }
411 
412             List<Long> subfolderIds = new ArrayList<Long>();
413 
414             getSubfolderIds(
415                 subfolderIds, folder.getGroupId(), folder.getFolderId());
416 
417             if (subfolderIds.contains(parentFolderId)) {
418                 return folder.getParentFolderId();
419             }
420 
421             return parentFolderId;
422         }
423     }
424 
425     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
426         throws PortalException, SystemException {
427 
428         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
429                 fromFolder.getGroupId(), fromFolder.getFolderId());
430 
431         for (BookmarksFolder folder : folders) {
432             mergeFolders(folder, toFolderId);
433         }
434 
435         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
436             fromFolder.getFolderId());
437 
438         for (BookmarksEntry entry : entries) {
439             entry.setFolderId(toFolderId);
440 
441             bookmarksEntryPersistence.update(entry, false);
442         }
443 
444         deleteFolder(fromFolder);
445     }
446 
447     protected void reIndexFolders(long companyId) throws SystemException {
448         int folderCount = bookmarksFolderPersistence.countByCompanyId(
449             companyId);
450 
451         int folderPages = folderCount / Indexer.DEFAULT_INTERVAL;
452 
453         for (int i = 0; i <= folderPages; i++) {
454             int folderStart = (i * Indexer.DEFAULT_INTERVAL);
455             int folderEnd = folderStart + Indexer.DEFAULT_INTERVAL;
456 
457             reIndexFolders(companyId, folderStart, folderEnd);
458         }
459     }
460 
461     protected void reIndexFolders(
462             long companyId, int folderStart, int folderEnd)
463         throws SystemException {
464 
465         List<BookmarksFolder> folders =
466             bookmarksFolderPersistence.findByCompanyId(
467                 companyId, folderStart, folderEnd);
468 
469         for (BookmarksFolder folder : folders) {
470             long folderId = folder.getFolderId();
471 
472             int entryCount = bookmarksEntryPersistence.countByFolderId(
473                 folderId);
474 
475             int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
476 
477             for (int i = 0; i <= entryPages; i++) {
478                 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
479                 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
480 
481                 reIndexEntries(folderId, entryStart, entryEnd);
482             }
483         }
484     }
485 
486     protected void reIndexEntries(long folderId, int entryStart, int entryEnd)
487         throws SystemException {
488 
489         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
490             folderId, entryStart, entryEnd);
491 
492         for (BookmarksEntry entry : entries) {
493             bookmarksEntryLocalService.reIndex(entry);
494         }
495     }
496 
497     protected void validate(String name) throws PortalException {
498         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
499             (name.indexOf("//") != -1)) {
500 
501             throw new FolderNameException();
502         }
503     }
504 
505     private static Log _log =
506         LogFactoryUtil.getLog(BookmarksFolderLocalServiceImpl.class);
507 
508 }