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}