001    /**
002     * Copyright (c) 2000-present 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.util;
016    
017    import com.liferay.document.library.kernel.model.DLFileEntry;
018    import com.liferay.document.library.kernel.model.DLFileEntryMetadata;
019    import com.liferay.document.library.kernel.model.DLFileEntryType;
020    import com.liferay.document.library.kernel.model.DLFileVersion;
021    import com.liferay.document.library.kernel.service.DLFileEntryMetadataLocalService;
022    import com.liferay.document.library.kernel.service.persistence.DLFileVersionPersistence;
023    import com.liferay.document.library.kernel.store.DLStoreUtil;
024    import com.liferay.document.library.kernel.util.DLFileVersionPolicy;
025    import com.liferay.dynamic.data.mapping.kernel.DDMFormValues;
026    import com.liferay.dynamic.data.mapping.kernel.DDMStructure;
027    import com.liferay.dynamic.data.mapping.kernel.StorageEngineManagerUtil;
028    import com.liferay.expando.kernel.model.ExpandoBridge;
029    import com.liferay.portal.kernel.bean.BeanReference;
030    import com.liferay.portal.kernel.exception.PortalException;
031    import com.liferay.portal.kernel.log.Log;
032    import com.liferay.portal.kernel.log.LogFactoryUtil;
033    import com.liferay.portal.kernel.service.ServiceContext;
034    import com.liferay.portal.kernel.util.Constants;
035    import com.liferay.portal.kernel.util.DigesterUtil;
036    import com.liferay.portal.kernel.util.StreamUtil;
037    import com.liferay.portal.kernel.util.Validator;
038    import com.liferay.portal.kernel.workflow.WorkflowConstants;
039    import com.liferay.portal.util.PropsValues;
040    import com.liferay.registry.collections.ServiceTrackerCollections;
041    import com.liferay.registry.collections.ServiceTrackerList;
042    
043    import java.io.InputStream;
044    import java.io.Serializable;
045    
046    import java.util.List;
047    import java.util.Map;
048    import java.util.Objects;
049    
050    /**
051     * @author Adolfo P??rez
052     */
053    public class DLFileVersionPolicyImpl implements DLFileVersionPolicy {
054    
055            public void destroy() {
056                    _serviceTrackerList.close();
057            }
058    
059            @Override
060            public boolean isKeepFileVersionLabel(
061                            DLFileVersion lastDLFileVersion, DLFileVersion latestDLFileVersion,
062                            boolean majorVersion, ServiceContext serviceContext)
063                    throws PortalException {
064    
065                    for (DLFileVersionPolicy dlFileVersionPolicy : _serviceTrackerList) {
066                            if ((dlFileVersionPolicy != this) &&
067                                    !dlFileVersionPolicy.isKeepFileVersionLabel(
068                                            lastDLFileVersion, latestDLFileVersion, majorVersion,
069                                            serviceContext)) {
070    
071                                    return false;
072                            }
073                    }
074    
075                    return isKeepFileVersionLabel(
076                            lastDLFileVersion.getFileEntry(), lastDLFileVersion,
077                            latestDLFileVersion, majorVersion, serviceContext);
078            }
079    
080            /**
081             * @see com.liferay.dynamic.data.lists.service.impl.DDLRecordLocalServiceImpl#isKeepRecordVersionLabel(
082             *      com.liferay.dynamic.data.lists.model.DDLRecordVersion,
083             *      com.liferay.dynamic.data.lists.model.DDLRecordVersion,
084             *      ServiceContext)
085             */
086            protected boolean isKeepFileVersionLabel(
087                            DLFileEntry dlFileEntry, DLFileVersion lastDLFileVersion,
088                            DLFileVersion latestDLFileVersion, boolean majorVersion,
089                            ServiceContext serviceContext)
090                    throws PortalException {
091    
092                    if (PropsValues.DL_FILE_ENTRY_VERSION_POLICY != 1) {
093                            return false;
094                    }
095    
096                    if (majorVersion) {
097                            return false;
098                    }
099    
100                    if (Objects.equals(serviceContext.getCommand(), Constants.REVERT)) {
101                            return false;
102                    }
103    
104                    if (!Objects.equals(
105                                    lastDLFileVersion.getTitle(), latestDLFileVersion.getTitle())) {
106    
107                            return false;
108                    }
109    
110                    if (!Objects.equals(
111                                    lastDLFileVersion.getDescription(),
112                                    latestDLFileVersion.getDescription())) {
113    
114                            return false;
115                    }
116    
117                    if (lastDLFileVersion.getFileEntryTypeId() !=
118                                    latestDLFileVersion.getFileEntryTypeId()) {
119    
120                            return false;
121                    }
122    
123                    if (serviceContext.getWorkflowAction() ==
124                                    WorkflowConstants.ACTION_SAVE_DRAFT) {
125    
126                            return false;
127                    }
128    
129                    // File entry type
130    
131                    DLFileEntryType dlFileEntryType =
132                            lastDLFileVersion.getDLFileEntryType();
133    
134                    List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
135    
136                    for (DDMStructure ddmStructure : ddmStructures) {
137                            DLFileEntryMetadata lastFileEntryMetadata =
138                                    dlFileEntryMetadataLocalService.fetchFileEntryMetadata(
139                                            ddmStructure.getStructureId(),
140                                            lastDLFileVersion.getFileVersionId());
141    
142                            if (lastFileEntryMetadata == null) {
143                                    return false;
144                            }
145    
146                            DLFileEntryMetadata latestFileEntryMetadata =
147                                    dlFileEntryMetadataLocalService.getFileEntryMetadata(
148                                            ddmStructure.getStructureId(),
149                                            latestDLFileVersion.getFileVersionId());
150    
151                            DDMFormValues lastDDMFormValues =
152                                    StorageEngineManagerUtil.getDDMFormValues(
153                                            lastFileEntryMetadata.getDDMStorageId());
154                            DDMFormValues latestDDMFormValues =
155                                    StorageEngineManagerUtil.getDDMFormValues(
156                                            latestFileEntryMetadata.getDDMStorageId());
157    
158                            if (!lastDDMFormValues.equals(latestDDMFormValues)) {
159                                    return false;
160                            }
161                    }
162    
163                    // Expando
164    
165                    ExpandoBridge lastExpandoBridge = lastDLFileVersion.getExpandoBridge();
166                    ExpandoBridge latestExpandoBridge =
167                            latestDLFileVersion.getExpandoBridge();
168    
169                    Map<String, Serializable> lastAttributes =
170                            lastExpandoBridge.getAttributes();
171                    Map<String, Serializable> latestAttributes =
172                            latestExpandoBridge.getAttributes();
173    
174                    if (!lastAttributes.equals(latestAttributes)) {
175                            return false;
176                    }
177    
178                    // Size
179    
180                    long lastSize = lastDLFileVersion.getSize();
181                    long latestSize = latestDLFileVersion.getSize();
182    
183                    if ((lastSize == 0) && (latestSize >= 0)) {
184                            return true;
185                    }
186    
187                    if (lastSize != latestSize) {
188                            return false;
189                    }
190    
191                    // Checksum
192    
193                    InputStream lastInputStream = null;
194                    InputStream latestInputStream = null;
195    
196                    try {
197                            String lastChecksum = lastDLFileVersion.getChecksum();
198    
199                            if (Validator.isNull(lastChecksum)) {
200                                    lastInputStream = DLStoreUtil.getFileAsStream(
201                                            dlFileEntry.getCompanyId(),
202                                            dlFileEntry.getDataRepositoryId(), dlFileEntry.getName(),
203                                            lastDLFileVersion.getVersion());
204    
205                                    lastChecksum = DigesterUtil.digestBase64(lastInputStream);
206    
207                                    lastDLFileVersion.setChecksum(lastChecksum);
208    
209                                    dlFileVersionPersistence.update(lastDLFileVersion);
210                            }
211    
212                            latestInputStream = DLStoreUtil.getFileAsStream(
213                                    dlFileEntry.getCompanyId(), dlFileEntry.getDataRepositoryId(),
214                                    dlFileEntry.getName(), latestDLFileVersion.getVersion());
215    
216                            String latestChecksum = DigesterUtil.digestBase64(
217                                    latestInputStream);
218    
219                            if (lastChecksum.equals(latestChecksum)) {
220                                    return true;
221                            }
222    
223                            latestDLFileVersion.setChecksum(latestChecksum);
224    
225                            dlFileVersionPersistence.update(latestDLFileVersion);
226                    }
227                    catch (Exception e) {
228                            if (_log.isWarnEnabled()) {
229                                    _log.warn(e, e);
230                            }
231                    }
232                    finally {
233                            StreamUtil.cleanUp(lastInputStream);
234                            StreamUtil.cleanUp(latestInputStream);
235                    }
236    
237                    return false;
238            }
239    
240            @BeanReference(type = DLFileEntryMetadataLocalService.class)
241            protected DLFileEntryMetadataLocalService dlFileEntryMetadataLocalService;
242    
243            @BeanReference(type = DLFileVersionPersistence.class)
244            protected DLFileVersionPersistence dlFileVersionPersistence;
245    
246            private static final Log _log = LogFactoryUtil.getLog(
247                    DLFileVersionPolicyImpl.class);
248    
249            private final ServiceTrackerList<DLFileVersionPolicy> _serviceTrackerList =
250                    ServiceTrackerCollections.openList(DLFileVersionPolicy.class);
251    
252    }