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

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

References #1597: Subtypes of items

Cleanup code and JSP pages. Added some utility functions to make it easier to load and use subtypes. Added subtype functionality to BioSource.

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