001/*
002 * (C) Copyright 2006-2011 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 GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Thomas Roger <troger@nuxeo.com>
016 */
017
018package org.nuxeo.ecm.platform.picture.listener;
019
020import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.ABOUT_TO_CREATE;
021import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.CTX_FORCE_VIEWS_GENERATION;
022import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTUREBOOK_TYPE_NAME;
023import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTURE_FACET;
024
025import java.io.IOException;
026import java.net.URL;
027import java.util.ArrayList;
028import java.util.List;
029import java.util.Map;
030
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033import org.nuxeo.common.utils.FileUtils;
034import org.nuxeo.common.utils.Path;
035import org.nuxeo.ecm.core.api.Blob;
036import org.nuxeo.ecm.core.api.Blobs;
037import org.nuxeo.ecm.core.api.CoreSession;
038import org.nuxeo.ecm.core.api.DocumentModel;
039import org.nuxeo.ecm.core.api.PathRef;
040import org.nuxeo.ecm.core.api.model.Property;
041import org.nuxeo.ecm.core.event.Event;
042import org.nuxeo.ecm.core.event.EventContext;
043import org.nuxeo.ecm.core.event.EventListener;
044import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
045import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry;
046import org.nuxeo.ecm.platform.picture.api.ImageInfo;
047import org.nuxeo.ecm.platform.picture.api.ImagingService;
048import org.nuxeo.ecm.platform.picture.api.adapters.AbstractPictureAdapter;
049import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter;
050import org.nuxeo.runtime.api.Framework;
051
052/**
053 * Listener updating pre-filling the views of a Picture if the main Blob has changed.
054 *
055 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
056 * @since 5.5
057 */
058public class PictureChangedListener implements EventListener {
059
060    public static final String EMPTY_PICTURE_PATH = "nuxeo.war/img/empty_picture.png";
061
062    private static final Log log = LogFactory.getLog(PictureChangedListener.class);
063
064    private static ImageInfo emptyPictureImageInfo;
065
066    @Override
067    public void handleEvent(Event event) {
068        EventContext ctx = event.getContext();
069        if (!(ctx instanceof DocumentEventContext)) {
070            return;
071        }
072        DocumentEventContext docCtx = (DocumentEventContext) ctx;
073        DocumentModel doc = docCtx.getSourceDocument();
074        if (doc.hasFacet(PICTURE_FACET) && !doc.isProxy()) {
075            Property fileProp = doc.getProperty("file:content");
076            Property viewsProp = doc.getProperty(AbstractPictureAdapter.VIEWS_PROPERTY);
077
078            Boolean forceGeneration = Boolean.TRUE.equals(doc.getContextData(CTX_FORCE_VIEWS_GENERATION));
079            if (forceGeneration || !viewsProp.isDirty() && (ABOUT_TO_CREATE.equals(event.getName()) || fileProp.isDirty())) {
080                preFillPictureViews(docCtx.getCoreSession(), doc);
081            } else {
082                docCtx.setProperty(PictureViewsGenerationListener.DISABLE_PICTURE_VIEWS_GENERATION_LISTENER, true);
083            }
084        }
085    }
086
087    protected void preFillPictureViews(CoreSession session, DocumentModel doc) {
088        try {
089            URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(getEmptyPicturePath());
090            if (fileUrl == null) {
091                return;
092            }
093
094            Blob blob = Blobs.createBlob(FileUtils.getFileFromURL(fileUrl));
095            MimetypeRegistry mimetypeRegistry = Framework.getLocalService(MimetypeRegistry.class);
096            String mimeType = mimetypeRegistry.getMimetypeFromFilenameAndBlobWithDefault(blob.getFilename(), blob, null);
097            blob.setMimeType(mimeType);
098
099            DocumentModel parentDoc = getParentDocument(session, doc);
100
101            List<Map<String, Object>> pictureConversions = null;
102            if (parentDoc != null && PICTUREBOOK_TYPE_NAME.equals(parentDoc.getType())) {
103                // use PictureBook Properties
104                pictureConversions = (ArrayList<Map<String, Object>>) parentDoc.getPropertyValue("picturebook:picturetemplates");
105                if (pictureConversions.isEmpty()) {
106                    pictureConversions = null;
107                }
108            }
109
110            if (emptyPictureImageInfo == null) {
111                ImagingService imagingService = Framework.getLocalService(ImagingService.class);
112                emptyPictureImageInfo = imagingService.getImageInfo(blob);
113            }
114
115            PictureResourceAdapter adapter = doc.getAdapter(PictureResourceAdapter.class);
116            adapter.preFillPictureViews(blob, pictureConversions, emptyPictureImageInfo);
117        } catch (IOException e) {
118            log.error("Error while pre-filling picture views: " + e.getMessage(), e);
119        }
120    }
121
122    protected String getEmptyPicturePath() {
123        return EMPTY_PICTURE_PATH;
124    }
125
126    protected DocumentModel getParentDocument(CoreSession session, DocumentModel doc) {
127        DocumentModel parent;
128        if (session.exists(doc.getRef())) {
129            parent = session.getParentDocument(doc.getRef());
130        } else {
131            Path parentPath = doc.getPath().removeLastSegments(1);
132            parent = session.getDocument(new PathRef(parentPath.toString()));
133        }
134        return parent;
135    }
136
137}