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

Last change on this file since 5630 was 5630, checked in by Nicklas Nordborg, 12 years ago

References #1597: Subtypes of items

Added Subtypable interface and ItemSubtype item (and corresponding data-layer classes). File, Protocol, Software and Hardware are implementing the new interface and the FileType, ProtocolType, SoftwareType and HardwareType + data-layer classes have been deleted.

The rest of the changes are dependencies that have been updated to use the new subtype functionality.

There is no updgrade script yet. This will need to move existing *Type items into ItemSubtype and update all links from the other items. Then it can remove the old columns and tables. We also need to fix context-related information, but I think we have most functionality for this.

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