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.PICTUREBOOK_TYPE_NAME;
022import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTURE_FACET;
023
024import java.io.IOException;
025import java.net.URL;
026import java.util.ArrayList;
027import java.util.List;
028import java.util.Map;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.nuxeo.common.utils.FileUtils;
033import org.nuxeo.common.utils.Path;
034import org.nuxeo.ecm.core.api.Blob;
035import org.nuxeo.ecm.core.api.Blobs;
036import org.nuxeo.ecm.core.api.CoreSession;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.PathRef;
039import org.nuxeo.ecm.core.api.model.Property;
040import org.nuxeo.ecm.core.event.Event;
041import org.nuxeo.ecm.core.event.EventContext;
042import org.nuxeo.ecm.core.event.EventListener;
043import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
044import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry;
045import org.nuxeo.ecm.platform.picture.api.ImageInfo;
046import org.nuxeo.ecm.platform.picture.api.ImagingService;
047import org.nuxeo.ecm.platform.picture.api.adapters.AbstractPictureAdapter;
048import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter;
049import org.nuxeo.runtime.api.Framework;
050
051/**
052 * Listener updating pre-filling the views of a Picture if the main Blob has changed.
053 *
054 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
055 * @since 5.5
056 */
057public class PictureChangedListener implements EventListener {
058
059    public static final String EMPTY_PICTURE_PATH = "nuxeo.war/img/empty_picture.png";
060
061    private static final Log log = LogFactory.getLog(PictureChangedListener.class);
062
063    private static ImageInfo emptyPictureImageInfo;
064
065    @Override
066    public void handleEvent(Event event) {
067        EventContext ctx = event.getContext();
068        if (!(ctx instanceof DocumentEventContext)) {
069            return;
070        }
071        DocumentEventContext docCtx = (DocumentEventContext) ctx;
072        DocumentModel doc = docCtx.getSourceDocument();
073        if (doc.hasFacet(PICTURE_FACET) && !doc.isProxy()) {
074            Property fileProp = doc.getProperty("file:content");
075            Property viewsProp = doc.getProperty(AbstractPictureAdapter.VIEWS_PROPERTY);
076
077            if (!viewsProp.isDirty() && (ABOUT_TO_CREATE.equals(event.getName()) || fileProp.isDirty())) {
078                preFillPictureViews(docCtx.getCoreSession(), doc);
079            } else {
080                docCtx.setProperty(PictureViewsGenerationListener.DISABLE_PICTURE_VIEWS_GENERATION_LISTENER, true);
081            }
082        }
083    }
084
085    protected void preFillPictureViews(CoreSession session, DocumentModel doc) {
086        try {
087            URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(getEmptyPicturePath());
088            if (fileUrl == null) {
089                return;
090            }
091
092            Blob blob = Blobs.createBlob(FileUtils.getFileFromURL(fileUrl));
093            MimetypeRegistry mimetypeRegistry = Framework.getLocalService(MimetypeRegistry.class);
094            String mimeType = mimetypeRegistry.getMimetypeFromFilenameAndBlobWithDefault(blob.getFilename(), blob, null);
095            blob.setMimeType(mimeType);
096
097            DocumentModel parentDoc = getParentDocument(session, doc);
098
099            List<Map<String, Object>> pictureConversions = null;
100            if (parentDoc != null && PICTUREBOOK_TYPE_NAME.equals(parentDoc.getType())) {
101                // use PictureBook Properties
102                pictureConversions = (ArrayList<Map<String, Object>>) parentDoc.getPropertyValue("picturebook:picturetemplates");
103                if (pictureConversions.isEmpty()) {
104                    pictureConversions = null;
105                }
106            }
107
108            if (emptyPictureImageInfo == null) {
109                ImagingService imagingService = Framework.getLocalService(ImagingService.class);
110                emptyPictureImageInfo = imagingService.getImageInfo(blob);
111            }
112
113            PictureResourceAdapter adapter = doc.getAdapter(PictureResourceAdapter.class);
114            adapter.preFillPictureViews(blob, pictureConversions, emptyPictureImageInfo);
115        } catch (IOException e) {
116            log.error("Error while pre-filling picture views: " + e.getMessage(), e);
117        }
118    }
119
120    protected String getEmptyPicturePath() {
121        return EMPTY_PICTURE_PATH;
122    }
123
124    protected DocumentModel getParentDocument(CoreSession session, DocumentModel doc) {
125        DocumentModel parent;
126        if (session.exists(doc.getRef())) {
127            parent = session.getParentDocument(doc.getRef());
128        } else {
129            Path parentPath = doc.getPath().removeLastSegments(1);
130            parent = session.getDocument(new PathRef(parentPath.toString()));
131        }
132        return parent;
133    }
134
135}