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