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.Document;
28  import com.liferay.portal.kernel.search.Field;
29  import com.liferay.portal.kernel.search.Hits;
30  import com.liferay.portal.kernel.search.SearchEngineUtil;
31  import com.liferay.portal.kernel.util.FileUtil;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.kernel.util.StringPool;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.model.ResourceConstants;
36  import com.liferay.portal.model.User;
37  import com.liferay.portal.search.lucene.LuceneUtil;
38  import com.liferay.portal.util.PortalUtil;
39  import com.liferay.portlet.imagegallery.DuplicateFolderNameException;
40  import com.liferay.portlet.imagegallery.FolderNameException;
41  import com.liferay.portlet.imagegallery.model.IGFolder;
42  import com.liferay.portlet.imagegallery.model.IGImage;
43  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
44  import com.liferay.portlet.imagegallery.service.base.IGFolderLocalServiceBaseImpl;
45  import com.liferay.portlet.imagegallery.util.Indexer;
46  
47  import java.util.ArrayList;
48  import java.util.Date;
49  import java.util.List;
50  
51  import org.apache.commons.logging.Log;
52  import org.apache.commons.logging.LogFactory;
53  import org.apache.lucene.index.Term;
54  import org.apache.lucene.search.BooleanClause;
55  import org.apache.lucene.search.BooleanQuery;
56  import org.apache.lucene.search.TermQuery;
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 = new BooleanQuery();
357 
358             LuceneUtil.addRequiredTerm(
359                 contextQuery, Field.PORTLET_ID, Indexer.PORTLET_ID);
360 
361             if (groupId > 0) {
362                 LuceneUtil.addRequiredTerm(
363                     contextQuery, Field.GROUP_ID, groupId);
364             }
365 
366             if ((folderIds != null) && (folderIds.length > 0)) {
367                 BooleanQuery folderIdsQuery = new BooleanQuery();
368 
369                 for (int i = 0; i < folderIds.length; i++) {
370                     Term term = new Term(
371                         "folderId", String.valueOf(folderIds[i]));
372                     TermQuery termQuery = new TermQuery(term);
373 
374                     folderIdsQuery.add(termQuery, BooleanClause.Occur.SHOULD);
375                 }
376 
377                 contextQuery.add(folderIdsQuery, BooleanClause.Occur.MUST);
378             }
379 
380             BooleanQuery searchQuery = new BooleanQuery();
381 
382             if (Validator.isNotNull(keywords)) {
383                 LuceneUtil.addTerm(searchQuery, Field.DESCRIPTION, keywords);
384                 LuceneUtil.addTerm(searchQuery, Field.TAGS_ENTRIES, keywords);
385             }
386 
387             BooleanQuery fullQuery = new BooleanQuery();
388 
389             fullQuery.add(contextQuery, BooleanClause.Occur.MUST);
390 
391             if (searchQuery.clauses().size() > 0) {
392                 fullQuery.add(searchQuery, BooleanClause.Occur.MUST);
393             }
394 
395             return SearchEngineUtil.search(
396                 companyId, fullQuery.toString(), start, end);
397         }
398         catch (Exception e) {
399             throw new SystemException(e);
400         }
401     }
402 
403     public IGFolder updateFolder(
404             long folderId, long parentFolderId, String name, String description,
405             boolean mergeWithParentFolder)
406         throws PortalException, SystemException {
407 
408         // Folder
409 
410         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
411 
412         parentFolderId = getParentFolderId(folder, parentFolderId);
413 
414         validate(
415             folder.getFolderId(), folder.getGroupId(), parentFolderId, name);
416 
417         folder.setModifiedDate(new Date());
418         folder.setParentFolderId(parentFolderId);
419         folder.setName(name);
420         folder.setDescription(description);
421 
422         igFolderPersistence.update(folder, false);
423 
424         // Merge folders
425 
426         if (mergeWithParentFolder && (folderId != parentFolderId) &&
427             (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
428 
429             mergeFolders(folder, parentFolderId);
430         }
431 
432         return folder;
433     }
434 
435     protected long getParentFolderId(long groupId, long parentFolderId)
436         throws SystemException {
437 
438         if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
439             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
440                 parentFolderId);
441 
442             if ((parentFolder == null) ||
443                 (groupId != parentFolder.getGroupId())) {
444 
445                 parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
446             }
447         }
448 
449         return parentFolderId;
450     }
451 
452     protected long getParentFolderId(IGFolder folder, long parentFolderId)
453         throws SystemException {
454 
455         if (parentFolderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
456             return parentFolderId;
457         }
458 
459         if (folder.getFolderId() == parentFolderId) {
460             return folder.getParentFolderId();
461         }
462         else {
463             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
464                 parentFolderId);
465 
466             if ((parentFolder == null) ||
467                 (folder.getGroupId() != parentFolder.getGroupId())) {
468 
469                 return folder.getParentFolderId();
470             }
471 
472             List<Long> subfolderIds = new ArrayList<Long>();
473 
474             getSubfolderIds(
475                 subfolderIds, folder.getGroupId(), folder.getFolderId());
476 
477             if (subfolderIds.contains(parentFolderId)) {
478                 return folder.getParentFolderId();
479             }
480 
481             return parentFolderId;
482         }
483     }
484 
485     protected void mergeFolders(IGFolder fromFolder, long toFolderId)
486         throws PortalException, SystemException {
487 
488         List<IGFolder> folders = igFolderPersistence.findByG_P(
489             fromFolder.getGroupId(), fromFolder.getFolderId());
490 
491         for (IGFolder folder : folders) {
492             mergeFolders(folder, toFolderId);
493         }
494 
495         List<IGImage> images = igImagePersistence.findByFolderId(
496             fromFolder.getFolderId());
497 
498         for (IGImage image : images) {
499             image.setFolderId(toFolderId);
500 
501             igImagePersistence.update(image, false);
502         }
503 
504         igFolderPersistence.remove(fromFolder.getFolderId());
505     }
506 
507     protected void validate(long groupId, long parentFolderId, String name)
508         throws PortalException, SystemException {
509 
510         long folderId = 0;
511 
512         validate(folderId, groupId, parentFolderId, name);
513     }
514 
515     protected void validate(
516             long folderId, long groupId, long parentFolderId, String name)
517         throws PortalException, SystemException {
518 
519         if ((Validator.isNull(name)) || (name.indexOf("\\\\") != -1) ||
520             (name.indexOf("//") != -1)) {
521 
522             throw new FolderNameException();
523         }
524 
525         IGFolder folder = igFolderPersistence.fetchByG_P_N(
526             groupId, parentFolderId, name);
527 
528         if ((folder != null) && (folder.getFolderId() != folderId)) {
529             throw new DuplicateFolderNameException();
530         }
531 
532         if (name.indexOf(StringPool.PERIOD) != -1) {
533             String nameWithExtension = name;
534 
535             name = FileUtil.stripExtension(nameWithExtension);
536 
537             List<IGImage> images = igImagePersistence.findByF_N(
538                 parentFolderId, name);
539 
540             for (IGImage image : images) {
541                 if (nameWithExtension.equals(image.getNameWithExtension())) {
542                     throw new DuplicateFolderNameException();
543                 }
544             }
545         }
546     }
547 
548     private static Log _log = LogFactory.getLog(IGFolderLocalServiceImpl.class);
549 
550 }