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