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