source: trunk/www/filemanager/upload/select.jsp @ 3507

Last change on this file since 3507 was 3507, checked in by Nicklas Nordborg, 16 years ago

References #470. Upload form can now handle file names with double extensions, for example .tar.gz

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.4 KB
Line 
1<%-- $Id: select.jsp 3507 2007-06-18 11:51:34Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) Authors contributing to this file.
4
5  This file is part of BASE - BioArray Software Environment.
6  Available at http://base.thep.lu.se/
7
8  BASE is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License
10  as published by the Free Software Foundation; either version 2
11  of the License, or (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330,
21  Boston, MA  02111-1307, USA.
22  ------------------------------------------------------------------
23
24
25  @author Nicklas
26  @version 2.0
27--%>
28<%@ page session="false"
29  import="net.sf.basedb.core.SessionControl"
30  import="net.sf.basedb.core.DbControl"
31  import="net.sf.basedb.core.Item"
32  import="net.sf.basedb.core.SystemItems"
33  import="net.sf.basedb.core.ItemContext"
34  import="net.sf.basedb.core.Permission"
35  import="net.sf.basedb.core.Directory"
36  import="net.sf.basedb.core.File"
37  import="net.sf.basedb.core.FileType"
38  import="net.sf.basedb.core.User"
39  import="net.sf.basedb.core.Group"
40  import="net.sf.basedb.core.Quota"
41  import="net.sf.basedb.core.QuotaType"
42  import="net.sf.basedb.core.Location"
43  import="net.sf.basedb.core.PluginDefinition"
44  import="net.sf.basedb.core.Include"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.ItemResultList"
47  import="net.sf.basedb.core.PermissionDeniedException"
48  import="net.sf.basedb.core.BaseException"
49  import="net.sf.basedb.core.query.Orders"
50  import="net.sf.basedb.core.query.Hql"
51  import="net.sf.basedb.util.zip.FileUnpacker"
52  import="net.sf.basedb.clients.web.Base"
53  import="net.sf.basedb.clients.web.util.HTML"
54  import="net.sf.basedb.util.Values"
55  import="java.util.List"
56  import="java.util.Set"
57  import="java.util.HashSet"
58%>
59<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
60<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
61<%
62final Item itemType = Item.FILE;
63final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
64final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
65final int itemId = cc.getId();
66final String ID = sc.getId();
67final float scale = Base.getScale(sc);
68final DbControl dc = sc.newDbControl();
69try
70{
71  String title = null;
72  File file = null;
73  Directory directory = null;
74  boolean readCurrentFileType = true;
75  int currentFileTypeId = 0;
76
77  if (itemId == 0)
78  {
79    title = "Upload new file";
80    currentFileTypeId = Values.getInt(cc.getPropertyValue("fileType"), 0);
81    if (currentFileTypeId == 0)
82    {
83      currentFileTypeId = Values.getInt(cc.getRecent(Item.FILETYPE.name(), 0), 0);
84    }
85    directory = Directory.getById(dc, Values.getInt(request.getParameter("directory_id"), SystemItems.getId(Directory.ROOT)));
86    cc.removeObject("item");
87  }
88  else
89  {
90    file = File.getById(dc, itemId);
91    directory = file.getDirectory();
92    cc.setObject("item", file);
93    title = "Upload again -- " + HTML.encodeTags(file.getName());
94    try
95    {
96      FileType ft = file.getFileType();
97      if (ft != null) currentFileTypeId = ft.getId();
98    }
99    catch (PermissionDeniedException ex)
100    {
101      readCurrentFileType = false;
102    }
103  }
104  if (file != null && !file.hasPermission(Permission.WRITE))
105  {
106    throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
107  }
108 
109  if (file == null || file.getLocation() != Location.PRIMARY)
110  {
111    // Check quota
112    User user = User.getById(dc, sc.getLoggedInUserId());
113    QuotaType totalQuotaType = QuotaType.getById(dc, SystemItems.getId(QuotaType.TOTAL));
114    QuotaType fileQuotaType = QuotaType.getById(dc, SystemItems.getId(QuotaType.FILE));
115   
116    if (user.hasExceededQuota(totalQuotaType, Location.PRIMARY) 
117      || user.hasExceededQuota(fileQuotaType, Location.PRIMARY))
118    {
119      throw new PermissionDeniedException("Quota has been exceeded");
120    }
121  }
122 
123 
124  // Query to retrieve file types
125  final ItemQuery<FileType> fileTypeQuery = FileType.getQuery();
126  fileTypeQuery.order(Orders.asc(Hql.property("name")));
127  fileTypeQuery.setCacheResult(true);
128 
129  // Query to retreive FileUnpacker plugins
130  final ItemQuery<PluginDefinition> pluginQuery = PluginDefinition.getQuery(null, "net.sf.basedb.util.zip.FileUnpacker");
131  pluginQuery.order(Orders.asc(Hql.property("name")));
132  pluginQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
133  List<PluginDefinition> plugins = pluginQuery.list(dc);
134
135  final String clazz = "class=\"text\"";
136  final String requiredClazz = "class=\"text required\"";
137  %>
138  <base:page type="popup" title="<%=title%>">
139  <base:head scripts="tabcontrol.js,ajax.js" styles="tabcontrol.css,progressbar.css">
140    <script language="JavaScript">
141    // Validate the "File" tab
142    function validateFile()
143    {
144      var frm = document.forms['file'];
145      if (Main.trimString(frm.the_file.value) == '')
146      {
147        alert("You must select a file to upload");
148        frm.the_file.focus();
149        return false;
150      }
151      return true;
152    }
153
154    // Submit the form
155    function doUpload()
156    {
157      var frm = document.forms['file'];
158      if (TabControl.validateActiveTab('settings'))
159      {
160        // Copy form values so they are sent BEFORE the file
161        frm.check_md5.value = frm.temp_check_md5 && frm.temp_check_md5.checked ? "1" : "0";
162        frm.write_protected.value = frm.temp_write_protected.checked ? "1" : "0";
163        if (frm.temp_zip_format)
164        {
165          frm.zip_format.value = frm.temp_zip_format[frm.temp_zip_format.selectedIndex].value;
166          frm.zip_unpack.value = frm.temp_zip_unpack.checked ? "1" : "0";
167          frm.zip_overwrite.value = frm.temp_zip_overwrite.checked ? "1" : "0";
168          frm.zip_keep.value = frm.temp_zip_keep.checked ? "1" : "0";
169        }
170        frm.filetype_id.value = frm.temp_filetype_id[frm.temp_filetype_id.selectedIndex].value;
171        frm.description.value = frm.temp_description.value;
172        frm.submit();
173        Main.hide('selectForm');
174        Main.show('progressForm');
175        if (!sendProgressUpdateWithAjax())
176        {
177          window.top.frames['progress'].location.href = 'progress.jsp?ID=<%=ID%>';
178        }
179      }
180    }
181   
182    function sendProgressUpdateWithAjax()
183    {
184      var request = Ajax.getXmlHttpRequest();
185      if (request != null)
186      {
187        var url = 'progress.jsp?ID=<%=ID%>&ajax=1&'+Math.random();
188        request.open("GET", url, true);
189        Ajax.setReadyStateHandler(request, updateProgressWithAjax);
190        request.send(null);
191      }
192      return request != null;
193    }
194   
195    function updateProgressWithAjax(request)
196    {
197      var response = request.responseText.split(':');
198      //alert(response[0]+':'+response[1]+':'+response[2]+':'+response[3]+':'+response[4]+':'+response[5]);
199      displayProgress(response[0],response[1],response[2],response[3],response[4],response.slice(5).join(':'));
200      setTimeout('sendProgressUpdateWithAjax()', 1500);
201    }
202   
203    function abortUpload()
204    {
205      if (confirm('Are you sure you want to abort the upload? It cannot be resumed.'))
206      {
207        window.top.frames['progress'].location.href = 'progress.jsp?ID=<%=ID%>&abort=1';
208      }
209    }
210   
211    function fileOnChange()
212    {
213      var frm = document.forms['file'];
214      var filename = frm.the_file.value;
215      var isZip = false;
216      var zipIndex = 0;
217     
218      for (var i = 0; i < allZipFormats.length; i++)
219      {
220        var zf = allZipFormats[i];
221        if (zf.matchesExtension(filename))
222        {
223          isZip = true;
224          zipIndex = zf.index;
225          i = allZipFormats.length;
226        }
227      }
228     
229      if (frm.temp_zip_format)
230      {
231        frm['temp_zip_format'].disabled = !isZip;
232        frm['temp_zip_format'].selectedIndex = zipIndex;
233        frm['temp_zip_unpack'].disabled = !isZip;
234        frm['temp_zip_overwrite'].disabled = !isZip || !frm['temp_zip_unpack'].checked;
235        frm['temp_zip_keep'].disabled = !isZip || !frm['temp_zip_unpack'].checked;
236      }
237    }
238    function unpackZipOnClick()
239    {
240      var frm = document.forms['file'];
241      var checked = frm['temp_zip_unpack'].checked;
242      if (!checked) frm['temp_zip_keep'].checked = true;
243      frm['temp_zip_overwrite'].disabled = !checked;
244      frm['temp_zip_keep'].disabled = !checked;
245    }
246   
247    function initZipFormats()
248    {
249      var frm = document.forms['file'];
250      var zipFormat = frm.temp_zip_format;
251      if (zipFormat)
252      {
253      <%
254      for (PluginDefinition plugin : plugins)
255      {
256        FileUnpacker unpacker = plugin.newInstance(FileUnpacker.class, null, sc, null, null);
257        %>
258          var extensions = [ '<%=Values.getString(unpacker.getExtensions(), "','", true)%>' ];
259          var zf = new ZipFormat(zipFormat.length, <%=plugin.getId()%>, '<%=HTML.javaScriptEncode(unpacker.getFormatName())%>', extensions);
260          zipFormat[zipFormat.length] = new Option(zf.toString(), zf.id);
261        <%
262      }
263      %>
264      }
265    }
266   
267    function displayProgress(fileName, transferredBytes, totalBytes, transferTime, remainTime, unpackMessage)
268    {
269      // File name
270      document.getElementById('fileName').innerHTML = 'Uploading ' + fileName + '...';
271       
272      // Percent done
273      var percentDone = totalBytes == 0 ? 0 : Math.round(100 * transferredBytes / totalBytes);
274      document.getElementById('percent').innerHTML = '&nbsp;' + percentDone+'%';
275      var doneElement = document.getElementById('percentDone');
276      doneElement.style.width = percentDone+'%';
277      var remainElement = document.getElementById('percentRemain');
278      remainElement.style.width = (100-percentDone)+'%';
279      if (percentDone == 100) Main.hide('percentRemain');
280     
281      // Bytes
282      document.getElementById('transferredBytes').innerHTML = Numbers.formatBytes(transferredBytes);
283      document.getElementById('totalBytes').innerHTML = Numbers.formatBytes(totalBytes);
284
285      // Times and rate
286      var transferRate = transferTime == 0 ? 0 : transferredBytes / transferTime;
287      document.getElementById('transferTime').innerHTML = Numbers.formatSeconds(transferTime);
288      document.getElementById('transferRate').innerHTML = '(' + Numbers.formatBytes(transferRate) + '/s)';
289      document.getElementById('remainTime').innerHTML = Numbers.formatSeconds(remainTime) + ' (estimated)';
290     
291      // Message
292      if (unpackMessage)
293      {
294        document.getElementById('unpackMessage').innerHTML = unpackMessage.replace(/(.*):(.*)/, '<b>$1:</b> $2');
295      }
296    }
297   
298    var allZipFormats = new Array();
299    function ZipFormat(index, id, name, extensions)
300    {
301      this.index = index;
302      this.id = id;
303      this.name = name;
304      this.extensions = extensions;
305     
306      allZipFormats[allZipFormats.length] = this;
307     
308      this.matchesExtension = function(filename)
309      {
310        for (var i = 0; i < this.extensions.length; i++)
311        {
312          var ext = '.' + this.extensions[i];
313          var index = filename.lastIndexOf(ext);
314          if (index > 0 && (index + ext.length == filename.length))
315          {
316            return true;
317          }
318        }
319        return false;
320      }
321     
322      this.toString = function()
323      {
324        var s = this.name + " [";
325        for (var i = 0; i < this.extensions.length; i++)
326        {
327          if (i > 0) s += ', ';
328          s += '*.' + this.extensions[i];
329        }
330        s += ']';
331        return s;
332      }
333    }
334   
335    </script>
336  </base:head>
337  <base:body onload="initZipFormats()">
338  <p>
339  <div id="selectForm">
340    <form action="upload.jsp?ID=<%=ID%>&directory_id=<%=directory.getId()%>" 
341      method="post" name="file" enctype="multipart/form-data" onsubmit="return false;" target="upload">
342
343    <input type="hidden" name="check_md5" value="0">
344    <input type="hidden" name="write_protected" value="0">
345    <input type="hidden" name="zip_format" value="">
346    <input type="hidden" name="zip_unpack" value="0">
347    <input type="hidden" name="zip_overwrite" value="0">
348    <input type="hidden" name="zip_keep" value="1">
349    <input type="hidden" name="filetype_id" value="">
350    <input type="hidden" name="description" value="">
351
352    <h3 class="docked"><%=title%> <base:help tabcontrol="settings" /></h3>
353    <t:tabcontrol id="settings" contentstyle="<%="height: "+(int)(scale*340)+"px;"%>" 
354      position="bottom" remember="false">
355    <t:tab id="info" title="File" validate="validateFile()" helpid="file.upload">
356      <table class="form" cellspacing=0>
357      <tr>
358        <td class="prompt">Directory</td>
359        <td><%=HTML.encodeTags(directory.getPath().toString())%></td>
360      </tr>
361      <tr>
362        <td class="prompt">File</td>
363        <td>
364          <input <%=requiredClazz%> type="file" name="the_file" size="50"
365            onchange="fileOnChange()">
366        </td>
367      </tr>
368      <tr>
369        <td class="prompt">Write protected</td>
370        <td>
371          <input type="checkbox" name="temp_write_protected" value="1" 
372          <%=(file != null && file.isWriteProtected()) || 
373            (file == null && Values.getBoolean(cc.getPropertyValue("writeProtected"))) ? "checked" : ""%>>
374        </td>
375      </tr>
376      <%
377      if (file != null)
378      {
379        %>
380        <tr>
381          <td class="prompt">Validate MD5</td>
382          <td><input type="checkbox" name="temp_check_md5"></td>
383        </tr>
384        <%
385      }
386      %>
387      <tr valign="top">
388        <td class="prompt">Type</td>
389        <td colspan="2">
390          <select name="temp_filetype_id" <%=!readCurrentFileType ? "disabled readonly class=\"disabled\"" : ""%>>
391          <%
392          if (!readCurrentFileType)
393          {
394            %>
395            <option value="-1">- denied -
396            <%
397          }
398          else
399          {
400            %>
401            <option value="0">- none -
402            <%
403            ItemResultList<FileType> fileTypes = fileTypeQuery.list(dc);
404            for (FileType fileType : fileTypes)
405            {
406              int id = fileType.getId();
407              boolean current = id == currentFileTypeId;
408              %>
409              <option 
410                value="<%=current && file != null ? -id : id%>" 
411                <%=current ? "selected" : ""%>
412                ><%=HTML.encodeTags(fileType.getName())%>
413              <%
414            }
415          }
416          %>
417          </select>
418        </td>
419      </tr>
420
421      <tr valign=top>
422        <td class="prompt">Description</td>
423        <td nowrap>
424          <textarea <%=clazz%> rows="4" cols="50" name="temp_description" wrap="virtual"
425            ><%=HTML.encodeTags(file == null ? cc.getPropertyValue("description") : file.getDescription())%></textarea>
426          <a href="javascript:Main.zoom('Description', 'file', 'temp_description')"
427            title="Edit in larger window"><base:icon image="zoom.gif" /></a>
428        </td>
429      </tr>
430     
431      <tr valign=top>
432        <td class="prompt">Max trans-<br>fer rate</td>
433        <td nowrap>
434          <%
435          long maxTransferRate = Values.getInt(sc.getClientDefaultSetting("server.transferRate"), 0);
436          %>
437          <%=maxTransferRate == 0 ? "unlimited" : Values.formatBytes(maxTransferRate)+"/s (approx.)"%>
438        </td>
439      </tr>
440     
441      <%
442      if (file == null)
443      {
444        %>
445        <tr valign=top>
446          <td class="prompt">Compressed file</td>
447          <td>
448            <select name="temp_zip_format" disabled>
449              <option>
450            </select><br>
451         
452            <input type="checkbox" name="temp_zip_unpack" disabled
453              onclick="unpackZipOnClick()"><a 
454              href="javascript:document.forms['file'].temp_zip_unpack.click()">Unpack file</a><br>
455            <input type="checkbox" name="temp_zip_overwrite" disabled
456              ><a 
457              href="javascript:document.forms['file'].temp_zip_overwrite.click()">Overwrite existing files</a><br>
458            <input type="checkbox" name="temp_zip_keep" disabled checked
459              ><a 
460              href="javascript:document.forms['file'].temp_zip_keep.click()">Keep the compressed file</a><br>
461          </td>
462        </tr>
463        <%
464      }
465      %>
466     
467      </table>
468      <div align=right>&nbsp;<i><base:icon image="required.gif" /> = required information</i></div>
469    </t:tab>
470
471    </t:tabcontrol>
472
473    <table align="center">
474    <tr>
475      <td width="50%"><base:button image="upload.gif" onclick="doUpload()" title="Upload" /></td>
476      <td width="50%"><base:button onclick="top.window.close()" title="Cancel" /></td>
477    </tr>
478    </table>
479    </form>
480  </div>
481 
482  <div id="progressForm" style="display:none;">
483    <h3 class="docked" id="fileName">Preparing file upload...</h3>
484    <div class="boxed" style="background: #E0E0E0">
485      <br>
486      <table width="90%" border=0 cellspacing=0 cellpadding=0 align="center">
487      <tr>
488      <td width="90%" >
489        <table width="100%" class="progressbar" border=0 cellspacing=0 cellpadding=0>
490        <tr>
491          <td width="0%" class="done" id="percentDone">&nbsp;</td>
492          <td width="100%" class="remain" id="percentRemain">&nbsp;</td>
493        </tr>
494        </table>
495      </td>
496        <td width="10%" id="percent">&nbsp;0%</td>
497      </tr>
498      <tr>
499        <td colspan="2">
500          <b>Transferred:</b> <span id="transferredBytes">0 bytes</span> of <span id="totalBytes">unknown</span><br>
501          <b>Time:</b> <span id="transferTime">0s</span> <span id="transferRate"></span><br>
502          <b>Remain:</b> <span id="remainTime">unknown</span><br>
503          <span id="unpackMessage"></span>
504        </td>
505      </tr>
506      </table>
507      <br>
508    </div>
509    <br>
510    <table align="center">
511    <tr>
512      <td><base:button image="cancel.gif" onclick="abortUpload()" title="Abort..." /></td>
513    </tr>
514    </table>
515 
516  </div>
517  </base:body>
518  </base:page>
519  <%
520}
521finally
522{
523  if (dc != null) dc.close();
524}
525%>
Note: See TracBrowser for help on using the repository browser.