1   /**
2    * Copyright (c) 2000-2009 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.imagegallery.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.FileUtil;
36  import com.liferay.portal.kernel.util.GetterUtil;
37  import com.liferay.portal.kernel.util.StringPool;
38  import com.liferay.portal.kernel.util.Validator;
39  import com.liferay.portal.model.ResourceConstants;
40  import com.liferay.portal.model.User;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portlet.imagegallery.DuplicateFolderNameException;
43  import com.liferay.portlet.imagegallery.FolderNameException;
44  import com.liferay.portlet.imagegallery.model.IGFolder;
45  import com.liferay.portlet.imagegallery.model.IGImage;
46  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
47  import com.liferay.portlet.imagegallery.service.base.IGFolderLocalServiceBaseImpl;
48  import com.liferay.portlet.imagegallery.util.Indexer;
49  import com.liferay.portlet.tags.util.TagsUtil;
50  
51  import java.util.ArrayList;
52  import java.util.Date;
53  import java.util.List;
54  
55  /**
56   * <a href="IGFolderLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
57   *
58   * @author Brian Wing Shun Chan
59   *
60   */
61  public class IGFolderLocalServiceImpl extends IGFolderLocalServiceBaseImpl {
62  
63      public IGFolder addFolder(
64              long userId, long plid, long parentFolderId, String name,
65              String description, boolean addCommunityPermissions,
66              boolean addGuestPermissions)
67          throws PortalException, SystemException {
68  
69          return addFolder(
70              null, userId, plid, parentFolderId, name, description,
71              Boolean.valueOf(addCommunityPermissions),
72              Boolean.valueOf(addGuestPermissions), null, null);
73      }
74  
75      public IGFolder addFolder(
76              String uuid, long userId, long plid, long parentFolderId,
77              String name, String description, boolean addCommunityPermissions,
78              boolean addGuestPermissions)
79          throws PortalException, SystemException {
80  
81          return addFolder(
82              uuid, userId, plid, parentFolderId, name, description,
83              Boolean.valueOf(addCommunityPermissions),
84              Boolean.valueOf(addGuestPermissions), null, null);
85      }
86  
87      public IGFolder addFolder(
88              long userId, long plid, long parentFolderId, String name,
89              String description, String[] communityPermissions,
90              String[] guestPermissions)
91          throws PortalException, SystemException {
92  
93          return addFolder(
94              null, userId, plid, parentFolderId, name, description, null, null,
95              communityPermissions, guestPermissions);
96      }
97  
98      public IGFolder addFolder(
99              String uuid, long userId, long plid, long parentFolderId,
100             String name, String description, Boolean addCommunityPermissions,
101             Boolean addGuestPermissions, String[] communityPermissions,
102             String[] guestPermissions)
103         throws PortalException, SystemException {
104 
105         long groupId = PortalUtil.getScopeGroupId(plid);
106 
107         return addFolderToGroup(
108             uuid, userId, groupId, parentFolderId, name, description,
109             addCommunityPermissions, addGuestPermissions, communityPermissions,
110             guestPermissions);
111     }
112 
113     public IGFolder addFolderToGroup(
114             String uuid, long userId, long groupId, long parentFolderId,
115             String name, String description, Boolean addCommunityPermissions,
116             Boolean addGuestPermissions, String[] communityPermissions,
117             String[] guestPermissions)
118         throws PortalException, SystemException {
119 
120         // Folder
121 
122         User user = userPersistence.findByPrimaryKey(userId);
123         parentFolderId = getParentFolderId(groupId, parentFolderId);
124         Date now = new Date();
125 
126         validate(groupId, parentFolderId, name);
127 
128         long folderId = counterLocalService.increment();
129 
130         IGFolder folder = igFolderPersistence.create(folderId);
131 
132         folder.setUuid(uuid);
133         folder.setGroupId(groupId);
134         folder.setCompanyId(user.getCompanyId());
135         folder.setUserId(user.getUserId());
136         folder.setCreateDate(now);
137         folder.setModifiedDate(now);
138         folder.setParentFolderId(parentFolderId);
139         folder.setName(name);
140         folder.setDescription(description);
141 
142         igFolderPersistence.update(folder, false);
143 
144         // Resources
145 
146         if ((addCommunityPermissions != null) &&
147             (addGuestPermissions != null)) {
148 
149             addFolderResources(
150                 folder, addCommunityPermissions.booleanValue(),
151                 addGuestPermissions.booleanValue());
152         }
153         else {
154             addFolderResources(folder, communityPermissions, guestPermissions);
155         }
156 
157         return folder;
158     }
159 
160     public void addFolderResources(
161             long folderId, boolean addCommunityPermissions,
162             boolean addGuestPermissions)
163         throws PortalException, SystemException {
164 
165         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
166 
167         addFolderResources(
168             folder, addCommunityPermissions, addGuestPermissions);
169     }
170 
171     public void addFolderResources(
172             IGFolder folder, boolean addCommunityPermissions,
173             boolean addGuestPermissions)
174         throws PortalException, SystemException {
175 
176         resourceLocalService.addResources(
177             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
178             IGFolder.class.getName(), folder.getFolderId(), false,
179             addCommunityPermissions, addGuestPermissions);
180     }
181 
182     public void addFolderResources(
183             long folderId, String[] communityPermissions,
184             String[] guestPermissions)
185         throws PortalException, SystemException {
186 
187         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
188 
189         addFolderResources(folder, communityPermissions, guestPermissions);
190     }
191 
192     public void addFolderResources(
193             IGFolder folder, String[] communityPermissions,
194             String[] guestPermissions)
195         throws PortalException, SystemException {
196 
197         resourceLocalService.addModelResources(
198             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
199             IGFolder.class.getName(), folder.getFolderId(),
200             communityPermissions, guestPermissions);
201     }
202 
203     public void deleteFolder(long folderId)
204         throws PortalException, SystemException {
205 
206         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
207 
208         deleteFolder(folder);
209     }
210 
211     public void deleteFolder(IGFolder folder)
212         throws PortalException, SystemException {
213 
214         // Folders
215 
216         List<IGFolder> folders = igFolderPersistence.findByG_P(
217             folder.getGroupId(), folder.getFolderId());
218 
219         for (IGFolder curFolder : folders) {
220             deleteFolder(curFolder);
221         }
222 
223         // Images
224 
225         igImageLocalService.deleteImages(folder.getFolderId());
226 
227         // Resources
228 
229         resourceLocalService.deleteResource(
230             folder.getCompanyId(), IGFolder.class.getName(),
231             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
232 
233         // Folder
234 
235         igFolderPersistence.remove(folder);
236     }
237 
238     public void deleteFolders(long groupId)
239         throws PortalException, SystemException {
240 
241         List<IGFolder> folders = igFolderPersistence.findByG_P(
242             groupId, IGFolderImpl.DEFAULT_PARENT_FOLDER_ID);
243 
244         for (IGFolder folder : folders) {
245             deleteFolder(folder);
246         }
247     }
248 
249     public IGFolder getFolder(long folderId)
250         throws PortalException, SystemException {
251 
252         return igFolderPersistence.findByPrimaryKey(folderId);
253     }
254 
255     public IGFolder getFolder(long groupId, long parentFolderId, String name)
256         throws PortalException, SystemException {
257 
258         return igFolderPersistence.findByG_P_N(groupId, parentFolderId, name);
259     }
260 
261     public List<IGFolder> getFolders(long groupId) throws SystemException {
262         return igFolderPersistence.findByGroupId(groupId);
263     }
264 
265     public List<IGFolder> getFolders(long groupId, long parentFolderId)
266         throws SystemException {
267 
268         return igFolderPersistence.findByG_P(groupId, parentFolderId);
269     }
270 
271     public List<IGFolder> getFolders(
272             long groupId, long parentFolderId, int start, int end)
273         throws SystemException {
274 
275         return igFolderPersistence.findByG_P(
276             groupId, parentFolderId, start, end);
277     }
278 
279     public int getFoldersCount(long groupId, long parentFolderId)
280         throws SystemException {
281 
282         return igFolderPersistence.countByG_P(groupId, parentFolderId);
283     }
284 
285     public void getSubfolderIds(
286             List<Long> folderIds, long groupId, long folderId)
287         throws SystemException {
288 
289         List<IGFolder> folders = igFolderPersistence.findByG_P(
290             groupId, folderId);
291 
292         for (IGFolder folder : folders) {
293             folderIds.add(folder.getFolderId());
294 
295             getSubfolderIds(
296                 folderIds, folder.getGroupId(), folder.getFolderId());
297         }
298     }
299 
300     public void reIndex(String[] ids) throws SystemException {
301         if (SearchEngineUtil.isIndexReadOnly()) {
302             return;
303         }
304 
305         long companyId = GetterUtil.getLong(ids[0]);
306 
307         try {
308             reIndexFolders(companyId);
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.DESCRIPTION, keywords);
350                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords, true);
351             }
352 
353             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
354 
355             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
356 
357             if (searchQuery.clauses().size() > 0) {
358                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
359             }
360 
361             return SearchEngineUtil.search(companyId, fullQuery, start, end);
362         }
363         catch (Exception e) {
364             throw new SystemException(e);
365         }
366     }
367 
368     public IGFolder updateFolder(
369             long folderId, long parentFolderId, String name, String description,
370             boolean mergeWithParentFolder)
371         throws PortalException, SystemException {
372 
373         // Folder
374 
375         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
376 
377         parentFolderId = getParentFolderId(folder, parentFolderId);
378 
379         validate(
380             folder.getFolderId(), folder.getGroupId(), parentFolderId, name);
381 
382         folder.setModifiedDate(new Date());
383         folder.setParentFolderId(parentFolderId);
384         folder.setName(name);
385         folder.setDescription(description);
386 
387         igFolderPersistence.update(folder, false);
388 
389         // Merge folders
390 
391         if (mergeWithParentFolder && (folderId != parentFolderId) &&
392             (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
393 
394             mergeFolders(folder, parentFolderId);
395         }
396 
397         return folder;
398     }
399 
400     protected long getParentFolderId(long groupId, long parentFolderId)
401         throws SystemException {
402 
403         if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
404             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
405                 parentFolderId);
406 
407             if ((parentFolder == null) ||
408                 (groupId != parentFolder.getGroupId())) {
409 
410                 parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
411             }
412         }
413 
414         return parentFolderId;
415     }
416 
417     protected long getParentFolderId(IGFolder folder, long parentFolderId)
418         throws SystemException {
419 
420         if (parentFolderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
421             return parentFolderId;
422         }
423 
424         if (folder.getFolderId() == parentFolderId) {
425             return folder.getParentFolderId();
426         }
427         else {
428             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
429                 parentFolderId);
430 
431             if ((parentFolder == null) ||
432                 (folder.getGroupId() != parentFolder.getGroupId())) {
433 
434                 return folder.getParentFolderId();
435             }
436 
437             List<Long> subfolderIds = new ArrayList<Long>();
438 
439             getSubfolderIds(
440                 subfolderIds, folder.getGroupId(), folder.getFolderId());
441 
442             if (subfolderIds.contains(parentFolderId)) {
443                 return folder.getParentFolderId();
444             }
445 
446             return parentFolderId;
447         }
448     }
449 
450     protected void mergeFolders(IGFolder fromFolder, long toFolderId)
451         throws PortalException, SystemException {
452 
453         List<IGFolder> folders = igFolderPersistence.findByG_P(
454             fromFolder.getGroupId(), fromFolder.getFolderId());
455 
456         for (IGFolder folder : folders) {
457             mergeFolders(folder, toFolderId);
458         }
459 
460         List<IGImage> images = igImagePersistence.findByFolderId(
461             fromFolder.getFolderId());
462 
463         for (IGImage image : images) {
464             image.setFolderId(toFolderId);
465 
466             igImagePersistence.update(image, false);
467         }
468 
469         deleteFolder(fromFolder);
470     }
471 
472     protected void reIndexFolders(long companyId) throws SystemException {
473         int folderCount = igFolderPersistence.countByCompanyId(companyId);
474 
475         int folderPages = folderCount / Indexer.DEFAULT_INTERVAL;
476 
477         for (int i = 0; i <= folderPages; i++) {
478             int folderStart = (i * Indexer.DEFAULT_INTERVAL);
479             int folderEnd = folderStart + Indexer.DEFAULT_INTERVAL;
480 
481             reIndexFolders(companyId, folderStart, folderEnd);
482         }
483     }
484 
485     protected void reIndexFolders(
486             long companyId, int folderStart, int folderEnd)
487         throws SystemException {
488 
489         List<IGFolder> folders = igFolderPersistence.findByCompanyId(
490             companyId, folderStart, folderEnd);
491 
492         for (IGFolder folder : folders) {
493             long folderId = folder.getFolderId();
494 
495             int entryCount = igImagePersistence.countByFolderId(folderId);
496 
497             int entryPages = entryCount / Indexer.DEFAULT_INTERVAL;
498 
499             for (int i = 0; i <= entryPages; i++) {
500                 int entryStart = (i * Indexer.DEFAULT_INTERVAL);
501                 int entryEnd = entryStart + Indexer.DEFAULT_INTERVAL;
502 
503                 reIndexImages(folderId, entryStart, entryEnd);
504             }
505         }
506     }
507 
508     protected void reIndexImages(long folderId, int entryStart, int entryEnd)
509         throws SystemException {
510 
511         List<IGImage> images = igImagePersistence.findByFolderId(
512             folderId, entryStart, entryEnd);
513 
514         for (IGImage image : images) {
515             igImageLocalService.reIndex(image);
516         }
517     }
518 
519     protected void validate(long groupId, long parentFolderId, String name)
520         throws PortalException, SystemException {
521 
522         long folderId = 0;
523 
524         validate(folderId, groupId, parentFolderId, name);
525     }
526 
527     protected void validate(
528             long folderId, long groupId, long parentFolderId, String name)
529         throws PortalException, SystemException {
530 
531         if (!TagsUtil.isValidWord(name)) {
532             throw new FolderNameException();
533         }
534 
535         IGFolder folder = igFolderPersistence.fetchByG_P_N(
536             groupId, parentFolderId, name);
537 
538         if ((folder != null) && (folder.getFolderId() != folderId)) {
539             throw new DuplicateFolderNameException();
540         }
541 
542         if (name.indexOf(StringPool.PERIOD) != -1) {
543             String nameWithExtension = name;
544 
545             name = FileUtil.stripExtension(nameWithExtension);
546 
547             List<IGImage> images = igImagePersistence.findByF_N(
548                 parentFolderId, name);
549 
550             for (IGImage image : images) {
551                 if (nameWithExtension.equals(image.getNameWithExtension())) {
552                     throw new DuplicateFolderNameException();
553                 }
554             }
555         }
556     }
557 
558 }