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.search.BooleanClauseOccur;
25  import com.liferay.portal.kernel.search.BooleanQuery;
26  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
27  import com.liferay.portal.kernel.search.Field;
28  import com.liferay.portal.kernel.search.Hits;
29  import com.liferay.portal.kernel.search.SearchEngineUtil;
30  import com.liferay.portal.kernel.search.TermQuery;
31  import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
32  import com.liferay.portal.kernel.util.FileUtil;
33  import com.liferay.portal.kernel.util.GetterUtil;
34  import com.liferay.portal.kernel.util.StringPool;
35  import com.liferay.portal.kernel.util.Validator;
36  import com.liferay.portal.model.ResourceConstants;
37  import com.liferay.portal.model.User;
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  import com.liferay.portlet.tags.util.TagsUtil;
47  
48  import java.util.ArrayList;
49  import java.util.Date;
50  import java.util.List;
51  
52  /**
53   * <a href="IGFolderLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Brian Wing Shun Chan
56   *
57   */
58  public class IGFolderLocalServiceImpl extends IGFolderLocalServiceBaseImpl {
59  
60      public IGFolder addFolder(
61              long userId, long plid, long parentFolderId, String name,
62              String description, boolean addCommunityPermissions,
63              boolean addGuestPermissions)
64          throws PortalException, SystemException {
65  
66          return addFolder(
67              null, userId, plid, parentFolderId, name, description,
68              Boolean.valueOf(addCommunityPermissions),
69              Boolean.valueOf(addGuestPermissions), null, null);
70      }
71  
72      public IGFolder addFolder(
73              String uuid, long userId, long plid, long parentFolderId,
74              String name, String description, boolean addCommunityPermissions,
75              boolean addGuestPermissions)
76          throws PortalException, SystemException {
77  
78          return addFolder(
79              uuid, userId, plid, parentFolderId, name, description,
80              Boolean.valueOf(addCommunityPermissions),
81              Boolean.valueOf(addGuestPermissions), null, null);
82      }
83  
84      public IGFolder addFolder(
85              long userId, long plid, long parentFolderId, String name,
86              String description, String[] communityPermissions,
87              String[] guestPermissions)
88          throws PortalException, SystemException {
89  
90          return addFolder(
91              null, userId, plid, parentFolderId, name, description, null, null,
92              communityPermissions, guestPermissions);
93      }
94  
95      public IGFolder addFolder(
96              String uuid, long userId, long plid, long parentFolderId,
97              String name, String description, Boolean addCommunityPermissions,
98              Boolean addGuestPermissions, String[] communityPermissions,
99              String[] guestPermissions)
100         throws PortalException, SystemException {
101 
102         long groupId = PortalUtil.getScopeGroupId(plid);
103 
104         return addFolderToGroup(
105             uuid, userId, groupId, parentFolderId, name, description,
106             addCommunityPermissions, addGuestPermissions, communityPermissions,
107             guestPermissions);
108     }
109 
110     public IGFolder addFolderToGroup(
111             String uuid, long userId, long groupId, long parentFolderId,
112             String name, String description, Boolean addCommunityPermissions,
113             Boolean addGuestPermissions, String[] communityPermissions,
114             String[] guestPermissions)
115         throws PortalException, SystemException {
116 
117         // Folder
118 
119         User user = userPersistence.findByPrimaryKey(userId);
120         parentFolderId = getParentFolderId(groupId, parentFolderId);
121         Date now = new Date();
122 
123         validate(groupId, parentFolderId, name);
124 
125         long folderId = counterLocalService.increment();
126 
127         IGFolder folder = igFolderPersistence.create(folderId);
128 
129         folder.setUuid(uuid);
130         folder.setGroupId(groupId);
131         folder.setCompanyId(user.getCompanyId());
132         folder.setUserId(user.getUserId());
133         folder.setCreateDate(now);
134         folder.setModifiedDate(now);
135         folder.setParentFolderId(parentFolderId);
136         folder.setName(name);
137         folder.setDescription(description);
138 
139         igFolderPersistence.update(folder, false);
140 
141         // Resources
142 
143         if ((addCommunityPermissions != null) &&
144             (addGuestPermissions != null)) {
145 
146             addFolderResources(
147                 folder, addCommunityPermissions.booleanValue(),
148                 addGuestPermissions.booleanValue());
149         }
150         else {
151             addFolderResources(folder, communityPermissions, guestPermissions);
152         }
153 
154         return folder;
155     }
156 
157     public void addFolderResources(
158             long folderId, boolean addCommunityPermissions,
159             boolean addGuestPermissions)
160         throws PortalException, SystemException {
161 
162         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
163 
164         addFolderResources(
165             folder, addCommunityPermissions, addGuestPermissions);
166     }
167 
168     public void addFolderResources(
169             IGFolder folder, boolean addCommunityPermissions,
170             boolean addGuestPermissions)
171         throws PortalException, SystemException {
172 
173         resourceLocalService.addResources(
174             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
175             IGFolder.class.getName(), folder.getFolderId(), false,
176             addCommunityPermissions, addGuestPermissions);
177     }
178 
179     public void addFolderResources(
180             long folderId, String[] communityPermissions,
181             String[] guestPermissions)
182         throws PortalException, SystemException {
183 
184         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
185 
186         addFolderResources(folder, communityPermissions, guestPermissions);
187     }
188 
189     public void addFolderResources(
190             IGFolder folder, String[] communityPermissions,
191             String[] guestPermissions)
192         throws PortalException, SystemException {
193 
194         resourceLocalService.addModelResources(
195             folder.getCompanyId(), folder.getGroupId(), folder.getUserId(),
196             IGFolder.class.getName(), folder.getFolderId(),
197             communityPermissions, guestPermissions);
198     }
199 
200     public void deleteFolder(long folderId)
201         throws PortalException, SystemException {
202 
203         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
204 
205         deleteFolder(folder);
206     }
207 
208     public void deleteFolder(IGFolder folder)
209         throws PortalException, SystemException {
210 
211         // Folders
212 
213         List<IGFolder> folders = igFolderPersistence.findByG_P(
214             folder.getGroupId(), folder.getFolderId());
215 
216         for (IGFolder curFolder : folders) {
217             deleteFolder(curFolder);
218         }
219 
220         // Images
221 
222         igImageLocalService.deleteImages(folder.getFolderId());
223 
224         // Resources
225 
226         resourceLocalService.deleteResource(
227             folder.getCompanyId(), IGFolder.class.getName(),
228             ResourceConstants.SCOPE_INDIVIDUAL, folder.getFolderId());
229 
230         // Folder
231 
232         igFolderPersistence.remove(folder);
233     }
234 
235     public void deleteFolders(long groupId)
236         throws PortalException, SystemException {
237 
238         List<IGFolder> folders = igFolderPersistence.findByG_P(
239             groupId, IGFolderImpl.DEFAULT_PARENT_FOLDER_ID);
240 
241         for (IGFolder folder : folders) {
242             deleteFolder(folder);
243         }
244     }
245 
246     public IGFolder getFolder(long folderId)
247         throws PortalException, SystemException {
248 
249         return igFolderPersistence.findByPrimaryKey(folderId);
250     }
251 
252     public IGFolder getFolder(long groupId, long parentFolderId, String name)
253         throws PortalException, SystemException {
254 
255         return igFolderPersistence.findByG_P_N(groupId, parentFolderId, name);
256     }
257 
258     public List<IGFolder> getFolders(long groupId) throws SystemException {
259         return igFolderPersistence.findByGroupId(groupId);
260     }
261 
262     public List<IGFolder> getFolders(long groupId, long parentFolderId)
263         throws SystemException {
264 
265         return igFolderPersistence.findByG_P(groupId, parentFolderId);
266     }
267 
268     public List<IGFolder> getFolders(
269             long groupId, long parentFolderId, int start, int end)
270         throws SystemException {
271 
272         return igFolderPersistence.findByG_P(
273             groupId, parentFolderId, start, end);
274     }
275 
276     public int getFoldersCount(long groupId, long parentFolderId)
277         throws SystemException {
278 
279         return igFolderPersistence.countByG_P(groupId, parentFolderId);
280     }
281 
282     public void getSubfolderIds(
283             List<Long> folderIds, long groupId, long folderId)
284         throws SystemException {
285 
286         List<IGFolder> folders = igFolderPersistence.findByG_P(
287             groupId, folderId);
288 
289         for (IGFolder folder : folders) {
290             folderIds.add(folder.getFolderId());
291 
292             getSubfolderIds(
293                 folderIds, folder.getGroupId(), folder.getFolderId());
294         }
295     }
296 
297     public void reIndex(String[] ids) throws SystemException {
298         if (SearchEngineUtil.isIndexReadOnly()) {
299             return;
300         }
301 
302         long companyId = GetterUtil.getLong(ids[0]);
303 
304         try {
305             reIndexFolders(companyId);
306         }
307         catch (SystemException se) {
308             throw se;
309         }
310         catch (Exception e) {
311             throw new SystemException(e);
312         }
313     }
314 
315     public Hits search(
316             long companyId, long groupId, long[] folderIds, String keywords,
317             int start, int end)
318         throws SystemException {
319 
320         try {
321             BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
322 
323             contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
324 
325             if (groupId > 0) {
326                 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
327             }
328 
329             if ((folderIds != null) && (folderIds.length > 0)) {
330                 BooleanQuery folderIdsQuery = BooleanQueryFactoryUtil.create();
331 
332                 for (long folderId : folderIds) {
333                     TermQuery termQuery = TermQueryFactoryUtil.create(
334                         "folderId", folderId);
335 
336                     folderIdsQuery.add(termQuery, BooleanClauseOccur.SHOULD);
337                 }
338 
339                 contextQuery.add(folderIdsQuery, BooleanClauseOccur.MUST);
340             }
341 
342             BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
343 
344             if (Validator.isNotNull(keywords)) {
345                 searchQuery.addTerm(Field.TITLE, keywords);
346                 searchQuery.addTerm(Field.DESCRIPTION, keywords);
347                 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords);
348             }
349 
350             BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
351 
352             fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
353 
354             if (searchQuery.clauses().size() > 0) {
355                 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
356             }
357 
358             return SearchEngineUtil.search(companyId, fullQuery, start, end);
359         }
360         catch (Exception e) {
361             throw new SystemException(e);
362         }
363     }
364 
365     public IGFolder updateFolder(
366             long folderId, long parentFolderId, String name, String description,
367             boolean mergeWithParentFolder)
368         throws PortalException, SystemException {
369 
370         // Folder
371 
372         IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
373 
374         parentFolderId = getParentFolderId(folder, parentFolderId);
375 
376         validate(
377             folder.getFolderId(), folder.getGroupId(), parentFolderId, name);
378 
379         folder.setModifiedDate(new Date());
380         folder.setParentFolderId(parentFolderId);
381         folder.setName(name);
382         folder.setDescription(description);
383 
384         igFolderPersistence.update(folder, false);
385 
386         // Merge folders
387 
388         if (mergeWithParentFolder && (folderId != parentFolderId) &&
389             (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID)) {
390 
391             mergeFolders(folder, parentFolderId);
392         }
393 
394         return folder;
395     }
396 
397     protected long getParentFolderId(long groupId, long parentFolderId)
398         throws SystemException {
399 
400         if (parentFolderId != IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
401             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
402                 parentFolderId);
403 
404             if ((parentFolder == null) ||
405                 (groupId != parentFolder.getGroupId())) {
406 
407                 parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
408             }
409         }
410 
411         return parentFolderId;
412     }
413 
414     protected long getParentFolderId(IGFolder folder, long parentFolderId)
415         throws SystemException {
416 
417         if (parentFolderId == IGFolderImpl.DEFAULT_PARENT_FOLDER_ID) {
418             return parentFolderId;
419         }
420 
421         if (folder.getFolderId() == parentFolderId) {
422             return folder.getParentFolderId();
423         }
424         else {
425             IGFolder parentFolder = igFolderPersistence.fetchByPrimaryKey(
426                 parentFolderId);
427 
428             if ((parentFolder == null) ||
429                 (folder.getGroupId() != parentFolder.getGroupId())) {
430 
431                 return folder.getParentFolderId();
432             }
433 
434             List<Long> subfolderIds = new ArrayList<Long>();
435 
436             getSubfolderIds(
437                 subfolderIds, folder.getGroupId(), folder.getFolderId());
438 
439             if (subfolderIds.contains(parentFolderId)) {
440                 return folder.getParentFolderId();
441             }
442 
443             return parentFolderId;
444         }
445     }
446 
447     protected void mergeFolders(IGFolder fromFolder, long toFolderId)
448         throws PortalException, SystemException {
449 
450         List<IGFolder> folders = igFolderPersistence.findByG_P(
451             fromFolder.getGroupId(), fromFolder.getFolderId());
452 
453         for (IGFolder folder : folders) {
454             mergeFolders(folder, toFolderId);
455         }
456 
457         List<IGImage> images = igImagePersistence.findByFolderId(
458             fromFolder.getFolderId());
459 
460         for (IGImage image : images) {
461             image.setFolderId(toFolderId);
462 
463             igImagePersistence.update(image, false);
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 }