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