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