001package org.nuxeo.ecm.platform.picture;
002
003import static org.nuxeo.ecm.core.api.CoreSession.ALLOW_VERSION_WRITE;
004
005import java.io.IOException;
006import java.util.List;
007
008import org.nuxeo.ecm.core.api.Blob;
009import org.nuxeo.ecm.core.api.DocumentModel;
010import org.nuxeo.ecm.core.api.IdRef;
011import org.nuxeo.ecm.core.api.model.Property;
012import org.nuxeo.ecm.core.event.Event;
013import org.nuxeo.ecm.core.event.EventService;
014import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
015import org.nuxeo.ecm.core.work.AbstractWork;
016import org.nuxeo.ecm.core.work.api.WorkManager;
017import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter;
018import org.nuxeo.runtime.api.Framework;
019import org.nuxeo.runtime.transaction.TransactionHelper;
020
021/**
022 * Work generating the different picture views for a Picture.
023 *
024 * @since 5.7
025 */
026public class PictureViewsGenerationWork extends AbstractWork {
027
028    private static final long serialVersionUID = 1L;
029
030    public static final String CATEGORY_PICTURE_GENERATION = "pictureViewsGeneration";
031
032    public static final String PICTURE_VIEWS_GENERATION_DONE_EVENT = "pictureViewsGenerationDone";
033
034    protected final String xpath;
035
036    public PictureViewsGenerationWork(String repositoryName, String docId, String xpath) {
037        super(repositoryName + ':' + docId + ':' + xpath + ":pictureView");
038        setDocument(repositoryName, docId);
039        this.xpath = xpath;
040    }
041
042    @Override
043    public String getCategory() {
044        return CATEGORY_PICTURE_GENERATION;
045    }
046
047    @Override
048    public String getTitle() {
049        return "Picture views generation";
050    }
051
052    @Override
053    public void work() {
054        setProgress(Progress.PROGRESS_INDETERMINATE);
055        setStatus("Extracting");
056
057        initSession();
058        if (!session.exists(new IdRef(docId))) {
059            setStatus("Nothing to process");
060            return;
061        }
062
063        DocumentModel workingDocument = session.getDocument(new IdRef(docId));
064        Property fileProp = workingDocument.getProperty(xpath);
065        Blob blob = (Blob) fileProp.getValue();
066        if (blob == null) {
067            // do nothing
068            return;
069        }
070
071        String title = workingDocument.getTitle();
072        setStatus("Generating views");
073        try {
074            PictureResourceAdapter picture = workingDocument.getAdapter(PictureResourceAdapter.class);
075            picture.fillPictureViews(blob, blob.getFilename(), title, null);
076        } catch (IOException e) {
077            throw new RuntimeException(e);
078        }
079
080        if (!TransactionHelper.isTransactionActive()) {
081            startTransaction();
082        }
083        initSession();
084        if (!session.exists(new IdRef(docId))) {
085            setStatus("Nothing to process");
086            return;
087        }
088        setStatus("Saving");
089        if (workingDocument.isVersion()) {
090            workingDocument.putContextData(ALLOW_VERSION_WRITE, Boolean.TRUE);
091        }
092        workingDocument.putContextData("disableNotificationService", Boolean.TRUE);
093        workingDocument.putContextData("disableAuditLogger", Boolean.TRUE);
094        session.saveDocument(workingDocument);
095
096        firePictureViewsGenerationDoneEvent(workingDocument);
097
098        setStatus("Done");
099    }
100
101    /**
102     * Fire a {@code PICTURE_VIEWS_GENERATION_DONE_EVENT} event when no other PictureViewsGenerationWork is scheduled
103     * for this document.
104     *
105     * @since 5.8
106     */
107    protected void firePictureViewsGenerationDoneEvent(DocumentModel doc) {
108        WorkManager workManager = Framework.getLocalService(WorkManager.class);
109        List<String> workIds = workManager.listWorkIds(CATEGORY_PICTURE_GENERATION, null);
110        int worksCount = 0;
111        for (String workId : workIds) {
112            if (workId.equals(getId())) {
113                if (++worksCount > 1) {
114                    // another work scheduled
115                    return;
116                }
117            }
118        }
119        DocumentEventContext ctx = new DocumentEventContext(session, session.getPrincipal(), doc);
120        Event event = ctx.newEvent(PICTURE_VIEWS_GENERATION_DONE_EVENT);
121        Framework.getLocalService(EventService.class).fireEvent(event);
122    }
123
124}