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