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.Field;
31  import com.liferay.portal.kernel.search.Hits;
32  import com.liferay.portal.kernel.search.SearchEngineUtil;
33  import com.liferay.portal.kernel.search.SearchException;
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                         Indexer.updateImage(
332                             companyId, groupId, folderId, imageId, name,
333                             description, tagsEntries);
334                     }
335                     catch (SearchException se) {
336                         _log.error("Reindexing " + imageId, se);
337                     }
338                 }
339             }
340         }
341         catch (SystemException se) {
342             throw se;
343         }
344         catch (Exception e) {
345             throw new SystemException(e);
346         }
347     }
348 
349     public Hits search(
350             long companyId, long groupId, long[] folderIds, String keywords,
351             int start, int end)
352         throws SystemException {
353 
354         try {
355             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
356 
357             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
358 
359             if (groupId > 0) {
360                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
361             }
362 
363             if ((folderIds != null) && (folderIds.length > 0)) {
364                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
365 
366                 for (long folderId : folderIds) {
367                     TermQuery termQuery = TermQueryFactoryUtil.create(
368                         "folderId", folderId);
369 
370                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
371                 }
372 
373                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
374             }
375 
376             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
377 
378             if (Validator.isNotNull(keywords)) {
379                 searchQuery.addTerm(Field.DESCRIPTION, keywords);
380                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords);
381             }
382 
383             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
384 
385             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
386 
387             if (searchQuery.clauses().size() > 0) {
388                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
389             }
390 
391             return SearchEngineUtil.search(companyId, fullQuery, start, end);
392         }
393         catch (Exception e) {
394             throw new SystemException(e);
395         }
396     }
397 
398     public IGFolder updateFolder(
399             long folderId, long parentFolderId, String name, String description,
400             boolean mergeWithParentFolder)
401         throws PortalException, SystemException {
402 
403         // Folder
404 
405         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
406 
407         parentFolderId = getParentFolderId(folder, parentFolderId);
408 
409         validate(
410             folder.getFolderId(), folder.getGroupId(), parentFolderId, name);
411 
412         folder.setModifiedDate(new Date());
413         folder.setParentFolderId(parentFolderId);
414         folder.setName(name);
415         folder.setDescription(description);
416 
417         igFolderPersistence.update(folder, false);
418 
419         // Merge folders
420 
421         if (mergeWithParentFolder && (folderId != parentFolderId) &&
422             (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
423 
424             mergeFolders(folder, parentFolderId);
425         }
426 
427         return folder;
428     }
429 
430     protected long getParentFolderId(long groupId, long parentFolderId)
431         throws SystemException {
432 
433         if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
434             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
435                 parentFolderId);
436 
437             if ((parentFolder == null) ||
438                 (groupId != parentFolder.getGroupId())) {
439 
440                 parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
441             }
442         }
443 
444         return parentFolderId;
445     }
446 
447     protected long getParentFolderId(IGFolder folder, long parentFolderId)
448         throws SystemException {
449 
450         if (parentFolderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
451             return parentFolderId;
452         }
453 
454         if (folder.getFolderId() == parentFolderId) {
455             return folder.getParentFolderId();
456         }
457         else {
458             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
459                 parentFolderId);
460 
461             if ((parentFolder == null) ||
462                 (folder.getGroupId() != parentFolder.getGroupId())) {
463 
464                 return folder.getParentFolderId();
465             }
466 
467             List<Long> subfolderIds = new ArrayList<Long>();
468 
469             getSubfolderIds(
470                 subfolderIds, folder.getGroupId(), folder.getFolderId());
471 
472             if (subfolderIds.contains(parentFolderId)) {
473                 return folder.getParentFolderId();
474             }
475 
476             return parentFolderId;
477         }
478     }
479 
480     protected void mergeFolders(IGFolder fromFolder, long toFolderId)
481         throws PortalException, SystemException {
482 
483         List<IGFolder> folders = igFolderPersistence.findByG_P(
484             fromFolder.getGroupId(), fromFolder.getFolderId());
485 
486         for (IGFolder folder : folders) {
487             mergeFolders(folder, toFolderId);
488         }
489 
490         List<IGImage> images = igImagePersistence.findByFolderId(
491             fromFolder.getFolderId());
492 
493         for (IGImage image : images) {
494             image.setFolderId(toFolderId);
495 
496             igImagePersistence.update(image, false);
497         }
498 
499         deleteFolder(fromFolder);
500     }
501 
502     protected void validate(long groupId, long parentFolderId, String name)
503         throws PortalException, SystemException {
504 
505         long folderId = 0;
506 
507         validate(folderId, groupId, parentFolderId, name);
508     }
509 
510     protected void validate(
511             long folderId, long groupId, long parentFolderId, String name)
512         throws PortalException, SystemException {
513 
514         if (!TagsUtil.isValidWord(name)) {
515             throw new FolderNameException();
516         }
517 
518         IGFolder folder = igFolderPersistence.fetchByG_P_N(
519             groupId, parentFolderId, name);
520 
521         if ((folder != null) && (folder.getFolderId() != folderId)) {
522             throw new DuplicateFolderNameException();
523         }
524 
525         if (name.indexOf(StringPool.PERIOD) != -1) {
526             String nameWithExtension = name;
527 
528             name = FileUtil.stripExtension(nameWithExtension);
529 
530             List<IGImage> images = igImagePersistence.findByF_N(
531                 parentFolderId, name);
532 
533             for (IGImage image : images) {
534                 if (nameWithExtension.equals(image.getNameWithExtension())) {
535                     throw new DuplicateFolderNameException();
536                 }
537             }
538         }
539     }
540 
541     private static Log _log = LogFactory.getLog(IGFolderLocalServiceImpl.class);
542 
543 }