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