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