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