View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.ecm.webui.component.explorer.thumbnail;
18  
19  import java.awt.image.BufferedImage;
20  
21  import javax.imageio.ImageIO;
22  import javax.jcr.AccessDeniedException;
23  import javax.jcr.Node;
24  import javax.jcr.PathNotFoundException;
25  import javax.jcr.lock.LockException;
26  import javax.jcr.version.VersionException;
27  
28  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
29  import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
30  import org.exoplatform.ecm.webui.utils.Utils;
31  import org.exoplatform.services.cms.mimetype.DMSMimeTypeResolver;
32  import org.exoplatform.services.cms.thumbnail.ThumbnailService;
33  import org.exoplatform.services.log.ExoLogger;
34  import org.exoplatform.services.log.Log;
35  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
36  import org.exoplatform.upload.UploadResource;
37  import org.exoplatform.web.application.ApplicationMessage;
38  import org.exoplatform.webui.application.WebuiRequestContext;
39  import org.exoplatform.webui.config.annotation.ComponentConfig;
40  import org.exoplatform.webui.config.annotation.ComponentConfigs;
41  import org.exoplatform.webui.config.annotation.EventConfig;
42  import org.exoplatform.webui.core.UIApplication;
43  import org.exoplatform.webui.core.UIPopupComponent;
44  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
45  import org.exoplatform.webui.event.Event;
46  import org.exoplatform.webui.event.Event.Phase;
47  import org.exoplatform.webui.event.EventListener;
48  import org.exoplatform.webui.form.UIForm;
49  import org.exoplatform.webui.form.input.UIUploadInput;
50  
51  /**
52   * Created by The eXo Platform SARL
53   * Author : Dang Van Minh
54   *          minh.dang@exoplatform.com
55   * Oct 24, 2008 10:52:13 AM
56   */
57  @ComponentConfigs({
58      @ComponentConfig(lifecycle = UIFormLifecycle.class, template = "app:/groovy/webui/component/explorer/thumbnail/UIThumbnailForm.gtmpl", events = {
59          @EventConfig(listeners = UIThumbnailForm.SaveActionListener.class),
60          @EventConfig(listeners = UIThumbnailForm.CancelActionListener.class, phase = Phase.DECODE),
61          @EventConfig(listeners = UIThumbnailForm.RemoveThumbnailActionListener.class, confirm = "UIThumbnailForm.msg.confirm-delete", phase = Phase.DECODE),
62          @EventConfig(listeners = UIThumbnailForm.PreviewActionListener.class) }),
63      @ComponentConfig(id="mediumSize", type = UIUploadInput.class, template = "app:/groovy/webui/component/explorer/thumbnail/UIFormUploadInput.gtmpl") })
64  public class UIThumbnailForm extends UIForm implements UIPopupComponent {
65  
66    /**
67     * Logger.
68     */
69    private static final Log LOG  = ExoLogger.getLogger(UIThumbnailForm.class.getName());
70  
71    private static final String THUMBNAIL_FIELD = "mediumSize";
72  
73    private UploadResource currentUploadResource;
74    private BufferedImage currentUploadImage;
75    private String currentPreviewLink;
76  
77    public UIThumbnailForm() throws Exception {
78      initForm();
79    }
80  
81    private void initForm() throws Exception {
82      currentUploadResource = null;
83      currentUploadImage = null;
84      currentPreviewLink = null;
85  
86      setMultiPart(true);
87      UIUploadInput uiInput = new UIUploadInput(THUMBNAIL_FIELD, THUMBNAIL_FIELD);
88      removeChild(UIUploadInput.class);
89      addUIFormInput(uiInput);
90    }
91  
92    public String getThumbnailImage(Node node) throws Exception {
93      return Utils.getThumbnailImage(node, ThumbnailService.MEDIUM_SIZE);
94    }
95  
96    public String getPreviewImage() throws Exception {
97      UIUploadInput input = this.getUIInput(THUMBNAIL_FIELD);
98      String uploadId = input.getUploadIds()[0];
99      if(input.getUploadResource(uploadId) == null)  return null;
100     return Utils.getThumbnailImage(input.getUploadDataAsStream(uploadId), input.getUploadResource(uploadId).getFileName());
101   }
102 
103   public Node getSelectedNode() throws Exception {
104     return getAncestorOfType(UIJCRExplorer.class).getRealCurrentNode();
105   }
106 
107   /* (non-Javadoc)
108    * @see org.exoplatform.webui.form.UIForm#processRender(org.exoplatform.webui.application.WebuiRequestContext)
109    */
110   @Override
111   public void processRender(WebuiRequestContext context) throws Exception {
112     Node currentRealNode = getSelectedNode();
113     if (getThumbnailImage(currentRealNode) == null) {
114       setActions(new String[] {"Save", "Cancel"});
115     } else {
116       setActions(new String[] {"RemoveThumbnail", "Cancel"});
117     }
118     super.processRender(context);
119   }
120 
121   public Node getThumbnailNode(Node node) throws Exception {
122     ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
123     return thumbnailService.getThumbnailNode(node);
124   }
125 
126   /**
127    * @return the currentUploadImage
128    */
129   public BufferedImage getCurrentUploadImage() {
130     return currentUploadImage;
131   }
132 
133   /**
134    * @param currentUploadImage the currentUploadImage to set
135    */
136   public void setCurrentUploadImage(BufferedImage currentUploadImage) {
137     this.currentUploadImage = currentUploadImage;
138   }
139 
140   /**
141    * @return the currentUploadResource
142    */
143   public UploadResource getCurrentUploadResource() {
144     return currentUploadResource;
145   }
146 
147   /**
148    * @param currentUploadResource the currentUploadResource to set
149    */
150   public void setCurrentUploadResource(UploadResource currentUploadResource) {
151     this.currentUploadResource = currentUploadResource;
152   }
153 
154   /**
155    * @param currentPreviewLink the currentPreviewLink to set
156    */
157   public void setCurrentPreviewLink(String currentPreviewLink) {
158     this.currentPreviewLink = currentPreviewLink;
159   }
160 
161   /**
162    * @return the currentPreviewLink
163    */
164   public String getCurrentPreviewLink() {
165     return currentPreviewLink;
166   }
167 
168   /**
169    * return the Modified date property of the selected node
170    *
171    * @param node the thumbnail node of the selected node
172    * @return the Modified date property
173    * @throws Exception
174    */
175   public String getThumbnailModifiedTime(Node node) throws Exception {
176     boolean hasLastModifiedProperty = node.hasProperty(ThumbnailService.THUMBNAIL_LAST_MODIFIED);
177     if (hasLastModifiedProperty) {
178       return node.getProperty(ThumbnailService.THUMBNAIL_LAST_MODIFIED).getDate().getTime().toString();
179     } else {
180       LOG.warn("Thumbnail last modified property of the node " + node.getPath() + " doesn't exist.");
181       return null;
182     }
183   }
184 
185   static  public class SaveActionListener extends EventListener<UIThumbnailForm> {
186     public void execute(Event<UIThumbnailForm> event) throws Exception {
187       UIThumbnailForm uiForm = event.getSource();
188       UIApplication uiApp = uiForm.getAncestorOfType(UIApplication.class) ;
189       UIJCRExplorer uiExplorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
190 
191       // Check resource available
192       if(uiForm.getCurrentUploadResource() == null) {
193         uiApp.addMessage(new ApplicationMessage("UIThumbnailForm.msg.fileName-error", null,
194                                                 ApplicationMessage.WARNING));
195         event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
196 
197         return;
198       }
199 
200       // Check if file is image
201       String fileName = uiForm.getCurrentUploadResource().getFileName();
202       DMSMimeTypeResolver mimeTypeSolver = DMSMimeTypeResolver.getInstance();
203       String mimeType = mimeTypeSolver.getMimeType(fileName) ;
204       if(!mimeType.startsWith("image")) {
205         uiApp.addMessage(new ApplicationMessage("UIThumbnailForm.msg.mimetype-incorrect", null,
206             ApplicationMessage.WARNING));
207 
208         return;
209       }
210 
211       // Add lock token
212       Node selectedNode = uiExplorer.getRealCurrentNode();
213       uiExplorer.addLockToken(selectedNode);
214 
215       // Create thumbnail
216       ThumbnailService thumbnailService = WCMCoreUtils.getService(ThumbnailService.class);
217       try {
218         thumbnailService.createThumbnailImage(selectedNode, uiForm.getCurrentUploadImage(), mimeType);
219 
220         selectedNode.getSession().save();
221         uiExplorer.updateAjax(event);
222       } catch(AccessDeniedException ace) {
223         uiApp.addMessage(new ApplicationMessage("UIThumbnailForm.msg.access-denied", null, ApplicationMessage.WARNING));
224       } catch(VersionException ver) {
225         uiApp.addMessage(new ApplicationMessage("UIThumbnailForm.msg.is-checked-in", null, ApplicationMessage.WARNING));
226       } catch(LockException lock) {
227         Object[] arg = { selectedNode.getPath() };
228         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.node-locked", arg, ApplicationMessage.WARNING));
229       } catch(PathNotFoundException path) {
230         uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null,ApplicationMessage.WARNING));
231       } catch(Exception e) {
232         if (LOG.isErrorEnabled()) {
233           LOG.error("An unexpected error occurs", e);
234         }
235         JCRExceptionManager.process(uiApp, e);
236       }
237     }
238   }
239 
240   static  public class PreviewActionListener extends EventListener<UIThumbnailForm> {
241     public void execute(Event<UIThumbnailForm> event) throws Exception {
242       UIThumbnailForm uiForm = event.getSource();
243 
244       // Current review link
245       UIUploadInput input = (UIUploadInput)uiForm.getUIInput(THUMBNAIL_FIELD);
246       String uploadId = input.getUploadIds()[0];
247       if (input.getUploadDataAsStream(uploadId) != null) {
248         uiForm.setCurrentPreviewLink(uiForm.getPreviewImage());
249         uiForm.setCurrentUploadImage(ImageIO.read(input.getUploadDataAsStream(uploadId)));
250         uiForm.setCurrentUploadResource(input.getUploadResource(uploadId));
251       } else {
252         uiForm.setCurrentPreviewLink(null);
253         uiForm.setCurrentUploadImage(null);
254         uiForm.setCurrentUploadResource(null);
255       }
256 
257       // New upload input
258       uiForm.removeChild(UIUploadInput.class);
259       UIUploadInput uiInput = new UIUploadInput(THUMBNAIL_FIELD, THUMBNAIL_FIELD) ;
260       uiForm.addUIFormInput(uiInput) ;
261     }
262   }
263 
264   static  public class RemoveThumbnailActionListener extends EventListener<UIThumbnailForm> {
265     public void execute(Event<UIThumbnailForm> event) throws Exception {
266       UIThumbnailForm uiForm = event.getSource();
267       UIJCRExplorer uiExplorer = uiForm.getAncestorOfType(UIJCRExplorer.class);
268       Node selectedNode = uiExplorer.getRealCurrentNode();
269       UIApplication uiApp = uiForm.getAncestorOfType(UIApplication.class);
270       uiExplorer.addLockToken(selectedNode);
271       ThumbnailService thumbnailService = uiForm.getApplicationComponent(ThumbnailService.class);
272       Node thumbnailNode = thumbnailService.getThumbnailNode(selectedNode);
273       if(thumbnailNode != null) {
274         try {
275           // Remove thumbmail
276           thumbnailNode.remove();
277           selectedNode.getSession().save();
278 
279           // Reset form
280           uiForm.initForm();
281           event.getRequestContext().addUIComponentToUpdateByAjax(uiForm);
282         } catch(LockException lock) {
283           Object[] arg = { selectedNode.getPath() };
284           uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.node-locked", arg, ApplicationMessage.WARNING));
285         } catch(AccessDeniedException ace) {
286           uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.access-denied", null, ApplicationMessage.WARNING));
287           uiExplorer.updateAjax(event);
288         } catch(PathNotFoundException path) {
289           uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null,ApplicationMessage.WARNING));
290         } catch(Exception e) {
291           if (LOG.isErrorEnabled()) {
292             LOG.error("An unexpected error occurs", e);
293           }
294           JCRExceptionManager.process(uiApp, e);
295         }
296       }
297     }
298   }
299 
300   static  public class CancelActionListener extends EventListener<UIThumbnailForm> {
301     public void execute(Event<UIThumbnailForm> event) throws Exception {
302       UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
303       uiExplorer.cancelAction();
304     }
305   }
306 
307   public void activate() {}
308 
309   public void deActivate() {}
310 }