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.Document;
28  import com.liferay.portal.kernel.search.Field;
29  import com.liferay.portal.kernel.search.Hits;
30  import com.liferay.portal.kernel.search.SearchEngineUtil;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.model.ResourceConstants;
34  import com.liferay.portal.model.User;
35  import com.liferay.portal.search.lucene.LuceneUtil;
36  import com.liferay.portal.util.PortalUtil;
37  import com.liferay.portlet.bookmarks.FolderNameException;
38  import com.liferay.portlet.bookmarks.model.BookmarksEntry;
39  import com.liferay.portlet.bookmarks.model.BookmarksFolder;
40  import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderImpl;
41  import com.liferay.portlet.bookmarks.service.base.BookmarksFolderLocalServiceBaseImpl;
42  import com.liferay.portlet.bookmarks.util.Indexer;
43  
44  import java.util.ArrayList;
45  import java.util.Date;
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.index.Term;
51  import org.apache.lucene.search.BooleanClause;
52  import org.apache.lucene.search.BooleanQuery;
53  import org.apache.lucene.search.TermQuery;
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.getPortletGroupId(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.getFolderId());
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                         Document doc = Indexer.getEntryDocument(
304                             companyId, groupId, folderId, entryId, name,
305                             url, comments, tagsEntries);
306 
307                         SearchEngineUtil.addDocument(companyId, doc);
308                     }
309                     catch (Exception e1) {
310                         _log.error("Reindexing " + entryId, e1);
311                     }
312                 }
313             }
314         }
315         catch (SystemException se) {
316             throw se;
317         }
318         catch (Exception e2) {
319             throw new SystemException(e2);
320         }
321     }
322 
323     public Hits search(
324             long companyId, long groupId, long[] folderIds, String keywords,
325             int start, int end)
326         throws SystemException {
327 
328         try {
329             BooleanQuery contextQuery = new BooleanQuery();
330 
331             LuceneUtil.addRequiredTerm(
332                 contextQuery, Field.PORTLET_ID, Indexer.PORTLET_ID);
333 
334             if (groupId > 0) {
335                 LuceneUtil.addRequiredTerm(
336                     contextQuery, Field.GROUP_ID, groupId);
337             }
338 
339             if ((folderIds != null) && (folderIds.length > 0)) {
340                 BooleanQuery folderIdsQuery = new BooleanQuery();
341 
342                 for (int i = 0; i < folderIds.length; i++) {
343                     Term term = new Term(
344                         "folderId", String.valueOf(folderIds[i]));
345                     TermQuery termQuery = new TermQuery(term);
346 
347                     folderIdsQuery.add(termQuery, BooleanClause.Occur.SHOULD);
348                 }
349 
350                 contextQuery.add(folderIdsQuery, BooleanClause.Occur.MUST);
351             }
352 
353             BooleanQuery searchQuery = new BooleanQuery();
354 
355             if (Validator.isNotNull(keywords)) {
356                 LuceneUtil.addTerm(searchQuery, Field.NAME, keywords);
357                 LuceneUtil.addTerm(searchQuery, Field.URL, keywords);
358                 LuceneUtil.addTerm(searchQuery, Field.COMMENTS, keywords);
359                 LuceneUtil.addTerm(searchQuery, Field.TAGS_ENTRIES, keywords);
360             }
361 
362             BooleanQuery fullQuery = new BooleanQuery();
363 
364             fullQuery.add(contextQuery, BooleanClause.Occur.MUST);
365 
366             if (searchQuery.clauses().size() > 0) {
367                 fullQuery.add(searchQuery, BooleanClause.Occur.MUST);
368             }
369 
370             return SearchEngineUtil.search(
371                 companyId, fullQuery.toString(), start, end);
372         }
373         catch (Exception e) {
374             throw new SystemException(e);
375         }
376     }
377 
378     public BookmarksFolder updateFolder(
379             long folderId, long parentFolderId, String name,
380             String description, boolean mergeWithParentFolder)
381         throws PortalException, SystemException {
382 
383         // Folder
384 
385         BookmarksFolder folder =
386             bookmarksFolderPersistence.findByPrimaryKey(folderId);
387 
388         parentFolderId = getParentFolderId(folder, parentFolderId);
389 
390         validate(name);
391 
392         folder.setModifiedDate(new Date());
393         folder.setParentFolderId(parentFolderId);
394         folder.setName(name);
395         folder.setDescription(description);
396 
397         bookmarksFolderPersistence.update(folder, false);
398 
399         // Merge folders
400 
401         if (mergeWithParentFolder && (folderId != parentFolderId) &&
402             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
403 
404             mergeFolders(folder, parentFolderId);
405         }
406 
407         return folder;
408     }
409 
410     protected long getParentFolderId(long groupId, long parentFolderId)
411         throws SystemException {
412 
413         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
414             BookmarksFolder parentFolder =
415                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
416 
417             if ((parentFolder == null) ||
418                 (groupId != parentFolder.getGroupId())) {
419 
420                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
421             }
422         }
423 
424         return parentFolderId;
425     }
426 
427     protected long getParentFolderId(
428             BookmarksFolder folder, long parentFolderId)
429         throws SystemException {
430 
431         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
432             return parentFolderId;
433         }
434 
435         if (folder.getFolderId() == parentFolderId) {
436             return folder.getParentFolderId();
437         }
438         else {
439             BookmarksFolder parentFolder =
440                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
441 
442             if ((parentFolder == null) ||
443                 (folder.getGroupId() != parentFolder.getGroupId())) {
444 
445                 return folder.getParentFolderId();
446             }
447 
448             List<Long> subfolderIds = new ArrayList<Long>();
449 
450             getSubfolderIds(
451                 subfolderIds, folder.getGroupId(), folder.getFolderId());
452 
453             if (subfolderIds.contains(parentFolderId)) {
454                 return folder.getParentFolderId();
455             }
456 
457             return parentFolderId;
458         }
459     }
460 
461     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
462         throws PortalException, SystemException {
463 
464         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
465                 fromFolder.getGroupId(), fromFolder.getFolderId());
466 
467         for (BookmarksFolder folder : folders) {
468             mergeFolders(folder, toFolderId);
469         }
470 
471         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
472             fromFolder.getFolderId());
473 
474         for (BookmarksEntry entry : entries) {
475             entry.setFolderId(toFolderId);
476 
477             bookmarksEntryPersistence.update(entry, false);
478         }
479 
480         bookmarksFolderPersistence.remove(fromFolder.getFolderId());
481     }
482 
483     protected void validate(String name) throws PortalException {
484         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
485             (name.indexOf("//") != -1)) {
486 
487             throw new FolderNameException();
488         }
489     }
490 
491     private static Log _log =
492         LogFactory.getLog(BookmarksFolderLocalServiceImpl.class);
493 
494 }