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