001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 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.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 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.picture.api.adapters; 021 022import static org.nuxeo.ecm.platform.picture.api.ImagingDocumentConstants.PICTURE_INFO_PROPERTY; 023 024import java.io.File; 025import java.io.IOException; 026import java.io.Serializable; 027import java.util.ArrayList; 028import java.util.Collection; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.ecm.core.api.Blob; 036import org.nuxeo.ecm.core.api.Blobs; 037import org.nuxeo.ecm.core.api.PropertyException; 038import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 039import org.nuxeo.ecm.core.api.blobholder.SimpleBlobHolder; 040import org.nuxeo.ecm.core.api.model.Property; 041import org.nuxeo.ecm.platform.picture.api.ImageInfo; 042import org.nuxeo.ecm.platform.picture.api.ImagingConvertConstants; 043import org.nuxeo.ecm.platform.picture.api.ImagingService; 044import org.nuxeo.ecm.platform.picture.api.PictureConversion; 045import org.nuxeo.ecm.platform.picture.api.PictureView; 046import org.nuxeo.runtime.api.Framework; 047 048public class DefaultPictureAdapter extends AbstractPictureAdapter { 049 private static final Log log = LogFactory.getLog(DefaultPictureAdapter.class); 050 051 // needs trailing slash 052 private static final String VIEW_XPATH = "picture:views/item[%d]/"; 053 054 private static final String TITLE_PROPERTY = "title"; 055 056 private static final String FILENAME_PROPERTY = "filename"; 057 058 @Override 059 public boolean createPicture(Blob blob, String filename, String title, 060 ArrayList<Map<String, Object>> pictureConversions) throws IOException { 061 return fillPictureViews(blob, filename, title, pictureConversions); 062 } 063 064 @Override 065 public boolean fillPictureViews(Blob blob, String filename, String title, 066 ArrayList<Map<String, Object>> pictureConversions) throws IOException { 067 if (blob == null) { 068 clearViews(); 069 return true; 070 } 071 072 File file = blob.getFile(); 073 if (file == null) { 074 file = File.createTempFile("nuxeoImage", ".jpg"); 075 Framework.trackFile(file, this); 076 blob.transferTo(file); 077 // use a persistent blob with our file 078 String digest = blob.getDigest(); 079 blob = Blobs.createBlob(file, blob.getMimeType(), blob.getEncoding(), blob.getFilename()); 080 blob.setDigest(digest); 081 } 082 083 fileContent = blob; 084 085 type = blob.getMimeType(); 086 if (type == null || type.equals("application/octet-stream")) { 087 // TODO : use MimetypeRegistry instead 088 type = getImagingService().getImageMimeType(file); 089 blob.setMimeType(type); 090 } 091 if (type == null || type.equals("application/octet-stream")) { 092 return false; 093 } 094 095 ImageInfo imageInfo = getImageInfo(); 096 if (imageInfo != null) { 097 doc.setPropertyValue(PICTURE_INFO_PROPERTY, (Serializable) imageInfo.toMap()); 098 } 099 100 if (imageInfo != null) { 101 width = imageInfo.getWidth(); 102 height = imageInfo.getHeight(); 103 depth = imageInfo.getDepth(); 104 } 105 106 if (width != null && height != null) { 107 clearViews(); 108 addViews(pictureConversions, filename, title); 109 } 110 return true; 111 } 112 113 @Override 114 public void preFillPictureViews(Blob blob, List<Map<String, Object>> pictureConversions, ImageInfo imageInfo) 115 throws IOException { 116 ImagingService imagingService = getImagingService(); 117 List<PictureView> pictureViews; 118 119 if (pictureConversions != null) { 120 List<PictureConversion> conversions = new ArrayList<PictureConversion>(pictureConversions.size()); 121 for (Map<String, Object> template : pictureConversions) { 122 conversions.add(new PictureConversion((String) template.get("title"), 123 (String) template.get("description"), (String) template.get("tag"), 0)); 124 } 125 126 pictureViews = imagingService.computeViewsFor(blob, conversions, imageInfo, false); 127 } else { 128 pictureViews = imagingService.computeViewsFor(doc, blob, imageInfo, false); 129 } 130 131 addPictureViews(pictureViews, true); 132 } 133 134 @Override 135 public void doRotate(int angle) { 136 int size = doc.getProperty(VIEWS_PROPERTY).size(); 137 for (int i = 0; i < size; i++) { 138 String xpath = "picture:views/view[" + i + "]/"; 139 BlobHolder blob = new SimpleBlobHolder(doc.getProperty(xpath + "content").getValue(Blob.class)); 140 String type = blob.getBlob().getMimeType(); 141 if (type != "image/png") { 142 Map<String, Serializable> options = new HashMap<String, Serializable>(); 143 options.put(ImagingConvertConstants.OPTION_ROTATE_ANGLE, angle); 144 blob = getConversionService().convert(ImagingConvertConstants.OPERATION_ROTATE, blob, options); 145 doc.getProperty(xpath + "content").setValue(blob.getBlob()); 146 Long height = (Long) doc.getProperty(xpath + "height").getValue(); 147 Long width = (Long) doc.getProperty(xpath + "width").getValue(); 148 doc.getProperty(xpath + "height").setValue(width); 149 doc.getProperty(xpath + "width").setValue(height); 150 } 151 } 152 } 153 154 @Override 155 public void doCrop(String coords) { 156 doc.setPropertyValue("picture:cropCoords", coords); 157 } 158 159 @Override 160 public Blob getPictureFromTitle(String title) throws PropertyException { 161 if (title == null) { 162 return null; 163 } 164 Collection<Property> views = doc.getProperty(VIEWS_PROPERTY).getChildren(); 165 for (Property property : views) { 166 if (title.equals(property.getValue(TITLE_PROPERTY))) { 167 Blob blob = (Blob) property.getValue("content"); 168 if (blob != null) { 169 blob.setFilename((String) property.getValue(FILENAME_PROPERTY)); 170 } 171 return blob; 172 } 173 } 174 return null; 175 } 176 177 @Override 178 public String getFirstViewXPath() { 179 return getViewXPathFor(0); 180 } 181 182 @Override 183 public String getViewXPath(String viewName) { 184 Property views = doc.getProperty(VIEWS_PROPERTY); 185 for (int i = 0; i < views.size(); i++) { 186 if (views.get(i).getValue(TITLE_PROPERTY).equals(viewName)) { 187 return getViewXPathFor(i); 188 } 189 } 190 return null; 191 } 192 193 protected String getViewXPathFor(int index) { 194 return String.format(VIEW_XPATH, index); 195 } 196 197}