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