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  
48  import java.util.ArrayList;
49  import java.util.Date;
50  import java.util.List;
51  
52  /**
53   * <a href="BookmarksFolderLocalServiceImpl.java.html"><b><i>View Source</i></b>
54   * </a>
55   *
56   * @author Brian Wing Shun Chan
57   */
58  public class BookmarksFolderLocalServiceImpl
59      extends BookmarksFolderLocalServiceBaseImpl {
60  
61      public BookmarksFolder addFolder(
62              long userId, long parentFolderId, String name, String description,
63              ServiceContext serviceContext)
64          throws PortalException, SystemException {
65  
66          return addFolder(
67              null, userId, parentFolderId, name, description, serviceContext);
68      }
69  
70      public BookmarksFolder addFolder(
71              String uuid, long userId, long parentFolderId, String name,
72              String description, ServiceContext serviceContext)
73          throws PortalException, SystemException {
74  
75          // Folder
76  
77          User user = userPersistence.findByPrimaryKey(userId);
78          long groupId = serviceContext.getScopeGroupId();
79          parentFolderId = getParentFolderId(groupId, parentFolderId);
80          Date now = new Date();
81  
82          validate(name);
83  
84          long folderId = counterLocalService.increment();
85  
86          BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
87  
88          folder.setUuid(uuid);
89          folder.setGroupId(groupId);
90          folder.setCompanyId(user.getCompanyId());
91          folder.setUserId(user.getUserId());
92          folder.setCreateDate(now);
93          folder.setModifiedDate(now);
94          folder.setParentFolderId(parentFolderId);
95          folder.setName(name);
96          folder.setDescription(description);
97          folder.setExpandoBridgeAttributes(serviceContext);
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         return folder;
117     }
118 
119     public void addFolderResources(
120             BookmarksFolder folder, boolean addCommunityPermissions,
121             boolean addGuestPermissions)
122         throws PortalException, SystemException {
123 
124         resourceLocalService.addResources(
125             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
126             BookmarksFolder.class.getName(), folder.getFolderId(), false,
127             addCommunityPermissions, addGuestPermissions);
128     }
129 
130     public void addFolderResources(
131             BookmarksFolder folder, String[] communityPermissions,
132             String[] guestPermissions)
133         throws PortalException, SystemException {
134 
135         resourceLocalService.addModelResources(
136             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
137             BookmarksFolder.class.getName(), folder.getFolderId(),
138             communityPermissions, guestPermissions);
139     }
140 
141     public void addFolderResources(
142             long folderId, boolean addCommunityPermissions,
143             boolean addGuestPermissions)
144         throws PortalException, SystemException {
145 
146         BookmarksFolder folder =
147             bookmarksFolderPersistence.findByPrimaryKey(folderId);
148 
149         addFolderResources(
150             folder, addCommunityPermissions, addGuestPermissions);
151     }
152 
153     public void addFolderResources(
154             long folderId, String[] communityPermissions,
155             String[] guestPermissions)
156         throws PortalException, SystemException {
157 
158         BookmarksFolder folder =
159             bookmarksFolderPersistence.findByPrimaryKey(folderId);
160 
161         addFolderResources(folder, communityPermissions, guestPermissions);
162     }
163 
164     public void deleteFolder(BookmarksFolder folder)
165         throws PortalException, SystemException {
166 
167         // Folder
168 
169         bookmarksFolderPersistence.remove(folder);
170 
171         // Resources
172 
173         resourceLocalService.deleteResource(
174             folder.getCompanyId(), BookmarksFolder.class.getName(),
175             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
176 
177         // Entries
178 
179         bookmarksEntryLocalService.deleteEntries(folder.getFolderId());
180 
181         // Folders
182 
183         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
184             folder.getGroupId(), folder.getFolderId());
185 
186         for (BookmarksFolder curFolder : folders) {
187             deleteFolder(curFolder);
188         }
189 
190         // Expando
191 
192         expandoValueLocalService.deleteValues(
193             BookmarksFolder.class.getName(), folder.getFolderId());
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 deleteFolders(long groupId)
206         throws PortalException, SystemException {
207 
208         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
209             groupId, BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID);
210 
211         for (BookmarksFolder folder : folders) {
212             deleteFolder(folder);
213         }
214     }
215 
216     public BookmarksFolder getFolder(long folderId)
217         throws PortalException, SystemException {
218 
219         return bookmarksFolderPersistence.findByPrimaryKey(folderId);
220     }
221 
222     public List<BookmarksFolder> getFolders(
223             long groupId, long parentFolderId, int start, int end)
224         throws SystemException {
225 
226         return bookmarksFolderPersistence.findByG_P(
227             groupId, parentFolderId, start, end);
228     }
229 
230     public int getFoldersCount(long groupId, long parentFolderId)
231         throws SystemException {
232 
233         return bookmarksFolderPersistence.countByG_P(groupId, parentFolderId);
234     }
235 
236     public void getSubfolderIds(
237             List<Long> folderIds, long groupId, long folderId)
238         throws SystemException {
239 
240         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
241             groupId, folderId);
242 
243         for (BookmarksFolder folder : folders) {
244             folderIds.add(folder.getFolderId());
245 
246             getSubfolderIds(
247                 folderIds, folder.getGroupId(), folder.getFolderId());
248         }
249     }
250 
251     public void reIndex(String[] ids) throws SystemException {
252         if (SearchEngineUtil.isIndexReadOnly()) {
253             return;
254         }
255 
256         long companyId = GetterUtil.getLong(ids[0]);
257 
258         try {
259             reIndexFolders(companyId);
260         }
261         catch (SystemException se) {
262             throw se;
263         }
264         catch (Exception e) {
265             throw new SystemException(e);
266         }
267     }
268 
269     public Hits search(
270             long companyId, long groupId, long userId, long[] folderIds,
271             String keywords, int start, int end)
272         throws SystemException {
273 
274         try {
275             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
276 
277             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
278 
279             if (groupId > 0) {
280                 Group group = groupLocalService.getGroup(groupId);
281 
282                 if (group.isLayout()) {
283                     contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
284 
285                     groupId = group.getParentGroupId();
286                 }
287 
288                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
289             }
290 
291             if ((folderIds != null) && (folderIds.length > 0)) {
292                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
293 
294                 for (long folderId : folderIds) {
295                     if (userId > 0) {
296                         try {
297                             bookmarksFolderService.getFolder(folderId);
298                         }
299                         catch (Exception e) {
300                             continue;
301                         }
302                     }
303 
304                     TermQuery termQuery = TermQueryFactoryUtil.create(
305                         "folderId", folderId);
306 
307                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
308                 }
309 
310                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
311             }
312 
313             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
314 
315             if (Validator.isNotNull(keywords)) {
316                 searchQuery.addTerm(Field.TITLE, keywords);
317                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
318                 searchQuery.addTerm(Field.URL, keywords);
319                 searchQuery.addTerm(Field.COMMENTS, keywords);
320             }
321 
322             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
323 
324             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
325 
326             if (searchQuery.clauses().size() > 0) {
327                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
328             }
329 
330             return SearchEngineUtil.search(
331                 companyId, groupId, userId, BookmarksEntry.class.getName(),
332                 fullQuery, start, end);
333         }
334         catch (Exception e) {
335             throw new SystemException(e);
336         }
337     }
338 
339     public BookmarksFolder updateFolder(
340             long folderId, long parentFolderId, String name,
341             String description, boolean mergeWithParentFolder,
342             ServiceContext serviceContext)
343         throws PortalException, SystemException {
344 
345         // Folder
346 
347         BookmarksFolder folder =
348             bookmarksFolderPersistence.findByPrimaryKey(folderId);
349 
350         parentFolderId = getParentFolderId(folder, parentFolderId);
351 
352         validate(name);
353 
354         folder.setModifiedDate(new Date());
355         folder.setParentFolderId(parentFolderId);
356         folder.setName(name);
357         folder.setDescription(description);
358         folder.setExpandoBridgeAttributes(serviceContext);
359 
360         bookmarksFolderPersistence.update(folder, false);
361 
362         // Merge folders
363 
364         if (mergeWithParentFolder && (folderId != parentFolderId) &&
365             (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
366 
367             mergeFolders(folder, parentFolderId);
368         }
369 
370         return folder;
371     }
372 
373     protected long getParentFolderId(
374             BookmarksFolder folder, long parentFolderId)
375         throws SystemException {
376 
377         if (parentFolderId == BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
378             return parentFolderId;
379         }
380 
381         if (folder.getFolderId() == parentFolderId) {
382             return folder.getParentFolderId();
383         }
384         else {
385             BookmarksFolder parentFolder =
386                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
387 
388             if ((parentFolder == null) ||
389                 (folder.getGroupId() != parentFolder.getGroupId())) {
390 
391                 return folder.getParentFolderId();
392             }
393 
394             List<Long> subfolderIds = new ArrayList<Long>();
395 
396             getSubfolderIds(
397                 subfolderIds, folder.getGroupId(), folder.getFolderId());
398 
399             if (subfolderIds.contains(parentFolderId)) {
400                 return folder.getParentFolderId();
401             }
402 
403             return parentFolderId;
404         }
405     }
406 
407     protected long getParentFolderId(long groupId, long parentFolderId)
408         throws SystemException {
409 
410         if (parentFolderId != BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
411             BookmarksFolder parentFolder =
412                 bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
413 
414             if ((parentFolder == null) ||
415                 (groupId != parentFolder.getGroupId())) {
416 
417                 parentFolderId = BookmarksFolderImpl.DEFAULT_PARENT_FOLDER_ID;
418             }
419         }
420 
421         return parentFolderId;
422     }
423 
424     protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
425         throws PortalException, SystemException {
426 
427         List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
428                 fromFolder.getGroupId(), fromFolder.getFolderId());
429 
430         for (BookmarksFolder folder : folders) {
431             mergeFolders(folder, toFolderId);
432         }
433 
434         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
435             fromFolder.getFolderId());
436 
437         for (BookmarksEntry entry : entries) {
438             entry.setFolderId(toFolderId);
439 
440             bookmarksEntryPersistence.update(entry, false);
441 
442             bookmarksEntryLocalService.reIndex(entry);
443         }
444 
445         deleteFolder(fromFolder);
446     }
447 
448     protected void reIndexEntries(long folderId, int entryStart, int entryEnd)
449         throws SystemException {
450 
451         List<BookmarksEntry> entries = bookmarksEntryPersistence.findByFolderId(
452             folderId, entryStart, entryEnd);
453 
454         for (BookmarksEntry entry : entries) {
455             bookmarksEntryLocalService.reIndex(entry);
456         }
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 validate(String name) throws PortalException {
499         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
500             (name.indexOf("//") != -1)) {
501 
502             throw new FolderNameException();
503         }
504     }
505 
506 }