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