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