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