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