1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.Field;
31  import com.liferay.portal.kernel.search.Hits;
32  import com.liferay.portal.kernel.search.SearchEngineUtil;
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.Group;
38  import com.liferay.portal.model.ResourceConstants;
39  import com.liferay.portal.model.User;
40  import com.liferay.portal.service.ServiceContext;
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  import com.liferay.portlet.expando.model.ExpandoBridge;
48  
49  import java.util.ArrayList;
50  import java.util.Date;
51  import java.util.List;
52  
53  /**
54   * <a href="BookmarksFolderLocalServiceImpl.java.html"><b><i>View Source</i></b>
55   * </a>
56   *
57   * @author Brian Wing Shun Chan
58   */
59  public class BookmarksFolderLocalServiceImpl
60      extends BookmarksFolderLocalServiceBaseImpl {
61  
62      public BookmarksFolder addFolder(
63              long userId, long parentFolderId, String name, String description,
64              ServiceContext serviceContext)
65          throws PortalException, SystemException {
66  
67          return addFolder(
68              null, userId, parentFolderId, name, description, serviceContext);
69      }
70  
71      public BookmarksFolder addFolder(
72              String uuid, long userId, long parentFolderId, String name,
73              String description, ServiceContext serviceContext)
74          throws PortalException, SystemException {
75  
76          // Folder
77  
78          User user = userPersistence.findByPrimaryKey(userId);
79          long groupId = serviceContext.getScopeGroupId();
80          parentFolderId = getParentFolderId(groupId, parentFolderId);
81          Date now = new Date();
82  
83          validate(name);
84  
85          long folderId = counterLocalService.increment();
86  
87          BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
88  
89          folder.setUuid(uuid);
90          folder.setGroupId(groupId);
91          folder.setCompanyId(user.getCompanyId());
92          folder.setUserId(user.getUserId());
93          folder.setCreateDate(now);
94          folder.setModifiedDate(now);
95          folder.setParentFolderId(parentFolderId);
96          folder.setName(name);
97          folder.setDescription(description);
98  
99          bookmarksFolderPersistence.update(folder, false);
100 
101         // Resources
102 
103         if (serviceContext.getAddCommunityPermissions() ||
104             serviceContext.getAddGuestPermissions()) {
105 
106             addFolderResources(
107                 folder, serviceContext.getAddCommunityPermissions(),
108                 serviceContext.getAddGuestPermissions());
109         }
110         else {
111             addFolderResources(
112                 folder, serviceContext.getCommunityPermissions(),
113                 serviceContext.getGuestPermissions());
114         }
115 
116         // Expando
117 
118         ExpandoBridge expandoBridge = folder.getExpandoBridge();
119 
120         expandoBridge.setAttributes(serviceContext);
121 
122         return folder;
123     }
124 
125     public void addFolderResources(
126             long folderId, boolean addCommunityPermissions,
127             boolean addGuestPermissions)
128         throws PortalException, SystemException {
129 
130         BookmarksFolder folder =
131             bookmarksFolderPersistence.findByPrimaryKey(folderId);
132 
133         addFolderResources(
134             folder, addCommunityPermissions, addGuestPermissions);
135     }
136 
137     public void addFolderResources(
138             BookmarksFolder folder, boolean addCommunityPermissions,
139             boolean addGuestPermissions)
140         throws PortalException, SystemException {
141 
142         resourceLocalService.addResources(
143             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
144             BookmarksFolder.class.getName(), folder.getFolderId(), false,
145             addCommunityPermissions, addGuestPermissions);
146     }
147 
148     public void addFolderResources(
149             long folderId, String[] communityPermissions,
150             String[] guestPermissions)
151         throws PortalException, SystemException {
152 
153         BookmarksFolder folder =
154             bookmarksFolderPersistence.findByPrimaryKey(folderId);
155 
156         addFolderResources(folder, communityPermissions, guestPermissions);
157     }
158 
159     public void addFolderResources(
160             BookmarksFolder folder, String[] communityPermissions,
161             String[] guestPermissions)
162         throws PortalException, SystemException {
163 
164         resourceLocalService.addModelResources(
165             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
166             BookmarksFolder.class.getName(), folder.getFolderId(),
167             communityPermissions, guestPermissions);
168     }
169 
170     public void deleteFolder(long folderId)
171         throws PortalException, SystemException {
172 
173         BookmarksFolder folder =
174             bookmarksFolderPersistence.findByPrimaryKey(folderId);
175 
176         deleteFolder(folder);
177     }
178 
179     public void deleteFolder(BookmarksFolder folder)
180         throws PortalException, SystemException {
181 
182         // Folders
183 
184         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
185             folder.getGroupId(), folder.getFolderId());
186 
187         for (BookmarksFolder curFolder : folders) {
188             deleteFolder(curFolder);
189         }
190 
191         // Entries
192 
193         bookmarksEntryLocalService.deleteEntries(folder.getFolderId());
194 
195         // Expando
196 
197         expandoValueLocalService.deleteValues(
198             BookmarksFolder.class.getName(), folder.getFolderId());
199 
200         // Resources
201 
202         resourceLocalService.deleteResource(
203             folder.getCompanyId(), BookmarksFolder.class.getName(),
204             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
205 
206         // Folder
207 
208         bookmarksFolderPersistence.remove(folder);
209     }
210 
211     public void deleteFolders(long groupId)
212         throws PortalException, SystemException {
213 
214         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
215             groupId, BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID);
216 
217         for (BookmarksFolder folder : folders) {
218             deleteFolder(folder);
219         }
220     }
221 
222     public BookmarksFolder getFolder(long folderId)
223         throws PortalException, SystemException {
224 
225         return bookmarksFolderPersistence.findByPrimaryKey(folderId);
226     }
227 
228     public List<BookmarksFolder> getFolders(
229             long groupId, long parentFolderId, int start, int end)
230         throws SystemException {
231 
232         return bookmarksFolderPersistence.findByG_P(
233             groupId, parentFolderId, start, end);
234     }
235 
236     public int getFoldersCount(long groupId, long parentFolderId)
237         throws SystemException {
238 
239         return bookmarksFolderPersistence.countByG_P(groupId, parentFolderId);
240     }
241 
242     public void getSubfolderIds(
243             List<Long> folderIds, long groupId, long folderId)
244         throws SystemException {
245 
246         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
247             groupId, folderId);
248 
249         for (BookmarksFolder folder : folders) {
250             folderIds.add(folder.getFolderId());
251 
252             getSubfolderIds(
253                 folderIds, folder.getGroupId(), folder.getFolderId());
254         }
255     }
256 
257     public void reIndex(String[] ids) throws SystemException {
258         if (SearchEngineUtil.isIndexReadOnly()) {
259             return;
260         }
261 
262         long companyId = GetterUtil.getLong(ids[0]);
263 
264         try {
265             reIndexFolders(companyId);
266         }
267         catch (SystemException se) {
268             throw se;
269         }
270         catch (Exception e) {
271             throw new SystemException(e);
272         }
273     }
274 
275     public Hits search(
276             long companyId, long groupId, long userId, long[] folderIds,
277             String keywords, int start, int end)
278         throws SystemException {
279 
280         try {
281             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
282 
283             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
284 
285             if (groupId > 0) {
286                 Group group = groupLocalService.getGroup(groupId);
287 
288                 if (group.isLayout()) {
289                     contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
290 
291                     groupId = group.getParentGroupId();
292                 }
293 
294                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
295             }
296 
297             if ((folderIds != null) && (folderIds.length > 0)) {
298                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
299 
300                 for (long folderId : folderIds) {
301                     if (userId > 0) {
302                         try {
303                             bookmarksFolderService.getFolder(folderId);
304                         }
305                         catch (Exception e) {
306                             continue;
307                         }
308                     }
309 
310                     TermQuery termQuery = TermQueryFactoryUtil.create(
311                         "folderId", folderId);
312 
313                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
314                 }
315 
316                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
317             }
318 
319             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
320 
321             if (Validator.isNotNull(keywords)) {
322                 searchQuery.addTerm(Field.TITLE, keywords);
323                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
324                 searchQuery.addTerm(Field.URL, keywords);
325                 searchQuery.addTerm(Field.COMMENTS, keywords);
326             }
327 
328             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
329 
330             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
331 
332             if (searchQuery.clauses().size() > 0) {
333                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
334             }
335 
336             return SearchEngineUtil.search(
337                 companyId, groupId, userId, BookmarksEntry.class.getName(),
338                 fullQuery, start, end);
339         }
340         catch (Exception e) {
341             throw new SystemException(e);
342         }
343     }
344 
345     public BookmarksFolder updateFolder(
346             long folderId, long parentFolderId, String name,
347             String description, boolean mergeWithParentFolder,
348             ServiceContext serviceContext)
349         throws PortalException, SystemException {
350 
351         // Folder
352 
353         BookmarksFolder folder =
354             bookmarksFolderPersistence.findByPrimaryKey(folderId);
355 
356         parentFolderId = getParentFolderId(folder, parentFolderId);
357 
358         validate(name);
359 
360         folder.setModifiedDate(new Date());
361         folder.setParentFolderId(parentFolderId);
362         folder.setName(name);
363         folder.setDescription(description);
364 
365         bookmarksFolderPersistence.update(folder, false);
366 
367         // Expando
368 
369         ExpandoBridge expandoBridge = folder.getExpandoBridge();
370 
371         expandoBridge.setAttributes(serviceContext);
372 
373         // Merge folders
374 
375         if (mergeWithParentFolder && (folderId != parentFolderId) &&
376             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
377 
378             mergeFolders(folder, parentFolderId);
379         }
380 
381         return folder;
382     }
383 
384     protected long getParentFolderId(long groupId, long parentFolderId)
385         throws SystemException {
386 
387         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
388             BookmarksFolder parentFolder =
389                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
390 
391             if ((parentFolder == null) ||
392                 (groupId != parentFolder.getGroupId())) {
393 
394                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
395             }
396         }
397 
398         return parentFolderId;
399     }
400 
401     protected long getParentFolderId(
402             BookmarksFolder folder, long parentFolderId)
403         throws SystemException {
404 
405         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
406             return parentFolderId;
407         }
408 
409         if (folder.getFolderId() == parentFolderId) {
410             return folder.getParentFolderId();
411         }
412         else {
413             BookmarksFolder parentFolder =
414                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
415 
416             if ((parentFolder == null) ||
417                 (folder.getGroupId() != parentFolder.getGroupId())) {
418 
419                 return folder.getParentFolderId();
420             }
421 
422             List<Long> subfolderIds = new ArrayList<Long>();
423 
424             getSubfolderIds(
425                 subfolderIds, folder.getGroupId(), folder.getFolderId());
426 
427             if (subfolderIds.contains(parentFolderId)) {
428                 return folder.getParentFolderId();
429             }
430 
431             return parentFolderId;
432         }
433     }
434 
435     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
436         throws PortalException, SystemException {
437 
438         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
439                 fromFolder.getGroupId(), fromFolder.getFolderId());
440 
441         for (BookmarksFolder folder : folders) {
442             mergeFolders(folder, toFolderId);
443         }
444 
445         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
446             fromFolder.getFolderId());
447 
448         for (BookmarksEntry entry : entries) {
449             entry.setFolderId(toFolderId);
450 
451             bookmarksEntryPersistence.update(entry, false);
452 
453             bookmarksEntryLocalService.reIndex(entry);
454         }
455 
456         deleteFolder(fromFolder);
457     }
458 
459     protected void reIndexFolders(long companyId) throws SystemException {
460         int folderCount = bookmarksFolderPersistence.countByCompanyId(
461             companyId);
462 
463         int folderPages = folderCount / Indexer.DEFAULT_INTERVAL;
464 
465         for (int i = 0; i <= folderPages; i++) {
466             int folderStart = (i * Indexer.DEFAULT_INTERVAL);
467             int folderEnd = folderStart + Indexer.DEFAULT_INTERVAL;
468 
469             reIndexFolders(companyId, folderStart, folderEnd);
470         }
471     }
472 
473     protected void reIndexFolders(
474             long companyId, int folderStart, int folderEnd)
475         throws SystemException {
476 
477         List<BookmarksFolder> folders =
478             bookmarksFolderPersistence.findByCompanyId(
479                 companyId, folderStart, folderEnd);
480 
481         for (BookmarksFolder folder : folders) {
482             long folderId = folder.getFolderId();
483 
484             int entryCount = bookmarksEntryPersistence.countByFolderId(
485                 folderId);
486 
487             int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
488 
489             for (int i = 0; i <= entryPages; i++) {
490                 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
491                 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
492 
493                 reIndexEntries(folderId, entryStart, entryEnd);
494             }
495         }
496     }
497 
498     protected void reIndexEntries(long folderId, int entryStart, int entryEnd)
499         throws SystemException {
500 
501         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
502             folderId, entryStart, entryEnd);
503 
504         for (BookmarksEntry entry : entries) {
505             bookmarksEntryLocalService.reIndex(entry);
506         }
507     }
508 
509     protected void validate(String name) throws PortalException {
510         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
511             (name.indexOf("//") != -1)) {
512 
513             throw new FolderNameException();
514         }
515     }
516 
517 }