View Javadoc

1   /**
2    * This file Copyright (c) 2003-2012 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 extensionIsDisplayableImage = this.getImageExtensions().contains(control.getExtension().toLowerCase());
109         final boolean showImage = extensionIsDisplayableImage && preview;
110 
111         StringBuffer htmlControlFileName = getHtmlControlFileName(control);
112         String htmlContentEmpty = control.getHtmlBrowse() + Spacer.getHtml(0, 0) + htmlControlFileName;
113         out.write("<div id=\"" + this.getName() + "_contentDiv\" style=\"width:100%;\">"); //$NON-NLS-1$ //$NON-NLS-2$
114         boolean exists = false;
115 
116         if (this.getStorageNode() != null) {
117             exists = this.getStorageNode().getNodeData(this.getName()).isExist();
118         }
119 
120         if (!exists) {
121             out.write(htmlContentEmpty);
122             out.write("</div>"); //$NON-NLS-1$
123         }
124         else {
125             String link = getLink(control);
126 
127             if (showImage) {
128 
129                 out.write("\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"" + width + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
130                 out.write("<tr><td class=\"" + CssConstants.CSSCLASS_FILEIMAGE + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
131 
132                 if ("swf".equals(control.getExtension().toLowerCase())) {
133 
134                     // flash movie
135                     out.write("<object type=\"application/x-shockwave-flash\" data=\"");
136                     out.write(link);
137                     out.write("\" title=\"");
138                     out.write(control.getFileName());
139                     out.write("\" ");
140                     out.write("width=\"" + defaultImageSize +
141                             "\" ");
142                     out.write("height=\"" + (int)(2*(double)(defaultImageSize)/3) +
143                             "\" ");
144                     out.write(">");
145 
146                     out.write("<param name=\"movie\" value=\"");
147                     out.write(link);
148                     out.write("\"/>");
149 
150                     out.write("</object>\n");
151 
152                 }
153                 else {
154                     // standard image
155 
156                     // todo: image thumbnail template
157                     // out.write("<img src=\""+ this.getRequest().getContextPath()
158                     // +THUMB_PATH+"?src="+control.getHandle()+"\"
159                     // class=\""+CSSCLASS_FILEIMAGE+"\">");
160                     // tmp workaround: resize in html ...
161 
162                     int imgwidth = defaultImageSize;
163                     int imgheight = defaultImageSize;
164 
165                     try{
166                         imgwidth = Integer.parseInt(control.getImageWidth());
167                         imgheight = Integer.parseInt(control.getImageHeight());
168                     }
169                     catch(NumberFormatException e){
170                         // ignore (default values are already set)
171                     }
172 
173                     // resize if to big
174                     if(imgwidth == imgheight && imgwidth > defaultImageSize){
175                         imgwidth = defaultImageSize;
176                         imgheight = defaultImageSize;
177                     }
178                     else if(imgwidth > imgheight && imgwidth > defaultImageSize){
179                         imgheight = (int)((double)(defaultImageSize)/imgwidth * imgheight);
180                         imgwidth = defaultImageSize;
181                     }
182                     else if(imgheight > imgwidth && imgheight > defaultImageSize){
183                         imgwidth = (int)((double)(defaultImageSize)/imgheight * imgwidth);
184                         imgheight = defaultImageSize;
185                     }
186 
187                     out.write("<img width=\"" + imgwidth + "\" height=\"" + imgheight + "\"src=\""); //$NON-NLS-1$
188                     out.write(link);
189                     out.write("\" class=\""); //$NON-NLS-1$
190                     out.write(CssConstants.CSSCLASS_FILEIMAGE);
191                     out.write("\" alt=\""); //$NON-NLS-1$
192                     out.write(control.getFileName());
193                     out.write("\" title=\""); //$NON-NLS-1$
194                     out.write(control.getFileName());
195                     out.write("\" />\n"); //$NON-NLS-1$
196 
197                     if (StringUtils.isNotEmpty(control.getImageWidth())) {
198                         out.write("<em style='white-space:nowrap'>"); //$NON-NLS-1$
199 
200                         out.write("width: "); //$NON-NLS-1$
201                         out.write(control.getImageWidth());
202 
203                         out.write(" height: "); //$NON-NLS-1$
204                         out.write(control.getImageHeight());
205 
206                         out.write("</em>\n"); //$NON-NLS-1$
207                     }
208 
209                 }
210 
211                 out.write("</td><td>"); //$NON-NLS-1$
212             }
213             writeInnerHtml(out, showImage, control, htmlControlFileName, link);
214 
215             out.write(Spacer.getHtml(12, 12));
216             out.write(control.getHtmlRemove("mgnlDialogFileRemove('" + this.getName() + "');")); //$NON-NLS-1$ //$NON-NLS-2$
217             if (showImage) {
218                 out.write("</td></tr></table>"); //$NON-NLS-1$
219             }
220             out.write("</div>\n"); //$NON-NLS-1$
221             out.write("<div style=\"position:absolute;top:-500px;left:-500px;visibility:hidden;\">\n<textarea id=\""); //$NON-NLS-1$
222             out.write(this.getName());
223             out.write("_contentEmpty\">");//$NON-NLS-1$
224             out.write(htmlContentEmpty);
225 
226             // @todo should be escaped, but we need to test it
227             // out.write(StringEscapeUtils.escapeXml(htmlContentEmpty));
228             out.write("</textarea>\n</div>\n"); //$NON-NLS-1$
229         }
230         control.setSaveInfo(true);
231         out.write(control.getHtmlSaveInfo());
232         control.setNodeDataTemplate(this.getConfigValue("nodeDataTemplate", null)); //$NON-NLS-1$
233         out.write(control.getHtmlNodeDataTemplate());
234         this.drawHtmlPost(out);
235     }
236 
237     protected String getLink(File control) {
238         String link = this.getRequest().getContextPath() + getFileURI(control);
239         if (!StringUtils.isEmpty(control.getExtension())) {
240             link += "." + control.getExtension();
241         }
242         return link;
243     }
244 
245     protected void writeInnerHtml(Writer out, final boolean showImage, File control, StringBuffer htmlControlFileName, String link) throws IOException {
246         out.write(htmlControlFileName.toString());
247         if (!showImage) {
248             String iconPath = MIMEMapping.getMIMETypeIcon(control.getExtension());
249 
250             out.write(Spacer.getHtml(0, 0));
251 
252             out.write("<a href=");
253             out.write(link);
254             out.write(" target=\"_blank\">"); //$NON-NLS-1$ //$NON-NLS-2$
255 
256             out.write("<img src=\"" //$NON-NLS-1$
257                 + this.getRequest().getContextPath()
258                 + iconPath
259                 + "\" class=\"" //$NON-NLS-1$
260                 + CssConstants.CSSCLASS_FILEICON
261                 + "\" border=\"0\">"); //$NON-NLS-1$
262             out.write(control.getFileName() + "." + control.getExtension() + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
263         }
264     }
265 
266     protected StringBuffer getHtmlControlFileName(File control) {
267         StringBuffer htmlControlFileName = new StringBuffer();
268         htmlControlFileName.append("<span class=\"" //$NON-NLS-1$
269             + CssConstants.CSSCLASS_DESCRIPTION
270             + "\">" //$NON-NLS-1$
271             + getMessage("dialog.file.filename") //$NON-NLS-1$
272             + "</span>"); //$NON-NLS-1$
273         htmlControlFileName.append(Spacer.getHtml(1, 1));
274         htmlControlFileName.append(control.getHtmlFileName() + "<span id=\"" //$NON-NLS-1$
275             + this.getName()
276             + "_fileNameExtension\">." //$NON-NLS-1$
277             + control.getExtension()
278             + "</span>"); //$NON-NLS-1$
279         return htmlControlFileName;
280     }
281 
282     @Override
283     public boolean validate() {
284         if (isRequired()) {
285             // if we have a form, then this is going to the database
286             MultipartForm form = (MultipartForm) getRequest().getAttribute(MultipartForm.REQUEST_ATTRIBUTE_NAME);
287             if (form != null) {
288                 Document doc = form.getDocument(getName());
289                 if (doc != null) { // we're submitting a document for this required field
290                     return true;
291                 }
292                 // we're removing the document
293                 // for this required field but
294                 // not uploading one
295                 if (form.getParameter(getName() + "_" + File.REMOVE) != null) {
296                     setValidationMessage("dialogs.validation.required");
297                     return false;
298                 }
299             }
300             // we are not uploading or removing
301             // check if there is a binary stored
302             if(this.getStorageNode() == null || !getStorageNode().getNodeData(getName()).isExist()){
303                 setValidationMessage("dialogs.validation.required");
304                 return false;
305             }
306         }
307         return true;
308     }
309 
310     /**
311      * Get the uri of the file (used to show images)
312      * @param control
313      * @return
314      */
315     protected String getFileURI(File control) {
316         return control.getHandle();
317     }
318 
319     /**
320      * Configures the inner file upload control
321      */
322     protected File getFileControl() {
323         File control = new File(this.getName(), this.getStorageNode());
324         return control;
325     }
326 }