001/*
002 * Copyright (c) 2006-2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 * Vladimir Pasquier <vpasquier@nuxeo.com>
011 * Laurent Doguin <ldoguin@nuxeo.com>
012 * Nelson Silva <nsilva@nuxeo.com>
013 */
014package org.nuxeo.ecm.platform.thumbnail.listener;
015
016import static org.nuxeo.ecm.core.api.CoreSession.ALLOW_VERSION_WRITE;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.io.Serializable;
021import java.util.HashSet;
022import java.util.Set;
023
024import org.nuxeo.ecm.core.api.Blob;
025import org.nuxeo.ecm.core.api.Blobs;
026import org.nuxeo.ecm.core.api.CoreSession;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.core.api.NuxeoException;
029import org.nuxeo.ecm.core.api.VersioningOption;
030import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
031import org.nuxeo.ecm.core.api.thumbnail.ThumbnailAdapter;
032import org.nuxeo.ecm.core.blob.BlobManager;
033import org.nuxeo.ecm.core.event.DeletedDocumentModel;
034import org.nuxeo.ecm.core.event.Event;
035import org.nuxeo.ecm.core.event.EventBundle;
036import org.nuxeo.ecm.core.event.PostCommitEventListener;
037import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
038import org.nuxeo.ecm.core.versioning.VersioningService;
039import org.nuxeo.ecm.platform.dublincore.listener.DublinCoreListener;
040import org.nuxeo.ecm.platform.ec.notification.NotificationConstants;
041import org.nuxeo.ecm.platform.thumbnail.ThumbnailConstants;
042import org.nuxeo.runtime.api.Framework;
043
044/**
045 * Thumbnail listener handling creation and update document event to store doc thumbnail preview (only for DocType File)
046 *
047 * @since 5.7
048 */
049public class UpdateThumbnailListener implements PostCommitEventListener {
050
051    public static final String THUMBNAIL_UPDATED = "thumbnailUpdated";
052
053    protected void processDoc(CoreSession session, DocumentModel doc) {
054        Blob thumbnailBlob = getManagedThumbnail(doc);
055        if (thumbnailBlob == null) {
056            ThumbnailAdapter thumbnailAdapter = doc.getAdapter(ThumbnailAdapter.class);
057            if (thumbnailAdapter == null) {
058                return;
059            }
060            thumbnailBlob = thumbnailAdapter.computeThumbnail(session);
061        }
062        if (thumbnailBlob != null) {
063            if (!doc.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) {
064                doc.addFacet(ThumbnailConstants.THUMBNAIL_FACET);
065            }
066            doc.setPropertyValue(ThumbnailConstants.THUMBNAIL_PROPERTY_NAME, (Serializable) thumbnailBlob);
067        } else {
068            if (doc.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) {
069                doc.setPropertyValue(ThumbnailConstants.THUMBNAIL_PROPERTY_NAME, null);
070                doc.removeFacet(ThumbnailConstants.THUMBNAIL_FACET);
071            }
072        }
073        if (doc.isDirty()) {
074            doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.NONE);
075            doc.putContextData(VersioningService.DISABLE_AUTO_CHECKOUT, Boolean.TRUE);
076            doc.putContextData(DublinCoreListener.DISABLE_DUBLINCORE_LISTENER, Boolean.TRUE);
077            doc.putContextData(NotificationConstants.DISABLE_NOTIFICATION_SERVICE, Boolean.TRUE);
078            doc.putContextData("disableAuditLogger", Boolean.TRUE);
079            if (doc.isVersion()) {
080                doc.putContextData(ALLOW_VERSION_WRITE, Boolean.TRUE);
081            }
082            doc.putContextData(THUMBNAIL_UPDATED, true);
083            session.saveDocument(doc);
084        }
085    }
086
087    private Blob getManagedThumbnail(DocumentModel doc) {
088        BlobHolder bh = doc.getAdapter(BlobHolder.class);
089        if (bh == null) {
090            return null;
091        }
092        Blob blob = bh.getBlob();
093        if (blob == null) {
094            return null;
095        }
096        BlobManager blobManager = Framework.getService(BlobManager.class);
097        try {
098            InputStream is = blobManager.getThumbnail(blob);
099            if (is == null) {
100                return null;
101            }
102            return Blobs.createBlob(is);
103        } catch (IOException e) {
104            throw new NuxeoException("Failed to get managed blob thumbnail", e);
105        }
106    }
107
108    @Override
109    public void handleEvent(EventBundle events) {
110        if (!events.containsEventName(ThumbnailConstants.EventNames.scheduleThumbnailUpdate.name())) {
111            return;
112        }
113        Set<String> processedDocs = new HashSet<String>();
114        for (Event event : events) {
115            if (!ThumbnailConstants.EventNames.scheduleThumbnailUpdate.name().equals(event.getName())) {
116                continue;
117            }
118            DocumentEventContext context = (DocumentEventContext) event.getContext();
119            DocumentModel doc = context.getSourceDocument();
120            if (doc instanceof DeletedDocumentModel) {
121                continue;
122            }
123            if (doc.isProxy()) {
124                continue;
125            }
126            if (processedDocs.contains(doc.getId())) {
127                continue;
128            }
129            CoreSession repo = context.getCoreSession();
130            processDoc(repo, doc);
131            processedDocs.add(doc.getId());
132        }
133    }
134}