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.Document;
31  import com.liferay.portal.kernel.search.Field;
32  import com.liferay.portal.kernel.search.Hits;
33  import com.liferay.portal.kernel.search.SearchEngineUtil;
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.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 = BooleanQueryFactoryUtil.create();
330 
331             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
332 
333             if (groupId > 0) {
334                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
335             }
336 
337             if ((folderIds != null) && (folderIds.length > 0)) {
338                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
339 
340                 for (long folderId : folderIds) {
341                     TermQuery termQuery = TermQueryFactoryUtil.create(
342                         "folderId", folderId);
343 
344                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
345                 }
346 
347                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
348             }
349 
350             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
351 
352             if (Validator.isNotNull(keywords)) {
353                 searchQuery.addTerm(Field.NAME, keywords);
354                 searchQuery.addTerm(Field.URL, keywords);
355                 searchQuery.addTerm(Field.COMMENTS, keywords);
356                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords);
357             }
358 
359             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
360 
361             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
362 
363             if (searchQuery.clauses().size() > 0) {
364                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
365             }
366 
367             return SearchEngineUtil.search(companyId, fullQuery, start, end);
368         }
369         catch (Exception e) {
370             throw new SystemException(e);
371         }
372     }
373 
374     public BookmarksFolder updateFolder(
375             long folderId, long parentFolderId, String name,
376             String description, boolean mergeWithParentFolder)
377         throws PortalException, SystemException {
378 
379         // Folder
380 
381         BookmarksFolder folder =
382             bookmarksFolderPersistence.findByPrimaryKey(folderId);
383 
384         parentFolderId = getParentFolderId(folder, parentFolderId);
385 
386         validate(name);
387 
388         folder.setModifiedDate(new Date());
389         folder.setParentFolderId(parentFolderId);
390         folder.setName(name);
391         folder.setDescription(description);
392 
393         bookmarksFolderPersistence.update(folder, false);
394 
395         // Merge folders
396 
397         if (mergeWithParentFolder && (folderId != parentFolderId) &&
398             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
399 
400             mergeFolders(folder, parentFolderId);
401         }
402 
403         return folder;
404     }
405 
406     protected long getParentFolderId(long groupId, long parentFolderId)
407         throws SystemException {
408 
409         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
410             BookmarksFolder parentFolder =
411                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
412 
413             if ((parentFolder == null) ||
414                 (groupId != parentFolder.getGroupId())) {
415 
416                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
417             }
418         }
419 
420         return parentFolderId;
421     }
422 
423     protected long getParentFolderId(
424             BookmarksFolder folder, long parentFolderId)
425         throws SystemException {
426 
427         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
428             return parentFolderId;
429         }
430 
431         if (folder.getFolderId() == parentFolderId) {
432             return folder.getParentFolderId();
433         }
434         else {
435             BookmarksFolder parentFolder =
436                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
437 
438             if ((parentFolder == null) ||
439                 (folder.getGroupId() != parentFolder.getGroupId())) {
440 
441                 return folder.getParentFolderId();
442             }
443 
444             List<Long> subfolderIds = new ArrayList<Long>();
445 
446             getSubfolderIds(
447                 subfolderIds, folder.getGroupId(), folder.getFolderId());
448 
449             if (subfolderIds.contains(parentFolderId)) {
450                 return folder.getParentFolderId();
451             }
452 
453             return parentFolderId;
454         }
455     }
456 
457     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
458         throws PortalException, SystemException {
459 
460         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
461                 fromFolder.getGroupId(), fromFolder.getFolderId());
462 
463         for (BookmarksFolder folder : folders) {
464             mergeFolders(folder, toFolderId);
465         }
466 
467         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
468             fromFolder.getFolderId());
469 
470         for (BookmarksEntry entry : entries) {
471             entry.setFolderId(toFolderId);
472 
473             bookmarksEntryPersistence.update(entry, false);
474         }
475 
476         bookmarksFolderPersistence.remove(fromFolder.getFolderId());
477     }
478 
479     protected void validate(String name) throws PortalException {
480         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
481             (name.indexOf("//") != -1)) {
482 
483             throw new FolderNameException();
484         }
485     }
486 
487     private static Log _log =
488         LogFactory.getLog(BookmarksFolderLocalServiceImpl.class);
489 
490 }