001    /**
002     * Copyright (c) 2000-2013 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.portal.verify;
016    
017    import com.liferay.counter.service.CounterLocalServiceUtil;
018    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.Criterion;
020    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
022    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.repository.model.FileEntry;
028    import com.liferay.portal.kernel.repository.model.FileVersion;
029    import com.liferay.portal.kernel.util.ContentTypes;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.ListUtil;
032    import com.liferay.portal.kernel.util.MimeTypesUtil;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
036    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
037    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
038    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
039    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
040    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
041    import com.liferay.portlet.documentlibrary.service.DLAppHelperLocalServiceUtil;
042    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
043    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
044    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
045    import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryActionableDynamicQuery;
046    import com.liferay.portlet.documentlibrary.service.persistence.DLFileVersionActionableDynamicQuery;
047    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
048    import com.liferay.portlet.documentlibrary.util.DLUtil;
049    import com.liferay.portlet.documentlibrary.util.comparator.FileVersionVersionComparator;
050    import com.liferay.portlet.documentlibrary.webdav.DLWebDAVStorageImpl;
051    
052    import java.io.InputStream;
053    
054    import java.util.Collections;
055    import java.util.Date;
056    import java.util.List;
057    
058    /**
059     * @author Raymond Aug??
060     * @author Douglas Wong
061     * @author Alexander Chow
062     */
063    public class VerifyDocumentLibrary extends VerifyProcess {
064    
065            protected void addDLFileVersion(DLFileEntry dlFileEntry)
066                    throws SystemException {
067    
068                    long fileVersionId = CounterLocalServiceUtil.increment();
069    
070                    DLFileVersion dlFileVersion =
071                            DLFileVersionLocalServiceUtil.createDLFileVersion(fileVersionId);
072    
073                    dlFileVersion.setGroupId(dlFileEntry.getGroupId());
074                    dlFileVersion.setCompanyId(dlFileEntry.getCompanyId());
075    
076                    long versionUserId = dlFileEntry.getVersionUserId();
077    
078                    if (versionUserId <= 0) {
079                            versionUserId = dlFileEntry.getUserId();
080                    }
081    
082                    dlFileVersion.setUserId(versionUserId);
083    
084                    String versionUserName = GetterUtil.getString(
085                            dlFileEntry.getVersionUserName(), dlFileEntry.getUserName());
086    
087                    dlFileVersion.setUserName(versionUserName);
088    
089                    dlFileVersion.setCreateDate(dlFileEntry.getModifiedDate());
090                    dlFileVersion.setModifiedDate(dlFileEntry.getModifiedDate());
091                    dlFileVersion.setRepositoryId(dlFileEntry.getRepositoryId());
092                    dlFileVersion.setFolderId(dlFileEntry.getFolderId());
093                    dlFileVersion.setFileEntryId(dlFileEntry.getFileEntryId());
094                    dlFileVersion.setExtension(dlFileEntry.getExtension());
095                    dlFileVersion.setMimeType(dlFileEntry.getMimeType());
096                    dlFileVersion.setTitle(dlFileEntry.getTitle());
097                    dlFileVersion.setDescription(dlFileEntry.getDescription());
098                    dlFileVersion.setExtraSettings(dlFileEntry.getExtraSettings());
099                    dlFileVersion.setFileEntryTypeId(dlFileEntry.getFileEntryTypeId());
100                    dlFileVersion.setVersion(dlFileEntry.getVersion());
101                    dlFileVersion.setSize(dlFileEntry.getSize());
102                    dlFileVersion.setStatus(WorkflowConstants.STATUS_APPROVED);
103                    dlFileVersion.setStatusByUserId(versionUserId);
104                    dlFileVersion.setStatusByUserName(versionUserName);
105                    dlFileVersion.setStatusDate(new Date());
106    
107                    DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
108            }
109    
110            protected void checkDLFileEntryType() throws Exception {
111                    DLFileEntryType dlFileEntryType =
112                            DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
113                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
114    
115                    if (dlFileEntryType != null) {
116                            return;
117                    }
118    
119                    Date now = new Date();
120    
121                    dlFileEntryType = DLFileEntryTypeLocalServiceUtil.createDLFileEntryType(
122                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
123    
124                    dlFileEntryType.setCreateDate(now);
125                    dlFileEntryType.setModifiedDate(now);
126                    dlFileEntryType.setName(DLFileEntryTypeConstants.NAME_BASIC_DOCUMENT);
127    
128                    DLFileEntryTypeLocalServiceUtil.updateDLFileEntryType(dlFileEntryType);
129            }
130    
131            protected void checkFileEntryMimeTypes(final String originalMimeType)
132                    throws Exception {
133    
134                    ActionableDynamicQuery actionableDynamicQuery =
135                            new DLFileEntryActionableDynamicQuery() {
136    
137                            @Override
138                            protected void performAction(Object object)
139                                    throws PortalException, SystemException {
140    
141                                    DLFileEntry dlFileEntry = (DLFileEntry)object;
142    
143                                    InputStream inputStream =
144                                            DLFileEntryLocalServiceUtil.getFileAsStream(
145                                                    dlFileEntry.getUserId(), dlFileEntry.getFileEntryId(),
146                                                    dlFileEntry.getVersion(), false);
147    
148                                    String title = DLUtil.getTitleWithExtension(
149                                            dlFileEntry.getTitle(), dlFileEntry.getExtension());
150    
151                                    String mimeType = MimeTypesUtil.getContentType(
152                                            inputStream, title);
153    
154                                    if (mimeType.equals(originalMimeType)) {
155                                            return;
156                                    }
157    
158                                    dlFileEntry.setMimeType(mimeType);
159    
160                                    DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
161    
162                                    DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
163    
164                                    dlFileVersion.setMimeType(mimeType);
165    
166                                    DLFileVersionLocalServiceUtil.updateDLFileVersion(
167                                            dlFileVersion);
168                            }
169    
170                    };
171    
172                    actionableDynamicQuery.performActions();
173            }
174    
175            protected void checkFileVersionMimeTypes(final String originalMimeType)
176                    throws Exception {
177    
178                    ActionableDynamicQuery actionableDynamicQuery =
179                            new DLFileVersionActionableDynamicQuery() {
180    
181                            @Override
182                            protected void performAction(Object object)
183                                    throws PortalException, SystemException {
184    
185                                    DLFileVersion dlFileVersion = (DLFileVersion)object;
186    
187                                    InputStream inputStream =
188                                            DLFileEntryLocalServiceUtil.getFileAsStream(
189                                                    dlFileVersion.getUserId(),
190                                                    dlFileVersion.getFileEntryId(),
191                                                    dlFileVersion.getVersion(), false);
192    
193                                    String title = DLUtil.getTitleWithExtension(
194                                            dlFileVersion.getTitle(), dlFileVersion.getExtension());
195    
196                                    String mimeType = MimeTypesUtil.getContentType(
197                                            inputStream, title);
198    
199                                    if (mimeType.equals(originalMimeType)) {
200                                            return;
201                                    }
202    
203                                    dlFileVersion.setMimeType(mimeType);
204    
205                                    DLFileVersionLocalServiceUtil.updateDLFileVersion(
206                                            dlFileVersion);
207                            }
208    
209                    };
210    
211                    actionableDynamicQuery.performActions();
212            }
213    
214            protected void checkMimeTypes() throws Exception {
215                    String[] mimeTypes = {
216                            ContentTypes.APPLICATION_OCTET_STREAM,
217                            DLWebDAVStorageImpl.MS_OFFICE_2010_TEXT_XML_UTF8
218                    };
219    
220                    for (String mimeType : mimeTypes) {
221                            checkFileEntryMimeTypes(mimeType);
222                            checkFileVersionMimeTypes(mimeType);
223                    }
224    
225                    if (_log.isDebugEnabled()) {
226                            _log.debug("Fixed file entries with invalid mime types");
227                    }
228            }
229    
230            protected void checkMisversionedDLFileEntries() throws Exception {
231                    List<DLFileEntry> dlFileEntries =
232                            DLFileEntryLocalServiceUtil.getMisversionedFileEntries();
233    
234                    if (_log.isDebugEnabled()) {
235                            _log.debug(
236                                    "Processing " + dlFileEntries.size() +
237                                            " misversioned file entries");
238                    }
239    
240                    for (DLFileEntry dlFileEntry : dlFileEntries) {
241                            copyDLFileEntry(dlFileEntry);
242    
243                            addDLFileVersion(dlFileEntry);
244                    }
245    
246                    if (_log.isDebugEnabled()) {
247                            _log.debug("Fixed misversioned file entries");
248                    }
249            }
250    
251            protected void checkTitles() throws Exception {
252                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
253                            DLFileEntry.class);
254    
255                    Criterion criterion1 = RestrictionsFactoryUtil.like("title", "%/%");
256                    Criterion criterion2 = RestrictionsFactoryUtil.like("title", "%\\\\%");
257    
258                    dynamicQuery.add(RestrictionsFactoryUtil.or(criterion1, criterion2));
259    
260                    List<DLFileEntry> dlFileEntries =
261                            DLFileEntryLocalServiceUtil.dynamicQuery(dynamicQuery);
262    
263                    for (DLFileEntry dlFileEntry : dlFileEntries) {
264                            String title = dlFileEntry.getTitle();
265    
266                            String newTitle = title.replace(StringPool.SLASH, StringPool.BLANK);
267    
268                            newTitle = newTitle.replace(
269                                    StringPool.BACK_SLASH, StringPool.UNDERLINE);
270    
271                            dlFileEntry.setTitle(newTitle);
272    
273                            DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
274    
275                            DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
276    
277                            dlFileVersion.setTitle(newTitle);
278    
279                            DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
280    
281                            if (_log.isDebugEnabled()) {
282                                    _log.debug(
283                                            "Invalid document title " + title + "renamed to " +
284                                                    newTitle);
285                            }
286                    }
287            }
288    
289            protected void copyDLFileEntry(DLFileEntry dlFileEntry)
290                    throws PortalException, SystemException {
291    
292                    long companyId = dlFileEntry.getCompanyId();
293                    long dataRepositoryId = dlFileEntry.getDataRepositoryId();
294                    String name = dlFileEntry.getName();
295                    String version = dlFileEntry.getVersion();
296    
297                    if (DLStoreUtil.hasFile(companyId, dataRepositoryId, name, version)) {
298                            return;
299                    }
300    
301                    FileVersionVersionComparator comparator =
302                            new FileVersionVersionComparator();
303    
304                    List<DLFileVersion> dlFileVersions = dlFileEntry.getFileVersions(
305                            WorkflowConstants.STATUS_APPROVED);
306    
307                    if (dlFileVersions.isEmpty()) {
308                            dlFileVersions = dlFileEntry.getFileVersions(
309                                    WorkflowConstants.STATUS_ANY);
310                    }
311    
312                    if (dlFileVersions.isEmpty()) {
313                            DLStoreUtil.addFile(companyId, dataRepositoryId, name, new byte[0]);
314    
315                            return;
316                    }
317    
318                    dlFileVersions = ListUtil.copy(dlFileVersions);
319    
320                    Collections.sort(dlFileVersions, comparator);
321    
322                    DLFileVersion dlFileVersion = dlFileVersions.get(0);
323    
324                    DLStoreUtil.copyFileVersion(
325                            companyId, dataRepositoryId, name, dlFileVersion.getVersion(),
326                            version);
327            }
328    
329            @Override
330            protected void doVerify() throws Exception {
331                    checkMisversionedDLFileEntries();
332    
333                    checkDLFileEntryType();
334                    checkMimeTypes();
335                    checkTitles();
336                    removeOrphanedDLFileEntries();
337                    updateAssets();
338            }
339    
340            protected void removeOrphanedDLFileEntries() throws Exception {
341                    List<DLFileEntry> dlFileEntries =
342                            DLFileEntryLocalServiceUtil.getOrphanedFileEntries();
343    
344                    if (_log.isDebugEnabled()) {
345                            _log.debug(
346                                    "Processing " + dlFileEntries.size() +
347                                            " file entries with no group");
348                    }
349    
350                    for (DLFileEntry dlFileEntry : dlFileEntries) {
351                            try {
352                                    DLFileEntryLocalServiceUtil.deleteFileEntry(
353                                            dlFileEntry.getFileEntryId());
354                            }
355                            catch (Exception e) {
356                                    if (_log.isWarnEnabled()) {
357                                            _log.warn(
358                                                    "Unable to remove file entry " +
359                                                            dlFileEntry.getFileEntryId() + ": " +
360                                                                    e.getMessage());
361                                    }
362                            }
363                    }
364    
365                    if (_log.isDebugEnabled()) {
366                            _log.debug("Removed orphaned file entries");
367                    }
368            }
369    
370            protected void updateAssets() throws Exception {
371                    List<DLFileEntry> dlFileEntries =
372                            DLFileEntryLocalServiceUtil.getNoAssetFileEntries();
373    
374                    if (_log.isDebugEnabled()) {
375                            _log.debug(
376                                    "Processing " + dlFileEntries.size() +
377                                            " file entries with no asset");
378                    }
379    
380                    for (DLFileEntry dlFileEntry : dlFileEntries) {
381                            FileEntry fileEntry = new LiferayFileEntry(dlFileEntry);
382                            FileVersion fileVersion = new LiferayFileVersion(
383                                    dlFileEntry.getFileVersion());
384    
385                            try {
386                                    DLAppHelperLocalServiceUtil.updateAsset(
387                                            dlFileEntry.getUserId(), fileEntry, fileVersion, null, null,
388                                            null);
389                            }
390                            catch (Exception e) {
391                                    if (_log.isWarnEnabled()) {
392                                            _log.warn(
393                                                    "Unable to update asset for file entry " +
394                                                            dlFileEntry.getFileEntryId() + ": " +
395                                                                    e.getMessage());
396                                    }
397                            }
398                    }
399    
400                    if (_log.isDebugEnabled()) {
401                            _log.debug("Assets verified for file entries");
402                    }
403            }
404    
405            private static Log _log = LogFactoryUtil.getLog(
406                    VerifyDocumentLibrary.class);
407    
408    }