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