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