View Javadoc
1   /**
2    * This file Copyright (c) 2003-2014 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.gui.dialog;
35  
36  import info.magnolia.cms.beans.config.MIMEMapping;
37  import info.magnolia.cms.beans.runtime.Document;
38  import info.magnolia.cms.beans.runtime.MultipartForm;
39  import info.magnolia.cms.core.Content;
40  import info.magnolia.cms.gui.control.File;
41  import info.magnolia.cms.gui.misc.CssConstants;
42  import info.magnolia.cms.gui.misc.Spacer;
43  
44  import java.io.IOException;
45  import java.io.Writer;
46  import java.util.ArrayList;
47  import java.util.List;
48  
49  import javax.jcr.PropertyType;
50  import javax.jcr.RepositoryException;
51  import javax.servlet.http.HttpServletRequest;
52  import javax.servlet.http.HttpServletResponse;
53  
54  import org.apache.commons.lang.StringUtils;
55  
56  
57  /**
58   * @author Vinzenz Wyser
59   * @version 2.0
60   */
61  public class DialogFile extends DialogBox {
62  
63      private List imageExtensions = new ArrayList();
64      private final int defaultImageSize = 150;
65  
66      /**
67       * @see info.magnolia.cms.gui.dialog.DialogControl#init(HttpServletRequest, HttpServletResponse, Content, Content)
68       */
69      @Override
70      public void init(HttpServletRequest request, HttpServletResponse response, Content websiteNode, Content configNode)
71              throws RepositoryException {
72          super.init(request, response, websiteNode, configNode);
73          initImageExtensions();
74      }
75  
76      public List getImageExtensions() {
77          return this.imageExtensions;
78      }
79  
80      public void setImageExtensions(List l) {
81          this.imageExtensions = l;
82      }
83  
84      public void initImageExtensions() {
85          this.getImageExtensions().add("jpg"); //$NON-NLS-1$
86          this.getImageExtensions().add("jpeg"); //$NON-NLS-1$
87          this.getImageExtensions().add("gif"); //$NON-NLS-1$
88          this.getImageExtensions().add("png"); //$NON-NLS-1$
89          this.getImageExtensions().add("bmp"); //$NON-NLS-1$
90          this.getImageExtensions().add("swf"); //$NON-NLS-1$
91      }
92  
93      @Override
94      public void drawHtml(Writer out) throws IOException {
95          File control = getFileControl();
96          control.setType(this.getConfigValue("type", PropertyType.TYPENAME_STRING)); //$NON-NLS-1$
97          control.setSaveInfo(false); // set manualy below
98          control.setCssClass(CssConstants.CSSCLASS_FILE);
99          control.setCssClassFileName(CssConstants.CSSCLASS_EDIT);
100         control.setCssStyles("width", this.getConfigValue("width", "100%")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
101 
102         this.drawHtmlPre(out);
103 
104         String width = this.getConfigValue("width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$
105 
106 
107         final boolean preview = Boolean.valueOf(getConfigValue("preview", "true")).booleanValue();
108         final boolean readonly = Boolean.valueOf(getConfigValue("readonly", "false")).booleanValue();
109         final boolean extensionIsDisplayableImage = this.getImageExtensions().contains(control.getExtension().toLowerCase());
110         final boolean showImage = extensionIsDisplayableImage && preview;
111 
112         StringBuffer htmlControlFileName = getHtmlControlFileName(control);
113         String htmlContentEmpty = control.getHtmlBrowse() + Spacer.getHtml(0, 0) + htmlControlFileName;
114         out.write("<div id=\"" + this.getName() + "_contentDiv\" style=\"width:100%;\">"); //$NON-NLS-1$ //$NON-NLS-2$
115         boolean exists = false;
116 
117         if (this.getStorageNode() != null) {
118             exists = this.getStorageNode().getNodeData(this.getName()).isExist();
119         }
120 
121         if (!exists && !readonly) {
122             out.write(htmlContentEmpty);
123             out.write("</div>"); //$NON-NLS-1$
124         }
125         else {
126             String link = getLink(control);
127 
128             if (showImage) {
129 
130                 out.write("\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"" + width + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
131                 out.write("<tr><td class=\"" + CssConstants.CSSCLASS_FILEIMAGE + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
132 
133                 if ("swf".equals(control.getExtension().toLowerCase())) {
134 
135                     // flash movie
136                     out.write("<object type=\"application/x-shockwave-flash\" data=\"");
137                     out.write(link);
138                     out.write("\" title=\"");
139                     out.write(control.getFileName());
140                     out.write("\" ");
141                     out.write("width=\"" + defaultImageSize +
142                             "\" ");
143                     out.write("height=\"" + (int)(2*(double)defaultImageSize/3) +
144                             "\" ");
145                     out.write(">");
146 
147                     out.write("<param name=\"movie\" value=\"");
148                     out.write(link);
149                     out.write("\"/>");
150 
151                     out.write("</object>\n");
152 
153                 }
154                 else {
155                     // standard image
156 
157                     // todo: image thumbnail template
158                     // out.write("<img src=\""+ this.getRequest().getContextPath()
159                     // +THUMB_PATH+"?src="+control.getHandle()+"\"
160                     // class=\""+CSSCLASS_FILEIMAGE+"\">");
161                     // tmp workaround: resize in html ...
162 
163                     int imgwidth = defaultImageSize;
164                     int imgheight = defaultImageSize;
165 
166                     try{
167                         imgwidth = Integer.parseInt(control.getImageWidth());
168                         imgheight = Integer.parseInt(control.getImageHeight());
169                     }
170                     catch(NumberFormatException e){
171                         // ignore (default values are already set)
172                     }
173 
174                     // resize if to big
175                     if(imgwidth == imgheight && imgwidth > defaultImageSize){
176                         imgwidth = defaultImageSize;
177                         imgheight = defaultImageSize;
178                     }
179                     else if(imgwidth > imgheight && imgwidth > defaultImageSize){
180                         imgheight = (int)((double)defaultImageSize/imgwidth * imgheight);
181                         imgwidth = defaultImageSize;
182                     }
183                     else if(imgheight > imgwidth && imgheight > defaultImageSize){
184                         imgwidth = (int)((double)defaultImageSize/imgheight * imgwidth);
185                         imgheight = defaultImageSize;
186                     }
187 
188                     out.write("<img width=\"" + imgwidth + "\" height=\"" + imgheight + "\" src=\""); //$NON-NLS-1$
189                     out.write(link);
190                     out.write("\" class=\""); //$NON-NLS-1$
191                     out.write(CssConstants.CSSCLASS_FILEIMAGE);
192                     out.write("\" alt=\""); //$NON-NLS-1$
193                     out.write(control.getFileName());
194                     out.write("\" title=\""); //$NON-NLS-1$
195                     out.write(control.getFileName());
196                     out.write("\" />\n"); //$NON-NLS-1$
197 
198                     if (StringUtils.isNotEmpty(control.getImageWidth())) {
199                         out.write("<em style='white-space:nowrap'>"); //$NON-NLS-1$
200 
201                         out.write("width: "); //$NON-NLS-1$
202                         out.write(control.getImageWidth());
203 
204                         out.write(" height: "); //$NON-NLS-1$
205                         out.write(control.getImageHeight());
206 
207                         out.write("</em>\n"); //$NON-NLS-1$
208                     }
209 
210                 }
211 
212                 out.write("</td><td>"); //$NON-NLS-1$
213             }
214             if (!readonly) {
215                 writeInnerHtml(out, showImage, control, htmlControlFileName, link);
216                 out.write(Spacer.getHtml(12, 12));
217                 out.write(control.getHtmlRemove("mgnlDialogFileRemove('" + this.getName() + "');")); //$NON-NLS-1$ //$NON-NLS-2$
218             }
219             if (showImage) {
220                 out.write("</td></tr></table>"); //$NON-NLS-1$
221             }
222             out.write("</div>\n"); //$NON-NLS-1$
223             out.write("<div style=\"position:absolute;top:-500px;left:-500px;visibility:hidden;\">\n<textarea id=\""); //$NON-NLS-1$
224             out.write(this.getName());
225             out.write("_contentEmpty\">");//$NON-NLS-1$
226             out.write(htmlContentEmpty);
227 
228             // @todo should be escaped, but we need to test it
229             // out.write(StringEscapeUtils.escapeXml(htmlContentEmpty));
230             out.write("</textarea>\n</div>\n"); //$NON-NLS-1$
231         }
232         control.setSaveInfo(true);
233         out.write(control.getHtmlSaveInfo());
234         control.setNodeDataTemplate(this.getConfigValue("nodeDataTemplate", null)); //$NON-NLS-1$
235         out.write(control.getHtmlNodeDataTemplate());
236         this.drawHtmlPost(out);
237     }
238 
239     protected String getLink(File control) {
240         String link = this.getRequest().getContextPath() + getFileURI(control) + "/" + control.getFileName();
241         if (!StringUtils.isEmpty(control.getExtension())) {
242             link += "." + control.getExtension();
243         }
244         return link;
245     }
246 
247     protected void writeInnerHtml(Writer out, final boolean showImage, File control, StringBuffer htmlControlFileName, String link) throws IOException {
248         out.write(htmlControlFileName.toString());
249         if (!showImage) {
250             String iconPath = MIMEMapping.getMIMETypeIcon(control.getExtension());
251 
252             out.write(Spacer.getHtml(0, 0));
253 
254             out.write("<a href=");
255             out.write(link);
256             out.write(" target=\"_blank\">"); //$NON-NLS-1$
257 
258             out.write("<img src=\"" //$NON-NLS-1$
259                     + this.getRequest().getContextPath()
260                     + iconPath
261                     + "\" class=\"" //$NON-NLS-1$
262                     + CssConstants.CSSCLASS_FILEICON
263                     + "\" border=\"0\">"); //$NON-NLS-1$
264             out.write(control.getFileName() + "." + control.getExtension() + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
265         }
266     }
267 
268     protected StringBuffer getHtmlControlFileName(File control) {
269         StringBuffer htmlControlFileName = new StringBuffer();
270         htmlControlFileName.append("<span class=\"" //$NON-NLS-1$
271                 + CssConstants.CSSCLASS_DESCRIPTION
272                 + "\">" //$NON-NLS-1$
273                 + getMessage("dialog.file.filename") //$NON-NLS-1$
274                 + "</span>"); //$NON-NLS-1$
275         htmlControlFileName.append(Spacer.getHtml(1, 1));
276         htmlControlFileName.append(control.getHtmlFileName() + "<span id=\"" //$NON-NLS-1$
277                 + this.getName()
278                 + "_fileNameExtension\">." //$NON-NLS-1$
279                 + control.getExtension()
280                 + "</span>"); //$NON-NLS-1$
281         return htmlControlFileName;
282     }
283 
284     @Override
285     public boolean validate() {
286         if (isRequired()) {
287             // if we have a form, then this is going to the database
288             MultipartForm form = (MultipartForm) getRequest().getAttribute(MultipartForm.REQUEST_ATTRIBUTE_NAME);
289             if (form != null) {
290                 Document doc = form.getDocument(getName());
291                 if (doc != null) { // we're submitting a document for this required field
292                     return true;
293                 }
294                 // we're removing the document
295                 // for this required field but
296                 // not uploading one
297                 if (form.getParameter(getName() + "_" + File.REMOVE) != null) {
298                     setValidationMessage("dialogs.validation.required");
299                     return false;
300                 }
301             }
302             // we are not uploading or removing
303             // check if there is a binary stored
304             if(this.getStorageNode() == null || !getStorageNode().getNodeData(getName()).isExist()){
305                 setValidationMessage("dialogs.validation.required");
306                 return false;
307             }
308         }
309         return true;
310     }
311 
312     /**
313      * Get the uri of the file (used to show images)
314      * @param control
315      * @return
316      */
317     protected String getFileURI(File control) {
318         return control.getHandle();
319     }
320 
321     /**
322      * Configures the inner file upload control
323      */
324     protected File getFileControl() {
325         File control = new File(this.getName(), this.getStorageNode());
326         return control;
327     }
328 }