001    /**
002     * Copyright (c) 2000-2013 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.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.Projection;
023    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
024    import com.liferay.portal.kernel.dao.orm.Property;
025    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
026    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
027    import com.liferay.portal.kernel.exception.PortalException;
028    import com.liferay.portal.kernel.exception.SystemException;
029    import com.liferay.portal.kernel.log.Log;
030    import com.liferay.portal.kernel.log.LogFactoryUtil;
031    import com.liferay.portal.kernel.repository.model.FileEntry;
032    import com.liferay.portal.kernel.repository.model.FileVersion;
033    import com.liferay.portal.kernel.repository.model.Folder;
034    import com.liferay.portal.kernel.util.ContentTypes;
035    import com.liferay.portal.kernel.util.ListUtil;
036    import com.liferay.portal.kernel.util.LocaleUtil;
037    import com.liferay.portal.kernel.util.MimeTypesUtil;
038    import com.liferay.portal.kernel.util.StreamUtil;
039    import com.liferay.portal.kernel.util.StringPool;
040    import com.liferay.portal.kernel.util.StringUtil;
041    import com.liferay.portal.kernel.workflow.WorkflowConstants;
042    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
043    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
044    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
045    import com.liferay.portal.util.PortalInstances;
046    import com.liferay.portal.util.PortalUtil;
047    import com.liferay.portlet.asset.model.AssetEntry;
048    import com.liferay.portlet.documentlibrary.DuplicateFileException;
049    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
050    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
051    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
052    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
053    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
054    import com.liferay.portlet.documentlibrary.model.DLFolder;
055    import com.liferay.portlet.documentlibrary.service.DLAppHelperLocalServiceUtil;
056    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
057    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
058    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
059    import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
060    import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryActionableDynamicQuery;
061    import com.liferay.portlet.documentlibrary.service.persistence.DLFileVersionActionableDynamicQuery;
062    import com.liferay.portlet.documentlibrary.service.persistence.DLFolderActionableDynamicQuery;
063    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
064    import com.liferay.portlet.documentlibrary.util.DLUtil;
065    import com.liferay.portlet.documentlibrary.util.comparator.FileVersionVersionComparator;
066    import com.liferay.portlet.documentlibrary.webdav.DLWebDAVStorageImpl;
067    import com.liferay.portlet.trash.model.TrashEntry;
068    import com.liferay.portlet.trash.service.TrashEntryLocalServiceUtil;
069    
070    import java.io.InputStream;
071    
072    import java.util.Collections;
073    import java.util.Date;
074    import java.util.List;
075    
076    /**
077     * @author Raymond Aug??
078     * @author Douglas Wong
079     * @author Alexander Chow
080     */
081    public class VerifyDocumentLibrary extends VerifyProcess {
082    
083            protected void addDLFileVersion(DLFileEntry dlFileEntry)
084                    throws SystemException {
085    
086                    long fileVersionId = CounterLocalServiceUtil.increment();
087    
088                    DLFileVersion dlFileVersion =
089                            DLFileVersionLocalServiceUtil.createDLFileVersion(fileVersionId);
090    
091                    dlFileVersion.setGroupId(dlFileEntry.getGroupId());
092                    dlFileVersion.setCompanyId(dlFileEntry.getCompanyId());
093    
094                    long userId = dlFileEntry.getUserId();
095    
096                    dlFileVersion.setUserId(userId);
097    
098                    String userName = dlFileEntry.getUserName();
099    
100                    dlFileVersion.setUserName(userName);
101    
102                    dlFileVersion.setCreateDate(dlFileEntry.getModifiedDate());
103                    dlFileVersion.setModifiedDate(dlFileEntry.getModifiedDate());
104                    dlFileVersion.setRepositoryId(dlFileEntry.getRepositoryId());
105                    dlFileVersion.setFolderId(dlFileEntry.getFolderId());
106                    dlFileVersion.setFileEntryId(dlFileEntry.getFileEntryId());
107                    dlFileVersion.setExtension(dlFileEntry.getExtension());
108                    dlFileVersion.setMimeType(dlFileEntry.getMimeType());
109                    dlFileVersion.setTitle(dlFileEntry.getTitle());
110                    dlFileVersion.setDescription(dlFileEntry.getDescription());
111                    dlFileVersion.setExtraSettings(dlFileEntry.getExtraSettings());
112                    dlFileVersion.setFileEntryTypeId(dlFileEntry.getFileEntryTypeId());
113                    dlFileVersion.setVersion(dlFileEntry.getVersion());
114                    dlFileVersion.setSize(dlFileEntry.getSize());
115                    dlFileVersion.setStatus(WorkflowConstants.STATUS_APPROVED);
116                    dlFileVersion.setStatusByUserId(userId);
117                    dlFileVersion.setStatusByUserName(userName);
118                    dlFileVersion.setStatusDate(new Date());
119    
120                    DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
121            }
122    
123            protected void checkDLFileEntryType() throws Exception {
124                    DLFileEntryType dlFileEntryType =
125                            DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
126                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
127    
128                    if (dlFileEntryType != null) {
129                            return;
130                    }
131    
132                    Date now = new Date();
133    
134                    dlFileEntryType = DLFileEntryTypeLocalServiceUtil.createDLFileEntryType(
135                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
136    
137                    dlFileEntryType.setCreateDate(now);
138                    dlFileEntryType.setModifiedDate(now);
139                    dlFileEntryType.setFileEntryTypeKey(
140                            StringUtil.toUpperCase(
141                                    DLFileEntryTypeConstants.NAME_BASIC_DOCUMENT));
142                    dlFileEntryType.setName(
143                            DLFileEntryTypeConstants.NAME_BASIC_DOCUMENT,
144                            LocaleUtil.getDefault());
145    
146                    DLFileEntryTypeLocalServiceUtil.updateDLFileEntryType(dlFileEntryType);
147            }
148    
149            protected void checkDuplicateTitles() throws Exception {
150                    ActionableDynamicQuery actionableDynamicQuery =
151                            new DLFileEntryActionableDynamicQuery() {
152    
153                                    @Override
154                                    public void performAction(Object object) {
155                                            DLFileEntry dlFileEntry = (DLFileEntry)object;
156    
157                                            if (dlFileEntry.isInTrash()) {
158                                                    return;
159                                            }
160    
161                                            try {
162                                                    DLFileEntryLocalServiceUtil.validateFile(
163                                                            dlFileEntry.getGroupId(), dlFileEntry.getFolderId(),
164                                                            dlFileEntry.getFileEntryId(),
165                                                            dlFileEntry.getTitle(), dlFileEntry.getExtension());
166                                            }
167                                            catch (Exception e1) {
168                                                    if (!(e1 instanceof DuplicateFileException) &&
169                                                            !(e1 instanceof DuplicateFolderNameException)) {
170    
171                                                            return;
172                                                    }
173    
174                                                    try {
175                                                            renameDuplicateTitle(dlFileEntry);
176                                                    }
177                                                    catch (Exception e2) {
178                                                            if (_log.isWarnEnabled()) {
179                                                                    _log.warn(
180                                                                            "Unable to rename duplicate title for " +
181                                                                                    "file entry " +
182                                                                                            dlFileEntry.getFileEntryId() +
183                                                                                                    ": " + e2.getMessage(),
184                                                                            e2);
185                                                            }
186                                                    }
187                                            }
188                                    }
189    
190                            };
191    
192                    actionableDynamicQuery.performActions();
193            }
194    
195            protected void checkFileEntryMimeTypes(final String originalMimeType)
196                    throws Exception {
197    
198                    ActionableDynamicQuery actionableDynamicQuery =
199                            new DLFileEntryActionableDynamicQuery() {
200    
201                            @Override
202                            public void addCriteria(DynamicQuery dynamicQuery) {
203                                    Property property = PropertyFactoryUtil.forName("mimeType");
204    
205                                    dynamicQuery.add(property.eq(originalMimeType));
206                            }
207    
208                            @Override
209                            protected void performAction(Object object)
210                                    throws PortalException, SystemException {
211    
212                                    DLFileEntry dlFileEntry = (DLFileEntry)object;
213    
214                                    InputStream inputStream = null;
215    
216                                    try {
217                                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
218                                                    dlFileEntry.getFileEntryId(), dlFileEntry.getVersion(),
219                                                    false);
220                                    }
221                                    catch (Exception e) {
222                                            if (_log.isWarnEnabled()) {
223                                                    _log.warn(
224                                                            "Unable to find file entry " +
225                                                                    dlFileEntry.getName(),
226                                                            e);
227                                            }
228    
229                                            return;
230                                    }
231    
232                                    String title = DLUtil.getTitleWithExtension(
233                                            dlFileEntry.getTitle(), dlFileEntry.getExtension());
234    
235                                    String mimeType = getMimeType(inputStream, title);
236    
237                                    if (mimeType.equals(originalMimeType)) {
238                                            return;
239                                    }
240    
241                                    dlFileEntry.setMimeType(mimeType);
242    
243                                    DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
244    
245                                    DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
246    
247                                    dlFileVersion.setMimeType(mimeType);
248    
249                                    DLFileVersionLocalServiceUtil.updateDLFileVersion(
250                                            dlFileVersion);
251                            }
252    
253                    };
254    
255                    actionableDynamicQuery.performActions();
256            }
257    
258            protected void checkFileVersionMimeTypes(final String originalMimeType)
259                    throws Exception {
260    
261                    ActionableDynamicQuery actionableDynamicQuery =
262                            new DLFileVersionActionableDynamicQuery() {
263    
264                            @Override
265                            public void addCriteria(DynamicQuery dynamicQuery) {
266                                    Property property = PropertyFactoryUtil.forName("mimeType");
267    
268                                    dynamicQuery.add(property.eq(originalMimeType));
269                            }
270    
271                            @Override
272                            protected void performAction(Object object) throws SystemException {
273                                    DLFileVersion dlFileVersion = (DLFileVersion)object;
274    
275                                    InputStream inputStream = null;
276    
277                                    try {
278                                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
279                                                    dlFileVersion.getFileEntryId(),
280                                                    dlFileVersion.getVersion(), false);
281                                    }
282                                    catch (Exception e) {
283                                            if (_log.isWarnEnabled()) {
284                                                    DLFileEntry dlFileEntry =
285                                                            DLFileEntryLocalServiceUtil.fetchDLFileEntry(
286                                                                    dlFileVersion.getFileEntryId());
287    
288                                                    if (dlFileEntry == null) {
289                                                            _log.warn(
290                                                                    "Unable to find file entry associated with " +
291                                                                            "file version " +
292                                                                                    dlFileVersion.getFileVersionId(),
293                                                                    e);
294                                                    }
295                                                    else {
296                                                            _log.warn(
297                                                                    "Unable to find file version " +
298                                                                            dlFileVersion.getVersion() + " for file " +
299                                                                                    "entry " + dlFileEntry.getName(),
300                                                                    e);
301                                                    }
302                                            }
303    
304                                            return;
305                                    }
306    
307                                    String title = DLUtil.getTitleWithExtension(
308                                            dlFileVersion.getTitle(), dlFileVersion.getExtension());
309    
310                                    String mimeType = getMimeType(inputStream, title);
311    
312                                    if (mimeType.equals(originalMimeType)) {
313                                            return;
314                                    }
315    
316                                    dlFileVersion.setMimeType(mimeType);
317    
318                                    DLFileVersionLocalServiceUtil.updateDLFileVersion(
319                                            dlFileVersion);
320                            }
321    
322                    };
323    
324                    actionableDynamicQuery.performActions();
325            }
326    
327            protected void checkMimeTypes() throws Exception {
328                    String[] mimeTypes = {
329                            ContentTypes.APPLICATION_OCTET_STREAM,
330                            DLWebDAVStorageImpl.MS_OFFICE_2010_TEXT_XML_UTF8
331                    };
332    
333                    for (String mimeType : mimeTypes) {
334                            checkFileEntryMimeTypes(mimeType);
335                            checkFileVersionMimeTypes(mimeType);
336                    }
337    
338                    if (_log.isDebugEnabled()) {
339                            _log.debug("Fixed file entries with invalid mime types");
340                    }
341            }
342    
343            protected void checkMisversionedDLFileEntries() throws Exception {
344                    List<DLFileEntry> dlFileEntries =
345                            DLFileEntryLocalServiceUtil.getMisversionedFileEntries();
346    
347                    if (_log.isDebugEnabled()) {
348                            _log.debug(
349                                    "Processing " + dlFileEntries.size() +
350                                            " misversioned file entries");
351                    }
352    
353                    for (DLFileEntry dlFileEntry : dlFileEntries) {
354                            copyDLFileEntry(dlFileEntry);
355    
356                            addDLFileVersion(dlFileEntry);
357                    }
358    
359                    if (_log.isDebugEnabled()) {
360                            _log.debug("Fixed misversioned file entries");
361                    }
362            }
363    
364            protected void checkTitles() throws Exception {
365                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
366                            DLFileEntry.class);
367    
368                    Criterion criterion1 = RestrictionsFactoryUtil.like("title", "%/%");
369                    Criterion criterion2 = RestrictionsFactoryUtil.like("title", "%\\\\%");
370    
371                    dynamicQuery.add(RestrictionsFactoryUtil.or(criterion1, criterion2));
372    
373                    List<DLFileEntry> dlFileEntries =
374                            DLFileEntryLocalServiceUtil.dynamicQuery(dynamicQuery);
375    
376                    for (DLFileEntry dlFileEntry : dlFileEntries) {
377                            TrashEntry trashEntry = TrashEntryLocalServiceUtil.fetchEntry(
378                                    dlFileEntry.getModelClassName(), dlFileEntry.getFileEntryId());
379    
380                            if (trashEntry != null) {
381                                    continue;
382                            }
383    
384                            String title = dlFileEntry.getTitle();
385    
386                            String newTitle = title.replace(StringPool.SLASH, StringPool.BLANK);
387    
388                            newTitle = newTitle.replace(
389                                    StringPool.BACK_SLASH, StringPool.UNDERLINE);
390    
391                            renameTitle(dlFileEntry, newTitle);
392                    }
393    
394                    checkDuplicateTitles();
395            }
396    
397            protected void copyDLFileEntry(DLFileEntry dlFileEntry)
398                    throws PortalException, SystemException {
399    
400                    long companyId = dlFileEntry.getCompanyId();
401                    long dataRepositoryId = dlFileEntry.getDataRepositoryId();
402                    String name = dlFileEntry.getName();
403                    String version = dlFileEntry.getVersion();
404    
405                    if (DLStoreUtil.hasFile(companyId, dataRepositoryId, name, version)) {
406                            return;
407                    }
408    
409                    FileVersionVersionComparator comparator =
410                            new FileVersionVersionComparator();
411    
412                    List<DLFileVersion> dlFileVersions = dlFileEntry.getFileVersions(
413                            WorkflowConstants.STATUS_APPROVED);
414    
415                    if (dlFileVersions.isEmpty()) {
416                            dlFileVersions = dlFileEntry.getFileVersions(
417                                    WorkflowConstants.STATUS_ANY);
418                    }
419    
420                    if (dlFileVersions.isEmpty()) {
421                            DLStoreUtil.addFile(companyId, dataRepositoryId, name, new byte[0]);
422    
423                            return;
424                    }
425    
426                    dlFileVersions = ListUtil.copy(dlFileVersions);
427    
428                    Collections.sort(dlFileVersions, comparator);
429    
430                    DLFileVersion dlFileVersion = dlFileVersions.get(0);
431    
432                    DLStoreUtil.copyFileVersion(
433                            companyId, dataRepositoryId, name, dlFileVersion.getVersion(),
434                            version);
435            }
436    
437            @Override
438            protected void doVerify() throws Exception {
439                    checkMisversionedDLFileEntries();
440    
441                    checkDLFileEntryType();
442                    checkMimeTypes();
443                    checkTitles();
444                    removeOrphanedDLFileEntries();
445                    updateClassNameId();
446                    updateFileEntryAssets();
447                    updateFolderAssets();
448                    verifyTree();
449            }
450    
451            protected String getMimeType(InputStream inputStream, String title) {
452                    String mimeType = null;
453    
454                    try {
455                            mimeType = MimeTypesUtil.getContentType(inputStream, title);
456                    }
457                    finally {
458                            StreamUtil.cleanUp(inputStream);
459                    }
460    
461                    return mimeType;
462            }
463    
464            protected void updateClassNameId() {
465                    try {
466                            runSQL(
467                                    "update DLFileEntry set classNameId = 0 where classNameId is " +
468                                            "null");
469                    }
470                    catch (Exception e) {
471                            if (_log.isWarnEnabled()) {
472                                    _log.warn(
473                                            "Unable to fix file entries where class name ID is null",
474                                            e);
475                            }
476                    }
477            }
478    
479            protected void removeOrphanedDLFileEntries() throws Exception {
480                    List<DLFileEntry> dlFileEntries =
481                            DLFileEntryLocalServiceUtil.getOrphanedFileEntries();
482    
483                    if (_log.isDebugEnabled()) {
484                            _log.debug(
485                                    "Processing " + dlFileEntries.size() +
486                                            " file entries with no group");
487                    }
488    
489                    for (DLFileEntry dlFileEntry : dlFileEntries) {
490                            try {
491                                    DLFileEntryLocalServiceUtil.deleteFileEntry(
492                                            dlFileEntry.getFileEntryId());
493                            }
494                            catch (Exception e) {
495                                    if (_log.isWarnEnabled()) {
496                                            _log.warn(
497                                                    "Unable to remove file entry " +
498                                                            dlFileEntry.getFileEntryId() + ": " +
499                                                                    e.getMessage());
500                                    }
501                            }
502                    }
503    
504                    if (_log.isDebugEnabled()) {
505                            _log.debug("Removed orphaned file entries");
506                    }
507            }
508    
509            protected void renameDuplicateTitle(DLFileEntry dlFileEntry)
510                    throws PortalException, SystemException {
511    
512                    String uniqueTitle = DLFileEntryLocalServiceUtil.getUniqueTitle(
513                            dlFileEntry.getGroupId(), dlFileEntry.getFolderId(),
514                            dlFileEntry.getFileEntryId(), dlFileEntry.getTitle(),
515                            dlFileEntry.getExtension());
516    
517                    renameTitle(dlFileEntry, uniqueTitle);
518            }
519    
520            protected void renameTitle(DLFileEntry dlFileEntry, String newTitle)
521                    throws PortalException, SystemException {
522    
523                    String title = dlFileEntry.getTitle();
524    
525                    dlFileEntry.setTitle(newTitle);
526    
527                    DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
528    
529                    DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
530    
531                    dlFileVersion.setTitle(newTitle);
532    
533                    DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
534    
535                    if (_log.isDebugEnabled()) {
536                            _log.debug(
537                                    "Invalid title " + title + " renamed to " + newTitle +
538                                            " for file entry " + dlFileEntry.getFileEntryId());
539                    }
540            }
541    
542            protected void updateFileEntryAssets() throws Exception {
543                    ActionableDynamicQuery actionableDynamicQuery =
544                            new DLFileEntryActionableDynamicQuery() {
545    
546                                    @Override
547                                    public void addCriteria(DynamicQuery dynamicQuery) {
548                                            Property fileEntryIdProperty = PropertyFactoryUtil.forName(
549                                                    "fileEntryId");
550    
551                                            DynamicQuery assetEntryDynamicQuery =
552                                                    DynamicQueryFactoryUtil.forClass(AssetEntry.class);
553    
554                                            Property classNameIdProperty = PropertyFactoryUtil.forName(
555                                                    "classNameId");
556    
557                                            long classNameId = PortalUtil.getClassNameId(
558                                                    DLFileEntry.class);
559    
560                                            assetEntryDynamicQuery.add(
561                                                    classNameIdProperty.eq(classNameId));
562    
563                                            Projection projection = ProjectionFactoryUtil.property(
564                                                    "classPK");
565    
566                                            assetEntryDynamicQuery.setProjection(projection);
567    
568                                            dynamicQuery.add(
569                                                    fileEntryIdProperty.notIn(assetEntryDynamicQuery));
570                                    }
571    
572                                    @Override
573                                    protected void performAction(Object object)
574                                            throws PortalException, SystemException {
575    
576                                            DLFileEntry dlFileEntry = (DLFileEntry)object;
577    
578                                            FileEntry fileEntry = new LiferayFileEntry(dlFileEntry);
579                                            FileVersion fileVersion = new LiferayFileVersion(
580                                                    dlFileEntry.getFileVersion());
581    
582                                            try {
583                                                    DLAppHelperLocalServiceUtil.updateAsset(
584                                                            dlFileEntry.getUserId(), fileEntry, fileVersion,
585                                                            null, null, null);
586                                            }
587                                            catch (Exception e) {
588                                                    if (_log.isWarnEnabled()) {
589                                                            _log.warn(
590                                                                    "Unable to update asset for file entry " +
591                                                                            dlFileEntry.getFileEntryId() + ": " +
592                                                                                    e.getMessage());
593                                                    }
594                                            }
595                                    }
596                            };
597    
598                    if (_log.isDebugEnabled()) {
599                            long count = actionableDynamicQuery.performCount();
600    
601                            _log.debug("Processing " + count + " file entries with no asset");
602                    }
603    
604                    actionableDynamicQuery.performActions();
605    
606                    if (_log.isDebugEnabled()) {
607                            _log.debug("Assets verified for file entries");
608                    }
609            }
610    
611            protected void updateFolderAssets() throws Exception {
612                    ActionableDynamicQuery actionableDynamicQuery =
613                            new DLFolderActionableDynamicQuery() {
614    
615                                    @Override
616                                    public void addCriteria(DynamicQuery dynamicQuery) {
617                                            Property folderIdProperty = PropertyFactoryUtil.forName(
618                                                    "folderId");
619    
620                                            DynamicQuery assetEntryDynamicQuery =
621                                                    DynamicQueryFactoryUtil.forClass(AssetEntry.class);
622    
623                                            Property classNameIdProperty = PropertyFactoryUtil.forName(
624                                                    "classNameId");
625    
626                                            long classNameId = PortalUtil.getClassNameId(
627                                                    DLFolder.class);
628    
629                                            assetEntryDynamicQuery.add(
630                                                    classNameIdProperty.eq(classNameId));
631    
632                                            Projection projection = ProjectionFactoryUtil.property(
633                                                    "classPK");
634    
635                                            assetEntryDynamicQuery.setProjection(projection);
636    
637                                            dynamicQuery.add(
638                                                    folderIdProperty.notIn(assetEntryDynamicQuery));
639                                    }
640    
641                                    @Override
642                                    protected void performAction(Object object)
643                                            throws PortalException, SystemException {
644    
645                                            DLFolder dlFolder = (DLFolder)object;
646    
647                                            Folder folder = new LiferayFolder(dlFolder);
648    
649                                            try {
650                                                    DLAppHelperLocalServiceUtil.updateAsset(
651                                                            dlFolder.getUserId(), folder, null, null, null);
652                                            }
653                                            catch (Exception e) {
654                                                    if (_log.isWarnEnabled()) {
655                                                            _log.warn(
656                                                                    "Unable to update asset for folder " +
657                                                                            dlFolder.getFolderId() + ": " +
658                                                                                    e.getMessage());
659                                                    }
660                                            }
661                                    }
662                            };
663    
664                    if (_log.isDebugEnabled()) {
665                            long count = actionableDynamicQuery.performCount();
666    
667                            _log.debug("Processing " + count + " folders with no asset");
668                    }
669    
670                    actionableDynamicQuery.performActions();
671    
672                    if (_log.isDebugEnabled()) {
673                            _log.debug("Assets verified for folders");
674                    }
675            }
676    
677            protected void verifyTree() throws Exception {
678                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
679    
680                    for (long companyId : companyIds) {
681                            DLFolderLocalServiceUtil.rebuildTree(companyId);
682                    }
683            }
684    
685            private static Log _log = LogFactoryUtil.getLog(
686                    VerifyDocumentLibrary.class);
687    
688    }