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