001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.util.ArrayUtil;
020    import com.liferay.portal.kernel.util.LocaleUtil;
021    import com.liferay.portal.kernel.util.OrderByComparator;
022    import com.liferay.portal.kernel.util.ParamUtil;
023    import com.liferay.portal.kernel.util.SortedArrayList;
024    import com.liferay.portal.model.User;
025    import com.liferay.portal.service.ServiceContext;
026    import com.liferay.portal.util.PortalUtil;
027    import com.liferay.portlet.documentlibrary.DuplicateFileEntryTypeException;
028    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
029    import com.liferay.portlet.documentlibrary.NoSuchMetadataSetException;
030    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
031    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
032    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
033    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
034    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
035    import com.liferay.portlet.documentlibrary.model.DLFolder;
036    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
037    import com.liferay.portlet.documentlibrary.service.base.DLFileEntryTypeLocalServiceBaseImpl;
038    import com.liferay.portlet.documentlibrary.util.DLUtil;
039    import com.liferay.portlet.dynamicdatamapping.StructureXsdException;
040    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
041    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
042    
043    import java.util.ArrayList;
044    import java.util.Date;
045    import java.util.HashMap;
046    import java.util.List;
047    import java.util.Locale;
048    import java.util.Map;
049    
050    /**
051     * @author Alexander Chow
052     * @author Sergio González
053     */
054    public class DLFileEntryTypeLocalServiceImpl
055            extends DLFileEntryTypeLocalServiceBaseImpl {
056    
057            public DLFileEntryType addFileEntryType(
058                            long userId, long groupId, String name, String description,
059                            long[] ddmStructureIds, ServiceContext serviceContext)
060                    throws PortalException, SystemException {
061    
062                    User user = userPersistence.findByPrimaryKey(userId);
063    
064                    long fileEntryTypeId = counterLocalService.increment();
065    
066                    long dynamicStructureId = updateDynamicStructure(
067                            userId, fileEntryTypeId, groupId, name, description,
068                            serviceContext);
069    
070                    if (dynamicStructureId > 0) {
071                            ddmStructureIds = ArrayUtil.append(
072                                    ddmStructureIds, dynamicStructureId);
073                    }
074    
075                    Date now = new Date();
076    
077                    validate(fileEntryTypeId, groupId, name, ddmStructureIds);
078    
079                    DLFileEntryType dlFileEntryType = dlFileEntryTypePersistence.create(
080                            fileEntryTypeId);
081    
082                    dlFileEntryType.setUuid(serviceContext.getUuid());
083                    dlFileEntryType.setGroupId(groupId);
084                    dlFileEntryType.setCompanyId(user.getCompanyId());
085                    dlFileEntryType.setUserId(user.getUserId());
086                    dlFileEntryType.setUserName(user.getFullName());
087                    dlFileEntryType.setCreateDate(serviceContext.getCreateDate(now));
088                    dlFileEntryType.setModifiedDate(serviceContext.getModifiedDate(now));
089                    dlFileEntryType.setName(name);
090                    dlFileEntryType.setDescription(description);
091    
092                    dlFileEntryTypePersistence.update(dlFileEntryType, false);
093    
094                    dlFileEntryTypePersistence.addDDMStructures(
095                            fileEntryTypeId, ddmStructureIds);
096    
097                    if (serviceContext.isAddGroupPermissions() ||
098                            serviceContext.isAddGuestPermissions()) {
099    
100                            addFileEntryTypeResources(
101                                    dlFileEntryType, serviceContext.isAddGroupPermissions(),
102                                    serviceContext.isAddGuestPermissions());
103                    }
104                    else {
105                            addFileEntryTypeResources(
106                                    dlFileEntryType, serviceContext.getGroupPermissions(),
107                                    serviceContext.getGuestPermissions());
108                    }
109    
110                    return dlFileEntryType;
111            }
112    
113            public void cascadeFileEntryTypes(long userId, DLFolder dlFolder)
114                    throws PortalException, SystemException {
115    
116                    List<DLFileEntryType> dlFileEntryTypes = getFolderFileEntryTypes(
117                            new long[] {dlFolder.getGroupId()}, dlFolder.getFolderId(), true);
118    
119                    List<Long> fileEntryTypeIds = getFileEntryTypeIds(dlFileEntryTypes);
120    
121                    long defaultFileEntryTypeId = getDefaultFileEntryTypeId(
122                            dlFolder.getFolderId());
123    
124                    ServiceContext serviceContext = new ServiceContext();
125    
126                    serviceContext.setCompanyId(dlFolder.getCompanyId());
127                    serviceContext.setScopeGroupId(dlFolder.getGroupId());
128                    serviceContext.setUserId(userId);
129    
130                    cascadeFileEntryTypes(
131                            dlFolder.getGroupId(), dlFolder.getFolderId(),
132                            defaultFileEntryTypeId, fileEntryTypeIds, serviceContext);
133            }
134    
135            public void deleteFileEntryType(DLFileEntryType dlFileEntryType)
136                    throws PortalException, SystemException {
137    
138                    DDMStructure ddmStructure = ddmStructureLocalService.fetchStructure(
139                            dlFileEntryType.getGroupId(),
140                            "auto_" + dlFileEntryType.getFileEntryTypeId());
141    
142                    if (ddmStructure != null) {
143                            ddmStructureLocalService.deleteStructure(
144                                    ddmStructure.getStructureId());
145                    }
146    
147                    dlFileEntryTypePersistence.remove(dlFileEntryType);
148            }
149    
150            public void deleteFileEntryType(long fileEntryTypeId)
151                    throws PortalException, SystemException {
152    
153                    DLFileEntryType dlFileEntryType =
154                            dlFileEntryTypePersistence.findByPrimaryKey(fileEntryTypeId);
155    
156                    deleteFileEntryType(dlFileEntryType);
157            }
158    
159            public void deleteFileEntryTypes(long groupId)
160                    throws PortalException, SystemException {
161    
162                    List<DLFileEntryType> dlFileEntryTypes =
163                            dlFileEntryTypePersistence.findByGroupId(groupId);
164    
165                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
166                            deleteFileEntryType(dlFileEntryType);
167                    }
168            }
169    
170            public DLFileEntryType fetchFileEntryType(long fileEntryTypeId)
171                    throws SystemException {
172    
173                    return dlFileEntryTypePersistence.fetchByPrimaryKey(fileEntryTypeId);
174            }
175    
176            public long getDefaultFileEntryTypeId(long folderId)
177                    throws PortalException, SystemException {
178    
179                    folderId = getFileEntryTypesPrimaryFolderId(folderId);
180    
181                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
182                            DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
183    
184                            return dlFolder.getDefaultFileEntryTypeId();
185                    }
186                    else {
187                            return 0;
188                    }
189            }
190    
191            public DLFileEntryType getFileEntryType(long fileEntryTypeId)
192                    throws PortalException, SystemException {
193    
194                    return dlFileEntryTypePersistence.findByPrimaryKey(fileEntryTypeId);
195            }
196    
197            public DLFileEntryType getFileEntryType(long groupId, String name)
198                    throws PortalException, SystemException {
199    
200                    return dlFileEntryTypePersistence.findByG_N(groupId, name);
201            }
202    
203            public List<DLFileEntryType> getFileEntryTypes(long[] groupIds)
204                    throws SystemException {
205    
206                    return dlFileEntryTypePersistence.findByGroupId(groupIds);
207            }
208    
209            public List<DLFileEntryType> getFolderFileEntryTypes(
210                            long[] groupIds, long folderId, boolean inherited)
211                    throws PortalException, SystemException {
212    
213                    if (!inherited) {
214                            return dlFolderPersistence.getDLFileEntryTypes(folderId);
215                    }
216    
217                    List<DLFileEntryType> dlFileEntryTypes = null;
218    
219                    folderId = getFileEntryTypesPrimaryFolderId(folderId);
220    
221                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
222                            dlFileEntryTypes = dlFolderPersistence.getDLFileEntryTypes(
223                                    folderId);
224                    }
225    
226                    if ((dlFileEntryTypes == null) || dlFileEntryTypes.isEmpty()) {
227                            dlFileEntryTypes = new ArrayList<DLFileEntryType>(
228                                    getFileEntryTypes(groupIds));
229    
230                            DLFileEntryType dlFileEntryType =
231                                    dlFileEntryTypePersistence.fetchByPrimaryKey(
232                                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
233    
234                            dlFileEntryTypes.add(0, dlFileEntryType);
235                    }
236    
237                    return dlFileEntryTypes;
238            }
239    
240            public List<DLFileEntryType> search(
241                            long companyId, long[] groupIds, String keywords,
242                            boolean includeBasicFileEntryType, int start, int end,
243                            OrderByComparator orderByComparator)
244                    throws SystemException {
245    
246                    return dlFileEntryTypeFinder.findByKeywords(
247                            companyId, groupIds, keywords, includeBasicFileEntryType, start,
248                            end, orderByComparator);
249            }
250    
251            public int searchCount(
252                            long companyId, long[] groupIds, String keywords,
253                            boolean includeBasicFileEntryType)
254                    throws SystemException {
255    
256                    return dlFileEntryTypeFinder.countByKeywords(
257                            companyId, groupIds, keywords, includeBasicFileEntryType);
258            }
259    
260            public void unsetFolderFileEntryTypes(long folderId)
261                    throws SystemException {
262    
263                    List<DLFileEntryType> dlFileEntryTypes =
264                            dlFolderPersistence.getDLFileEntryTypes(folderId);
265    
266                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
267                            dlFolderPersistence.removeDLFileEntryType(
268                                    folderId, dlFileEntryType);
269                    }
270            }
271    
272            public DLFileEntry updateFileEntryFileEntryType(
273                            DLFileEntry dlFileEntry, ServiceContext serviceContext)
274                    throws PortalException, SystemException {
275    
276                    long groupId = serviceContext.getScopeGroupId();
277                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
278    
279                    DLFolder dlFolder = dlFolderPersistence.fetchByPrimaryKey(
280                            dlFileEntry.getFolderId());
281    
282                    if (dlFolder != null) {
283                            groupId = dlFolder.getGroupId();
284                            folderId = dlFolder.getFolderId();
285                    }
286    
287                    List<DLFileEntryType> dlFileEntryTypes = getFolderFileEntryTypes(
288                            DLUtil.getGroupIds(groupId), folderId, true);
289    
290                    List<Long> fileEntryTypeIds = getFileEntryTypeIds(dlFileEntryTypes);
291    
292                    if (fileEntryTypeIds.contains(dlFileEntry.getFileEntryTypeId())) {
293                            return dlFileEntry;
294                    }
295    
296                    long defaultFileEntryTypeId = getDefaultFileEntryTypeId(folderId);
297    
298                    DLFileVersion dlFileVersion =
299                            dlFileVersionLocalService.getLatestFileVersion(
300                                    dlFileEntry.getFileEntryId(), true);
301    
302                    if (dlFileVersion.isPending()) {
303                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
304                                    dlFileVersion.getCompanyId(), dlFileEntry.getGroupId(),
305                                    DLFileEntry.class.getName(), dlFileVersion.getFileVersionId());
306                    }
307    
308                    return dlFileEntryLocalService.updateFileEntry(
309                            serviceContext.getUserId(), dlFileEntry.getFileEntryId(), null,
310                            null, null, null, null, false, defaultFileEntryTypeId, null, null,
311                            null, 0, serviceContext);
312            }
313    
314            public void updateFileEntryType(
315                            long userId, long fileEntryTypeId, String name, String description,
316                            long[] ddmStructureIds, ServiceContext serviceContext)
317                    throws PortalException, SystemException {
318    
319                    DLFileEntryType dlFileEntryType =
320                            dlFileEntryTypePersistence.findByPrimaryKey(fileEntryTypeId);
321    
322                    long dynamicStructureId = updateDynamicStructure(
323                            userId, fileEntryTypeId, dlFileEntryType.getGroupId(), name,
324                            description, serviceContext);
325    
326                    if (dynamicStructureId > 0) {
327                            ddmStructureIds = ArrayUtil.append(
328                                    ddmStructureIds, dynamicStructureId);
329                    }
330    
331                    validate(
332                            fileEntryTypeId, dlFileEntryType.getGroupId(), name,
333                            ddmStructureIds);
334    
335                    dlFileEntryType.setModifiedDate(serviceContext.getModifiedDate(null));
336                    dlFileEntryType.setName(name);
337                    dlFileEntryType.setDescription(description);
338    
339                    dlFileEntryTypePersistence.update(dlFileEntryType, false);
340    
341                    dlFileEntryTypePersistence.setDDMStructures(
342                            fileEntryTypeId, ddmStructureIds);
343            }
344    
345            public void updateFolderFileEntryTypes(
346                            DLFolder dlFolder, List<Long> fileEntryTypeIds,
347                            long defaultFileEntryTypeId, ServiceContext serviceContext)
348                    throws PortalException, SystemException {
349    
350                    List<Long> originalFileEntryTypeIds = getFileEntryTypeIds(
351                            dlFolderPersistence.getDLFileEntryTypes(dlFolder.getFolderId()));
352    
353                    if (fileEntryTypeIds.equals(originalFileEntryTypeIds)) {
354                            return;
355                    }
356    
357                    for (Long fileEntryTypeId : fileEntryTypeIds) {
358                            if (!originalFileEntryTypeIds.contains(fileEntryTypeId)) {
359                                    dlFolderPersistence.addDLFileEntryType(
360                                            dlFolder.getFolderId(), fileEntryTypeId);
361                            }
362                    }
363    
364                    for (Long originalFileEntryTypeId : originalFileEntryTypeIds) {
365                            if (!fileEntryTypeIds.contains(originalFileEntryTypeId)) {
366                                    dlFolderPersistence.removeDLFileEntryType(
367                                            dlFolder.getFolderId(), originalFileEntryTypeId);
368    
369                                    workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
370                                            dlFolder.getCompanyId(), dlFolder.getGroupId(),
371                                            DLFolder.class.getName(), dlFolder.getFolderId(),
372                                            originalFileEntryTypeId);
373                            }
374                    }
375            }
376    
377            protected void addFileEntryTypeResources(
378                            DLFileEntryType dlFileEntryType, boolean addGroupPermissions,
379                            boolean addGuestPermissions)
380                    throws PortalException, SystemException {
381    
382                    resourceLocalService.addResources(
383                            dlFileEntryType.getCompanyId(), dlFileEntryType.getGroupId(),
384                            dlFileEntryType.getUserId(), DLFileEntryType.class.getName(),
385                            dlFileEntryType.getFileEntryTypeId(), false, addGroupPermissions,
386                            addGuestPermissions);
387            }
388    
389            protected void addFileEntryTypeResources(
390                            DLFileEntryType dlFileEntryType, String[] groupPermissions,
391                            String[] guestPermissions)
392                    throws PortalException, SystemException {
393    
394                    resourceLocalService.addModelResources(
395                            dlFileEntryType.getCompanyId(), dlFileEntryType.getGroupId(),
396                            dlFileEntryType.getUserId(), DLFileEntryType.class.getName(),
397                            dlFileEntryType.getFileEntryTypeId(), groupPermissions,
398                            guestPermissions);
399            }
400    
401            protected void cascadeFileEntryTypes(
402                            long groupId, long folderId, long defaultFileEntryTypeId,
403                            List<Long> fileEntryTypeIds, ServiceContext serviceContext)
404                    throws PortalException, SystemException {
405    
406                    List<DLFileEntry> dlFileEntries = dlFileEntryPersistence.findByG_F(
407                            groupId, folderId);
408    
409                    for (DLFileEntry dlFileEntry : dlFileEntries) {
410                            Long fileEntryTypeId = dlFileEntry.getFileEntryTypeId();
411    
412                            if (fileEntryTypeIds.contains(fileEntryTypeId)) {
413                                    continue;
414                            }
415    
416                            DLFileVersion dlFileVersion =
417                                    dlFileVersionLocalService.getLatestFileVersion(
418                                            dlFileEntry.getFileEntryId(), true);
419    
420                            if (dlFileVersion.isPending()) {
421                                    workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
422                                            dlFileVersion.getCompanyId(), groupId,
423                                            DLFileEntry.class.getName(),
424                                            dlFileVersion.getFileVersionId());
425                            }
426    
427                            dlFileEntryService.updateFileEntry(
428                                    dlFileEntry.getFileEntryId(), null, null, null, null, null,
429                                    false, defaultFileEntryTypeId, null, null, null, 0,
430                                    serviceContext);
431                    }
432    
433                    List<DLFolder> subFolders = dlFolderPersistence.findByG_P_M(
434                            groupId, folderId, false);
435    
436                    for (DLFolder subFolder : subFolders) {
437                            long subFolderId = subFolder.getFolderId();
438    
439                            if (subFolder.isOverrideFileEntryTypes()) {
440                                    continue;
441                            }
442    
443                            cascadeFileEntryTypes(
444                                    groupId, subFolderId, defaultFileEntryTypeId, fileEntryTypeIds,
445                                    serviceContext);
446                    }
447            }
448    
449            protected List<Long> getFileEntryTypeIds(
450                    List<DLFileEntryType> dlFileEntryTypes) {
451    
452                    List<Long> fileEntryTypeIds = new SortedArrayList<Long>();
453    
454                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
455                            fileEntryTypeIds.add(dlFileEntryType.getFileEntryTypeId());
456                    }
457    
458                    return fileEntryTypeIds;
459            }
460    
461            protected long getFileEntryTypesPrimaryFolderId(long folderId)
462                    throws SystemException, NoSuchFolderException {
463    
464                    while (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
465                            DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
466    
467                            if (dlFolder.isOverrideFileEntryTypes()) {
468                                    break;
469                            }
470    
471                            folderId = dlFolder.getParentFolderId();
472                    }
473    
474                    return folderId;
475            }
476    
477            protected long updateDynamicStructure(
478                            long userId, long fileEntryTypeId, long groupId, String name,
479                            String description, ServiceContext serviceContext)
480                    throws SystemException, PortalException {
481    
482                    String ddmStructureKey = "auto_" + fileEntryTypeId;
483    
484                    Map<Locale, String> nameMap = new HashMap<Locale, String>();
485    
486                    Locale locale = serviceContext.getLocale();
487    
488                    nameMap.put(locale, name);
489    
490                    Locale defaultLocale = LocaleUtil.getDefault();
491    
492                    nameMap.put(defaultLocale, name);
493    
494                    Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
495    
496                    descriptionMap.put(locale, description);
497                    descriptionMap.put(defaultLocale, description);
498    
499                    String xsd = ParamUtil.getString(serviceContext, "xsd");
500    
501                    DDMStructure ddmStructure = ddmStructureLocalService.fetchStructure(
502                            groupId, ddmStructureKey);
503    
504                    try {
505                            if (ddmStructure == null) {
506                                    ddmStructure = ddmStructureLocalService.addStructure(
507                                            userId, groupId,
508                                            PortalUtil.getClassNameId(DLFileEntryMetadata.class),
509                                            ddmStructureKey, nameMap, descriptionMap, xsd, "xml",
510                                            DDMStructureConstants.TYPE_AUTO, serviceContext);
511                            }
512                            else {
513                                    ddmStructure = ddmStructureLocalService.updateStructure(
514                                            ddmStructure.getStructureId(), nameMap, descriptionMap, xsd,
515                                            serviceContext);
516                            }
517    
518                            return ddmStructure.getStructureId();
519                    }
520                    catch (StructureXsdException sxe) {
521                            if (ddmStructure != null) {
522                                    ddmStructureLocalService.deleteStructure(
523                                            ddmStructure.getStructureId());
524                            }
525                    }
526    
527                    return 0;
528            }
529    
530            protected void validate(
531                            long fileEntryTypeId, long groupId, String fileEntryTypeName,
532                            long[] ddmStructureIds)
533                    throws PortalException, SystemException {
534    
535                    DLFileEntryType dlFileEntryType = dlFileEntryTypePersistence.fetchByG_N(
536                            groupId, fileEntryTypeName);
537    
538                    if ((dlFileEntryType != null) &&
539                            (dlFileEntryType.getFileEntryTypeId() != fileEntryTypeId)) {
540    
541                            throw new DuplicateFileEntryTypeException(fileEntryTypeName);
542                    }
543    
544                    if (ddmStructureIds.length == 0) {
545                            throw new NoSuchMetadataSetException();
546                    }
547    
548                    for (long ddmStructureId : ddmStructureIds) {
549                            DDMStructure ddmStructure =
550                                    ddmStructurePersistence.fetchByPrimaryKey(ddmStructureId);
551    
552                            if (ddmStructure == null) {
553                                    throw new NoSuchMetadataSetException();
554                            }
555                    }
556            }
557    
558    }