001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thomas Roger <troger@nuxeo.com> 018 */ 019 020package org.nuxeo.ecm.platform.picture.listener; 021 022import static org.nuxeo.ecm.core.api.event.DocumentEventTypes.ABOUT_TO_CREATE; 023import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.CTX_FORCE_VIEWS_GENERATION; 024import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTUREBOOK_TYPE_NAME; 025import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTURE_FACET; 026 027import java.io.IOException; 028import java.net.URL; 029import java.util.ArrayList; 030import java.util.List; 031import java.util.Map; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.common.utils.FileUtils; 036import org.nuxeo.common.utils.Path; 037import org.nuxeo.ecm.core.api.Blob; 038import org.nuxeo.ecm.core.api.Blobs; 039import org.nuxeo.ecm.core.api.CoreSession; 040import org.nuxeo.ecm.core.api.DocumentModel; 041import org.nuxeo.ecm.core.api.PathRef; 042import org.nuxeo.ecm.core.api.model.Property; 043import org.nuxeo.ecm.core.event.Event; 044import org.nuxeo.ecm.core.event.EventContext; 045import org.nuxeo.ecm.core.event.EventListener; 046import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 047import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry; 048import org.nuxeo.ecm.platform.picture.api.ImageInfo; 049import org.nuxeo.ecm.platform.picture.api.ImagingService; 050import org.nuxeo.ecm.platform.picture.api.adapters.AbstractPictureAdapter; 051import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter; 052import org.nuxeo.runtime.api.Framework; 053 054/** 055 * Listener updating pre-filling the views of a Picture if the main Blob has changed. 056 * 057 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 058 * @since 5.5 059 */ 060public class PictureChangedListener implements EventListener { 061 062 public static final String EMPTY_PICTURE_PATH = "nuxeo.war/img/empty_picture.png"; 063 064 private static final Log log = LogFactory.getLog(PictureChangedListener.class); 065 066 private static ImageInfo emptyPictureImageInfo; 067 068 @Override 069 public void handleEvent(Event event) { 070 EventContext ctx = event.getContext(); 071 if (!(ctx instanceof DocumentEventContext)) { 072 return; 073 } 074 DocumentEventContext docCtx = (DocumentEventContext) ctx; 075 DocumentModel doc = docCtx.getSourceDocument(); 076 if (doc.hasFacet(PICTURE_FACET) && !doc.isProxy()) { 077 Property fileProp = doc.getProperty("file:content"); 078 Property viewsProp = doc.getProperty(AbstractPictureAdapter.VIEWS_PROPERTY); 079 080 boolean forceGeneration = Boolean.TRUE.equals(doc.getContextData(CTX_FORCE_VIEWS_GENERATION)); 081 boolean noPictureViews = !viewsProp.isDirty() || viewsProp.size() == 0; 082 boolean fileChanged = ABOUT_TO_CREATE.equals(event.getName()) || fileProp.isDirty(); 083 if (forceGeneration || (noPictureViews && fileChanged)) { 084 preFillPictureViews(docCtx.getCoreSession(), doc); 085 } else { 086 docCtx.setProperty(PictureViewsGenerationListener.DISABLE_PICTURE_VIEWS_GENERATION_LISTENER, true); 087 } 088 } 089 } 090 091 protected void preFillPictureViews(CoreSession session, DocumentModel doc) { 092 try { 093 URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(getEmptyPicturePath()); 094 if (fileUrl == null) { 095 return; 096 } 097 098 Blob blob = Blobs.createBlob(FileUtils.getFileFromURL(fileUrl)); 099 MimetypeRegistry mimetypeRegistry = Framework.getLocalService(MimetypeRegistry.class); 100 String mimeType = mimetypeRegistry.getMimetypeFromFilenameAndBlobWithDefault(blob.getFilename(), blob, 101 null); 102 blob.setMimeType(mimeType); 103 104 DocumentModel parentDoc = getParentDocument(session, doc); 105 106 List<Map<String, Object>> pictureConversions = null; 107 if (parentDoc != null && PICTUREBOOK_TYPE_NAME.equals(parentDoc.getType())) { 108 // use PictureBook Properties 109 pictureConversions = (ArrayList<Map<String, Object>>) parentDoc.getPropertyValue( 110 "picturebook:picturetemplates"); 111 if (pictureConversions.isEmpty()) { 112 pictureConversions = null; 113 } 114 } 115 116 if (emptyPictureImageInfo == null) { 117 ImagingService imagingService = Framework.getLocalService(ImagingService.class); 118 emptyPictureImageInfo = imagingService.getImageInfo(blob); 119 } 120 121 PictureResourceAdapter adapter = doc.getAdapter(PictureResourceAdapter.class); 122 adapter.preFillPictureViews(blob, pictureConversions, emptyPictureImageInfo); 123 } catch (IOException e) { 124 log.error("Error while pre-filling picture views: " + e.getMessage(), e); 125 } 126 } 127 128 protected String getEmptyPicturePath() { 129 return EMPTY_PICTURE_PATH; 130 } 131 132 protected DocumentModel getParentDocument(CoreSession session, DocumentModel doc) { 133 DocumentModel parent; 134 if (session.exists(doc.getRef())) { 135 parent = session.getParentDocument(doc.getRef()); 136 } else { 137 Path parentPath = doc.getPath().removeLastSegments(1); 138 parent = session.getDocument(new PathRef(parentPath.toString())); 139 } 140 return parent; 141 } 142 143}