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