001/* 002 * (C) Copyright 2006-2007 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: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $ 020 */ 021 022package org.nuxeo.ecm.platform.picture.web; 023 024import static org.jboss.seam.ScopeType.CONVERSATION; 025 026import java.io.IOException; 027import java.io.Serializable; 028import java.util.ArrayList; 029import java.util.HashMap; 030import java.util.Map; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.jboss.seam.annotations.Create; 035import org.jboss.seam.annotations.Destroy; 036import org.jboss.seam.annotations.In; 037import org.jboss.seam.annotations.Name; 038import org.jboss.seam.annotations.Observer; 039import org.jboss.seam.annotations.Scope; 040import org.jboss.seam.annotations.intercept.BypassInterceptors; 041import org.jboss.seam.annotations.remoting.WebRemote; 042import org.jboss.seam.annotations.web.RequestParameter; 043import org.nuxeo.ecm.core.api.Blob; 044import org.nuxeo.ecm.core.api.CoreSession; 045import org.nuxeo.ecm.core.api.DocumentLocation; 046import org.nuxeo.ecm.core.api.DocumentModel; 047import org.nuxeo.ecm.core.api.IdRef; 048import org.nuxeo.ecm.core.api.model.Property; 049import org.nuxeo.ecm.platform.commandline.executor.api.CommandAvailability; 050import org.nuxeo.ecm.platform.commandline.executor.api.CommandLineExecutorService; 051import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter; 052import org.nuxeo.ecm.platform.ui.web.api.NavigationContext; 053import org.nuxeo.ecm.platform.ui.web.rest.RestHelper; 054import org.nuxeo.ecm.platform.ui.web.tag.fn.DocumentModelFunctions; 055import org.nuxeo.ecm.platform.ui.web.util.ComponentUtils; 056import org.nuxeo.ecm.platform.url.api.DocumentView; 057import org.nuxeo.ecm.platform.url.codec.DocumentFileCodec; 058import org.nuxeo.ecm.platform.util.RepositoryLocation; 059import org.nuxeo.ecm.webapp.helpers.EventNames; 060import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor; 061import org.nuxeo.runtime.api.Framework; 062 063/** 064 * @author <a href="mailto:ldoguin@nuxeo.com">Laurent Doguin</a> 065 */ 066@Name("pictureManager") 067@Scope(CONVERSATION) 068public class PictureManagerBean implements PictureManager, Serializable { 069 070 private static final long serialVersionUID = 1L; 071 072 private static final Log log = LogFactory.getLog(PictureManagerBean.class); 073 074 protected static Boolean imageMagickAvailable; 075 076 @In(create = true, required = false) 077 protected transient CoreSession documentManager; 078 079 @RequestParameter 080 protected String fileFieldFullName; 081 082 @In(required = true, create = true) 083 protected transient NavigationContext navigationContext; 084 085 @In(create = true, required = false) 086 protected ResourcesAccessor resourcesAccessor; 087 088 protected String fileurlPicture; 089 090 protected String filename; 091 092 protected Blob fileContent; 093 094 protected Integer index; 095 096 protected String cropCoords; 097 098 protected ArrayList<Map<String, Object>> selectItems; 099 100 @Override 101 @Create 102 public void initialize() { 103 log.debug("Initializing..."); 104 index = 0; 105 } 106 107 protected DocumentModel getCurrentDocument() { 108 return navigationContext.getCurrentDocument(); 109 } 110 111 @Override 112 @SuppressWarnings("unchecked") 113 public String getFileurlPicture() { 114 ArrayList<Map<String, Object>> views = (ArrayList) getCurrentDocument().getProperty("picture", "views"); 115 return views.get(index).get("title") + ":content"; 116 } 117 118 @Override 119 public void setFileurlPicture(String fileurlPicture) { 120 this.fileurlPicture = fileurlPicture; 121 } 122 123 @SuppressWarnings({ "unchecked", "rawtypes" }) 124 protected void initSelectItems() { 125 selectItems = new ArrayList<Map<String, Object>>(); 126 DocumentModel doc = getCurrentDocument(); 127 ArrayList<Map<String, Object>> views = (ArrayList) doc.getProperty("picture", "views"); 128 for (int i = 0; i < views.size(); i++) { 129 Map<String, Object> map = new HashMap<String, Object>(); 130 map.put("title", views.get(i).get("title")); 131 map.put("idx", i); 132 selectItems.add(map); 133 } 134 } 135 136 @Override 137 public ArrayList getSelectItems() { 138 if (selectItems == null) { 139 initSelectItems(); 140 return selectItems; 141 } else { 142 return selectItems; 143 } 144 } 145 146 @Override 147 public void setSelectItems(ArrayList selectItems) { 148 this.selectItems = selectItems; 149 } 150 151 @Override 152 public String rotate90left() throws IOException { 153 DocumentModel doc = getCurrentDocument(); 154 PictureResourceAdapter picture = doc.getAdapter(PictureResourceAdapter.class); 155 picture.doRotate(-90); 156 documentManager.saveDocument(doc); 157 documentManager.save(); 158 navigationContext.setCurrentDocument(doc); 159 return null; 160 } 161 162 @Override 163 public String rotate90right() throws IOException { 164 DocumentModel doc = getCurrentDocument(); 165 PictureResourceAdapter picture = doc.getAdapter(PictureResourceAdapter.class); 166 picture.doRotate(90); 167 documentManager.saveDocument(doc); 168 documentManager.save(); 169 navigationContext.setCurrentDocument(doc); 170 return null; 171 } 172 173 @Override 174 public String crop() throws IOException { 175 if (cropCoords != null && !cropCoords.equals("")) { 176 DocumentModel doc = getCurrentDocument(); 177 PictureResourceAdapter picture = doc.getAdapter(PictureResourceAdapter.class); 178 picture.doCrop(cropCoords); 179 documentManager.saveDocument(doc); 180 documentManager.save(); 181 navigationContext.setCurrentDocument(doc); 182 } 183 return null; 184 } 185 186 @Override 187 @Observer(value = { EventNames.DOCUMENT_SELECTION_CHANGED, EventNames.DOCUMENT_CHANGED }) 188 @BypassInterceptors 189 public void resetFields() { 190 filename = ""; 191 fileContent = null; 192 selectItems = null; 193 index = 0; 194 cropCoords = null; 195 } 196 197 @WebRemote 198 public String remoteDownload(String patternName, String docID, String blobPropertyName, String filename) 199 { 200 IdRef docref = new IdRef(docID); 201 DocumentModel doc = documentManager.getDocument(docref); 202 return DocumentModelFunctions.fileUrl(patternName, doc, blobPropertyName, filename); 203 } 204 205 @WebRemote 206 public static String urlPopup(String url) { 207 return RestHelper.addCurrentConversationParameters(url); 208 } 209 210 @Override 211 public void download(DocumentView docView) { 212 if (docView != null) { 213 DocumentLocation docLoc = docView.getDocumentLocation(); 214 // fix for NXP-1799 215 if (documentManager == null) { 216 RepositoryLocation loc = new RepositoryLocation(docLoc.getServerName()); 217 navigationContext.setCurrentServerLocation(loc); 218 documentManager = navigationContext.getOrCreateDocumentManager(); 219 } 220 DocumentModel doc = documentManager.getDocument(docLoc.getDocRef()); 221 if (doc == null) { 222 return; 223 } 224 String path = docView.getParameter(DocumentFileCodec.FILE_PROPERTY_PATH_KEY); 225 String[] propertyPath = path.split(":"); 226 String title = null; 227 String field = null; 228 Property datamodel = null; 229 if (propertyPath.length == 2) { 230 title = propertyPath[0]; 231 field = propertyPath[1]; 232 datamodel = doc.getProperty("picture:views"); 233 } else if (propertyPath.length == 3) { 234 String schema = propertyPath[0]; 235 title = propertyPath[1]; 236 field = propertyPath[2]; 237 datamodel = doc.getProperty(schema + ":" + "views"); 238 } 239 Property view = null; 240 for (Property property : datamodel) { 241 if (property.get("title").getValue().equals(title)) { 242 view = property; 243 } 244 } 245 246 if (view == null) { 247 for (Property property : datamodel) { 248 if (property.get("title").getValue().equals("Thumbnail")) { 249 view = property; 250 } 251 } 252 } 253 if (view == null) { 254 return; 255 } 256 Blob blob = (Blob) view.getValue(field); 257 String filename = (String) view.getValue("filename"); 258 // download 259 ComponentUtils.download(doc, path, blob, filename, "picture"); 260 } 261 } 262 263 @Override 264 @Destroy 265 public void destroy() { 266 log.debug("Removing Seam action listener..."); 267 fileurlPicture = null; 268 filename = null; 269 fileContent = null; 270 index = null; 271 selectItems = null; 272 } 273 274 @Override 275 public String getFilename() { 276 return filename; 277 } 278 279 @Override 280 public void setFilename(String filename) { 281 this.filename = filename; 282 } 283 284 @Override 285 public Blob getFileContent() { 286 return fileContent; 287 } 288 289 @Override 290 public void setFileContent(Blob fileContent) { 291 this.fileContent = fileContent; 292 } 293 294 @Override 295 public Integer getIndex() { 296 return index; 297 } 298 299 @Override 300 public void setIndex(Integer index) { 301 this.index = index; 302 } 303 304 @Override 305 public String getCropCoords() { 306 return cropCoords; 307 } 308 309 @Override 310 public void setCropCoords(String cropCoords) { 311 this.cropCoords = cropCoords; 312 } 313 314 public Boolean isImageMagickAvailable() { 315 if (imageMagickAvailable == null) { 316 CommandLineExecutorService cles = Framework.getService(CommandLineExecutorService.class); 317 CommandAvailability ca = cles.getCommandAvailability("cropAndResize"); 318 imageMagickAvailable = ca.isAvailable(); 319 } 320 return imageMagickAvailable; 321 } 322}