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