001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.service.ServiceContextUtil;
027    import com.liferay.portal.util.PortalUtil;
028    import com.liferay.portlet.documentlibrary.DuplicateFileEntryTypeException;
029    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
030    import com.liferay.portlet.documentlibrary.NoSuchMetadataSetException;
031    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
032    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
033    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
034    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
035    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
036    import com.liferay.portlet.documentlibrary.model.DLFolder;
037    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
038    import com.liferay.portlet.documentlibrary.service.base.DLFileEntryTypeLocalServiceBaseImpl;
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.getAddGroupPermissions() ||
098                             serviceContext.getAddGuestPermissions()) {
099    
100                            addFileEntryTypeResources(
101                                    dlFileEntryType, serviceContext.getAddGroupPermissions(),
102                                    serviceContext.getAddGuestPermissions());
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                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(
277                            dlFileEntry.getFolderId());
278    
279                    List<DLFileEntryType> dlFileEntryTypes = getFolderFileEntryTypes(
280                            new long[] {dlFolder.getGroupId()}, dlFolder.getFolderId(), true);
281    
282                    List<Long> fileEntryTypeIds = getFileEntryTypeIds(dlFileEntryTypes);
283    
284                    if (fileEntryTypeIds.contains(dlFileEntry.getFileEntryTypeId())) {
285                            return dlFileEntry;
286                    }
287    
288                    long defaultFileEntryTypeId = getDefaultFileEntryTypeId(
289                            dlFolder.getFolderId());
290    
291                    DLFileVersion dlFileVersion =
292                            dlFileVersionLocalService.getLatestFileVersion(
293                                    dlFileEntry.getFileEntryId(), true);
294    
295                    if (dlFileVersion.isPending()) {
296                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
297                                    dlFileVersion.getCompanyId(), dlFileEntry.getGroupId(),
298                                    DLFileEntry.class.getName(),
299                                    dlFileVersion.getFileVersionId());
300                    }
301    
302                    return dlFileEntryLocalService.updateFileEntry(
303                            serviceContext.getUserId(), dlFileEntry.getFileEntryId(), null,
304                            null, null, null, null, false, defaultFileEntryTypeId, null, null,
305                            null, 0, serviceContext);
306            }
307    
308            public void updateFileEntryType(
309                            long userId, long fileEntryTypeId, String name, String description,
310                            long[] ddmStructureIds, ServiceContext serviceContext)
311                    throws PortalException, SystemException {
312    
313                    DLFileEntryType dlFileEntryType =
314                            dlFileEntryTypePersistence.findByPrimaryKey(fileEntryTypeId);
315    
316                    long dynamicStructureId = updateDynamicStructure(
317                            userId, fileEntryTypeId, dlFileEntryType.getGroupId(), name,
318                            description, serviceContext);
319    
320                    if (dynamicStructureId > 0) {
321                            ddmStructureIds = ArrayUtil.append(
322                                    ddmStructureIds, dynamicStructureId);
323                    }
324    
325                    validate(
326                            fileEntryTypeId, dlFileEntryType.getGroupId(), name,
327                            ddmStructureIds);
328    
329                    dlFileEntryType.setModifiedDate(serviceContext.getModifiedDate(null));
330                    dlFileEntryType.setName(name);
331                    dlFileEntryType.setDescription(description);
332    
333                    dlFileEntryTypePersistence.update(dlFileEntryType, false);
334    
335                    dlFileEntryTypePersistence.setDDMStructures(
336                            fileEntryTypeId, ddmStructureIds);
337            }
338    
339            public void updateFolderFileEntryTypes(
340                            DLFolder dlFolder, List<Long> fileEntryTypeIds,
341                            long defaultFileEntryTypeId, ServiceContext serviceContext)
342                    throws PortalException, SystemException {
343    
344                    List<Long> originalFileEntryTypeIds = getFileEntryTypeIds(
345                            dlFolderPersistence.getDLFileEntryTypes(dlFolder.getFolderId()));
346    
347                    if (fileEntryTypeIds.equals(originalFileEntryTypeIds)) {
348                            return;
349                    }
350    
351                    for (Long fileEntryTypeId : fileEntryTypeIds) {
352                            if (!originalFileEntryTypeIds.contains(fileEntryTypeId)) {
353                                    dlFolderPersistence.addDLFileEntryType(
354                                            dlFolder.getFolderId(), fileEntryTypeId);
355                            }
356                    }
357    
358                    for (Long originalFileEntryTypeId : originalFileEntryTypeIds) {
359                            if (!fileEntryTypeIds.contains(originalFileEntryTypeId)) {
360                                    dlFolderPersistence.removeDLFileEntryType(
361                                            dlFolder.getFolderId(), originalFileEntryTypeId);
362    
363                                    workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
364                                            dlFolder.getCompanyId(), dlFolder.getGroupId(),
365                                            DLFolder.class.getName(), dlFolder.getFolderId(),
366                                            originalFileEntryTypeId);
367                            }
368                    }
369            }
370    
371            protected void addFileEntryTypeResources(
372                            DLFileEntryType dlFileEntryType, boolean addGroupPermissions,
373                            boolean addGuestPermissions)
374                    throws PortalException, SystemException {
375    
376                    resourceLocalService.addResources(
377                            dlFileEntryType.getCompanyId(), dlFileEntryType.getGroupId(),
378                            dlFileEntryType.getUserId(), DLFileEntryType.class.getName(),
379                            dlFileEntryType.getFileEntryTypeId(), false, addGroupPermissions,
380                            addGuestPermissions);
381            }
382    
383            protected void addFileEntryTypeResources(
384                            DLFileEntryType dlFileEntryType, String[] groupPermissions,
385                            String[] guestPermissions)
386                    throws PortalException, SystemException {
387    
388                    resourceLocalService.addModelResources(
389                            dlFileEntryType.getCompanyId(), dlFileEntryType.getGroupId(),
390                            dlFileEntryType.getUserId(), DLFileEntryType.class.getName(),
391                            dlFileEntryType.getFileEntryTypeId(), groupPermissions,
392                            guestPermissions);
393            }
394    
395            protected void cascadeFileEntryTypes(
396                            long groupId, long folderId, long defaultFileEntryTypeId,
397                            List<Long> fileEntryTypeIds, ServiceContext serviceContext)
398                    throws PortalException, SystemException {
399    
400                    List<DLFileEntry> dlFileEntries = dlFileEntryPersistence.findByG_F(
401                            groupId, folderId);
402    
403                    for (DLFileEntry dlFileEntry : dlFileEntries) {
404                            Long fileEntryTypeId = dlFileEntry.getFileEntryTypeId();
405    
406                            if (fileEntryTypeIds.contains(fileEntryTypeId)) {
407                                    continue;
408                            }
409    
410                            DLFileVersion dlFileVersion =
411                                    dlFileVersionLocalService.getLatestFileVersion(
412                                            dlFileEntry.getFileEntryId(), true);
413    
414                            if (dlFileVersion.isPending()) {
415                                    workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
416                                            dlFileVersion.getCompanyId(), groupId,
417                                            DLFileEntry.class.getName(),
418                                            dlFileVersion.getFileVersionId());
419                            }
420    
421                            dlFileEntryService.updateFileEntry(
422                                    dlFileEntry.getFileEntryId(), null, null, null, null, null,
423                                    false, defaultFileEntryTypeId, null, null, null, 0,
424                                    serviceContext);
425                    }
426    
427                    List<DLFolder> subFolders = dlFolderPersistence.findByG_P_M(
428                            groupId, folderId, false);
429    
430                    for (DLFolder subFolder : subFolders) {
431                            long subFolderId = subFolder.getFolderId();
432    
433                            if (subFolder.isOverrideFileEntryTypes()) {
434                                    continue;
435                            }
436    
437                            cascadeFileEntryTypes(
438                                    groupId, subFolderId, defaultFileEntryTypeId, fileEntryTypeIds,
439                                    serviceContext);
440                    }
441            }
442    
443            protected List<Long> getFileEntryTypeIds(
444                    List<DLFileEntryType> dlFileEntryTypes) {
445    
446                    List<Long> fileEntryTypeIds = new SortedArrayList<Long>();
447    
448                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
449                            fileEntryTypeIds.add(dlFileEntryType.getFileEntryTypeId());
450                    }
451    
452                    return fileEntryTypeIds;
453            }
454    
455            protected long getFileEntryTypesPrimaryFolderId(long folderId)
456                    throws SystemException, NoSuchFolderException {
457    
458                    while (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
459                            DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
460    
461                            if (dlFolder.isOverrideFileEntryTypes()) {
462                                    break;
463                            }
464    
465                            folderId = dlFolder.getParentFolderId();
466                    }
467    
468                    return folderId;
469            }
470    
471            protected long updateDynamicStructure(
472                            long userId, long fileEntryTypeId, long groupId, String name,
473                            String description, ServiceContext serviceContext)
474                    throws SystemException, PortalException {
475    
476                    String ddmStructureKey = "auto_" + fileEntryTypeId;
477    
478                    Map<Locale, String> nameMap = new HashMap<Locale, String>();
479    
480                    Locale locale = ServiceContextUtil.getLocale(serviceContext);
481    
482                    nameMap.put(locale, name);
483    
484                    Locale defaultLocale = LocaleUtil.getDefault();
485    
486                    nameMap.put(defaultLocale, name);
487    
488                    Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
489    
490                    descriptionMap.put(locale, description);
491                    descriptionMap.put(defaultLocale, description);
492    
493                    String xsd = ParamUtil.getString(serviceContext, "xsd");
494    
495                    DDMStructure ddmStructure = ddmStructureLocalService.fetchStructure(
496                            groupId, ddmStructureKey);
497    
498                    try {
499                            if (ddmStructure == null) {
500                                    ddmStructure = ddmStructureLocalService.addStructure(
501                                            userId, groupId,
502                                            PortalUtil.getClassNameId(DLFileEntryMetadata.class),
503                                            ddmStructureKey, nameMap, descriptionMap, xsd, "xml",
504                                            DDMStructureConstants.TYPE_AUTO, serviceContext);
505                            }
506                            else {
507                                    ddmStructure = ddmStructureLocalService.updateStructure(
508                                            ddmStructure.getStructureId(), nameMap, descriptionMap, xsd,
509                                            serviceContext);
510                            }
511    
512                            return ddmStructure.getStructureId();
513                    }
514                    catch (StructureXsdException sxe) {
515                            if (ddmStructure != null) {
516                                    ddmStructureLocalService.deleteStructure(
517                                            ddmStructure.getStructureId());
518                            }
519                    }
520    
521                    return 0;
522            }
523    
524            protected void validate(
525                            long fileEntryTypeId, long groupId, String fileEntryTypeName,
526                            long[] ddmStructureIds)
527                    throws PortalException, SystemException {
528    
529                    DLFileEntryType dlFileEntryType = dlFileEntryTypePersistence.fetchByG_N(
530                            groupId, fileEntryTypeName);
531    
532                    if ((dlFileEntryType != null) &&
533                            (dlFileEntryType.getFileEntryTypeId() != fileEntryTypeId)) {
534    
535                            throw new DuplicateFileEntryTypeException(fileEntryTypeName);
536                    }
537    
538                    if (ddmStructureIds.length == 0) {
539                            throw new NoSuchMetadataSetException();
540                    }
541    
542                    for (long ddmStructureId : ddmStructureIds) {
543                            DDMStructure ddmStructure =
544                                    ddmStructurePersistence.fetchByPrimaryKey(ddmStructureId);
545    
546                            if (ddmStructure == null) {
547                                    throw new NoSuchMetadataSetException();
548                            }
549                    }
550            }
551    
552    }