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