source: trunk/www/views/itemlists/index.jsp @ 6768

Last change on this file since 6768 was 6768, checked in by Nicklas Nordborg, 8 years ago

References #1325: Lists of items

Added functionality for storing the active filter used to create a list. The functionality for re-syncing the list with the filter at a later time is still rudimentary but will be improved...

File size: 17.6 KB
Line 
1<%-- $Id$
2  ------------------------------------------------------------------
3  Copyright (C) 2015 Nicklas Nordborg
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 3
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 BASE. If not, see <http://www.gnu.org/licenses/>.
20  ------------------------------------------------------------------
21
22  @author Nicklas
23--%>
24<%@ page pageEncoding="UTF-8" session="false"
25  import="net.sf.basedb.core.SessionControl"
26  import="net.sf.basedb.core.DbControl"
27  import="net.sf.basedb.core.Item"
28  import="net.sf.basedb.core.Type"
29  import="net.sf.basedb.core.Include"
30  import="net.sf.basedb.core.ItemList"
31  import="net.sf.basedb.core.RawDataTypes"
32  import="net.sf.basedb.core.ItemSubtype"
33  import="net.sf.basedb.core.ItemQuery"
34  import="net.sf.basedb.core.Permission"
35  import="net.sf.basedb.core.ItemContext"
36  import="net.sf.basedb.core.ItemResultIterator"
37  import="net.sf.basedb.core.ItemQuery"
38  import="net.sf.basedb.core.MultiPermissions"
39  import="net.sf.basedb.core.OwnedItem"
40  import="net.sf.basedb.core.Listable"
41  import="net.sf.basedb.core.PermissionDeniedException"
42  import="net.sf.basedb.core.ItemAlreadyExistsException"
43  import="net.sf.basedb.core.query.Restrictions"
44  import="net.sf.basedb.core.query.Hql"
45  import="net.sf.basedb.core.query.Expressions"
46  import="net.sf.basedb.util.RemovableUtil"
47  import="net.sf.basedb.util.ShareableUtil"
48  import="net.sf.basedb.util.OwnableUtil"
49  import="net.sf.basedb.util.collections.CollectionTransformer"
50  import="net.sf.basedb.util.biomaterial.ListUtil"
51  import="net.sf.basedb.clients.web.Base"
52  import="net.sf.basedb.clients.web.WebException"
53  import="net.sf.basedb.util.Values"
54  import="net.sf.basedb.clients.web.util.HTML"
55  import="net.sf.basedb.core.plugin.GuiContext"
56  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
57  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
58  import="net.sf.basedb.clients.web.extensions.JspContext"
59  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
60  import="net.sf.basedb.clients.web.extensions.edit.OnSaveRenderer"
61  import="net.sf.basedb.clients.web.extensions.list.ListColumnExportRenderer"
62  import="net.sf.basedb.clients.web.extensions.list.ListColumnUtil"
63  import="java.util.Enumeration"
64  import="java.util.Set"
65  import="java.util.HashSet"
66  import="java.util.List"
67  import="java.util.ArrayList"
68  import="java.util.Collections"
69  import="java.util.Arrays"
70%>
71<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
72<%!
73  private static final ItemContext defaultContext = Base.createDefaultContext("name", "name,memberType,size,description");
74  private static final Item itemType = Item.ITEMLIST;
75%>
76<%
77final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
78final String ID = sc.getId();
79final String cmd = request.getParameter("cmd");
80final String root = request.getContextPath()+"/";
81final String mode = request.getParameter("mode");
82final String callback = request.getParameter("callback");
83final String itemId = request.getParameter("item_id");
84final String listPage = "list_lists.jsp?ID="+ID
85  +(mode == null ? "" : "&mode="+mode)
86  +(callback == null ? "" : "&callback="+callback)
87  +(itemId == null ? "" : "&item_id="+itemId);
88final String viewPage = "view_list.jsp?ID="+ID;
89final String editPage = "edit_list.jsp?ID="+ID;
90
91String forward = null;
92String redirect = null;
93String message = null;
94DbControl dc = null;
95
96try
97{
98  if (cmd == null || "List".equals(cmd))
99  {
100    // Display the list page without updatinging the current context
101    Base.getAndSetCurrentContext(sc, itemType, null, defaultContext, true);
102    redirect = listPage;
103  }
104  else if ("UpdateContext".equals(cmd))
105  {
106    // Display the list page after updating the current context from the request parameters
107    Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
108    redirect = listPage;
109  }
110  else if ("LoadContext".equals(cmd))
111  {
112    // Display the list page after loading a saved context
113    int contextId = Values.getInt(request.getParameter("context"));
114    Base.loadContext(sc, contextId, defaultContext);
115    redirect = listPage;
116  }
117
118  else if ("ViewItem".equals(cmd))
119  {
120    // Display the view page for a single item
121    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
122    forward = viewPage;
123  }
124  else if ("EditItem".equals(cmd))
125  {
126    // Display the edit page for a single item (should be opened in a popup)
127    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
128    redirect = editPage;
129  }
130  else if ("NewItem".equals(cmd))
131  {
132    // Display the edit page for a new item (should be opened in a popup)
133    if (!sc.hasPermission(Permission.CREATE, itemType))
134    {
135      throw new PermissionDeniedException(Permission.CREATE, itemType.toString());
136    }
137    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
138    cc.setId(0);
139    forward = editPage;
140  }
141  else if ("UpdateItem".equals(cmd))
142  {
143    // Update the properties on an item (will close the popup)
144    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, defaultContext);
145    dc = sc.newDbControl();
146    ItemList list = (ItemList)cc.getObject("item");
147    if (list == null)
148    {
149      Item memberType = Item.valueOf(request.getParameter("memberType"));
150      list = ItemList.getNew(dc, memberType);
151      dc.saveItem(list);
152      message = "List created";
153    }
154    else
155    {
156      dc.reattachItem(list, false);
157      message = "List updated";
158    }
159    JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(Item.ITEMLIST), list);
160    ExtensionsInvoker invoker = EditUtil.useOnSaveExtensions(jspContext);
161    try
162    {
163      list.setName(Values.getStringOrNull(request.getParameter("name")));
164      list.setExternalId(Values.getStringOrNull(request.getParameter("external_id")));
165      list.setDescription(Values.getStringOrNull(request.getParameter("description")));
166      if (list.getMemberType() == Item.RAWBIOASSAY)
167      {
168        list.setRawDataType(RawDataTypes.getRawDataType(request.getParameter("rawdatatype")));
169      }
170      else
171      {
172        int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1);
173        ItemSubtype subtype = null;
174        if (subtypeId >= 0) // < 0 = denied or unchanged
175        {
176          if (subtypeId > 0) subtype = ItemSubtype.getById(dc, subtypeId);
177          list.setItemSubtype(subtype);
178        }
179      }
180
181      // Annotations tab
182      Base.updateAnnotations(dc, list, list, request);
183
184      if (!list.isInDatabase())
185      {
186        // Add individual items from selected from a list page
187        String source = request.getParameter("source");
188        if (source != null)
189        {
190          String subContext = Values.getString(request.getParameter("subContext"), "");
191          boolean useSyncFilter = false;
192          ItemContext filterContext = sc.getCurrentContext(list.getMemberType(), subContext);
193          ItemQuery<? extends Listable> query = (ItemQuery<? extends Listable>)filterContext.getQuery();
194          if ("all".equals(source))
195          {
196            useSyncFilter = Values.getBoolean(request.getParameter("syncFilter"));
197            query.setFirstResult(0);
198            query.setMaxResults(-1);
199          }
200          else if ("selected".equals(source))
201          {
202            query.setFirstResult(0);
203            query.setMaxResults(-1);
204            Integer[] itemIds = Values.getInt(request.getParameter("items").split(","));
205            query.restrict(
206              Restrictions.in(
207                Hql.property("id"),
208                Expressions.parameter("selectedItems")
209              )
210            );
211            query.setParameter("selectedItems", Arrays.asList(itemIds), Type.INT);     
212          }
213          // else -- no modifications to the query mean that we only get the current page
214         
215          int numAdded = useSyncFilter ? list.applySyncFilter(dc, filterContext, ItemList.SynchronizeOption.ADD_ONLY) : list.add(query.iterate(dc));
216        }
217       
218        message = "List created with " + list.getSize() + " item(s)";
219      }
220
221     
222      // OnSave extensions
223      invoker.render(OnSaveRenderer.ON_SAVE);
224      dc.commit();
225      invoker.render(OnSaveRenderer.ON_COMMIT);
226    }
227    catch (Exception ex)
228    {
229      invoker.render(OnSaveRenderer.onRollback(ex));
230      throw ex;
231    }
232    finally
233    {
234      cc.removeObject("item");
235    }
236  }
237  else if ("ReSyncFilter".equals(cmd))
238  {
239    dc = sc.newDbControl();
240    ItemList list = ItemList.getById(dc, Values.getInt(itemId));
241    list.resyncFilter(dc, ItemList.SynchronizeOption.FULL);
242    dc.commit();
243    forward = viewPage;
244  }
245  else if ("DeleteItem".equals(cmd))
246  {
247    // Delete a single item and then return to the view page
248    dc = sc.newDbControl();
249    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
250    RemovableUtil.setRemoved(dc, itemType, Collections.singleton(cc.getId()), true);
251    dc.commit();
252    redirect = viewPage;
253  }
254  else if ("DeleteItems".equals(cmd))
255  {
256    // Delete all selected items on the list page
257    dc = sc.newDbControl();
258    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
259    int numTotal = cc.getSelected().size();
260    int numRemoved = RemovableUtil.setRemoved(dc, itemType, cc.getSelected(), true);
261    dc.commit();
262    if (numTotal != numRemoved)
263    {
264      message = (numRemoved == 0 ? "No" : "Only "+numRemoved+" of "+numTotal) + " items could be deleted, because you have no DELETE permission";
265    }
266    redirect = listPage;
267  }
268  else if ("RestoreItem".equals(cmd))
269  {
270    // Restore a single item and then return to the view page
271    dc = sc.newDbControl();
272    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
273    RemovableUtil.setRemoved(dc, itemType, Collections.singleton(cc.getId()), false);
274    dc.commit();
275    redirect = viewPage;
276  }
277  else if ("RestoreItems".equals(cmd))
278  {
279    // Restore all selected items on the list page
280    dc = sc.newDbControl();
281    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
282    int numTotal = cc.getSelected().size();
283    int numRemoved = RemovableUtil.setRemoved(dc, itemType, cc.getSelected(), false);
284    dc.commit();
285    if (numTotal != numRemoved)
286    {
287      message = (numRemoved == 0 ? "No" : "Only "+numRemoved+" of "+numTotal) + " items could be restored, because you have no WRITE permission";
288    }
289    redirect = listPage;
290  }
291  else if ("ShareItem".equals(cmd))
292  {
293    // Display a popup window for sharing a single item
294    dc = sc.newDbControl();
295    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
296    MultiPermissions permissions = ShareableUtil.getMultiPermissions(dc, itemType, Collections.singleton(cc.getId()));
297    dc.close();
298    cc.setObject("MultiPermissions", permissions);
299    redirect = "../../common/share/share.jsp?ID="+ID+"&item_type="+itemType.name();
300  }
301  else if ("ShareItems".equals(cmd))
302  {
303    // Display a popup window for sharing all selected items on the list page
304    dc = sc.newDbControl();
305    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
306    MultiPermissions permissions = ShareableUtil.getMultiPermissions(dc, itemType, cc.getSelected());
307    dc.close();
308    cc.setObject("MultiPermissions", permissions);
309    redirect = "../../common/share/share.jsp?ID="+ID+"&item_type="+itemType.name();
310  }
311  else if ("SetOwnerOfItem".equals(cmd))
312  {
313    // Change owner of items selected on a list page
314    dc = sc.newDbControl();
315    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
316    OwnedItem item = (OwnedItem)itemType.getById(dc, cc.getId());
317    cc.setObject("OwnedItems", Collections.singleton(item));
318    redirect = "../../common/ownership/ownership.jsp?ID="+ID+"&item_type="+itemType.name();
319  }
320  else if ("SetOwnerOfItems".equals(cmd))
321  {
322    // Change owner of items selected on a list page
323    dc = sc.newDbControl();
324    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
325    Set<OwnedItem> items = new HashSet<OwnedItem>();
326    for (Integer id : cc.getSelected())
327    {
328      if (id != null) items.add((OwnedItem)itemType.getById(dc, id));
329    }
330    dc.close();
331    cc.setObject("OwnedItems", items);
332    redirect = "../../common/ownership/ownership.jsp?ID="+ID+"&item_type="+itemType.name();
333  }
334  else if ("ExportItems".equals(cmd))
335  {
336    // Run an export plugin in a list context
337    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
338    final ItemQuery<ItemList> query = ItemList.getQuery();
339    dc = sc.newDbControl();
340    cc.configureQuery(dc, query, true);
341    dc.close();
342    cc.setQuery(query);
343    redirect = "../../common/export/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=LIST&title=Export+item+lists";
344  }
345  else if ("ExportItem".equals(cmd))
346  {
347    // Run an export plugin in single-item context
348    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
349    redirect = "../../common/export/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&title=Export+item+list";
350  }
351  else if ("ImportItems".equals(cmd))
352  {
353    // Run an import plugin in a list context
354    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
355    final ItemQuery<ItemList> query = ItemList.getQuery();
356    dc = sc.newDbControl();
357    cc.configureQuery(dc, query, true);
358    cc.setQuery(query);
359    JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.list(itemType), null);
360    ExtensionsInvoker listInvoker = ListColumnUtil.useExtensions(jspContext);
361    listInvoker.render(new ListColumnExportRenderer(cc));
362    dc.close();
363    redirect = "../../common/import/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=LIST&title=Import+item+lists";
364  }
365  else if ("ImportItem".equals(cmd))
366  {
367    // Run an import plugin in single-item context
368    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
369    redirect = "../../common/import/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&title=Import+item+list";
370  }
371  else if ("RunListPlugin".equals(cmd))
372  {
373    // Run another plugin in a list context
374    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
375    final ItemQuery<ItemList> query = ItemList.getQuery();
376    dc = sc.newDbControl();
377    cc.configureQuery(dc, query, true);
378    dc.close();
379    cc.setQuery(query);
380    redirect = "../../common/plugin/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=LIST&main_type=OTHER&title=Run+plugin";
381  }
382  else if ("RunPlugin".equals(cmd))
383  {
384    // Run another plugin in single-item context
385    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
386    redirect = "../../common/plugin/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&main_type=OTHER&title=Run+plugin";
387  }
388  else if ("MergeItem".equals(cmd))
389  {
390    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, defaultContext);
391    dc = sc.newDbControl();
392    ItemList itemList = (ItemList)cc.getObject("item");
393    dc.reattachItem(itemList, false);
394   
395    String mergeType = request.getParameter("mergeType");
396    String sourceMerge = request.getParameter("sourceMerge");
397   
398    String[] sourceListIds = Values.getString(request.getParameter("+ITEMLIST")).split(",");
399    List<ItemList> sourceLists = new ArrayList<ItemList>(sourceListIds.length);
400    for (int i = 0; i < sourceListIds.length; ++i)
401    {
402      int listId = Values.getInt(sourceListIds[i], -1);
403      if (listId != -1) sourceLists.add(ItemList.getById(dc, listId));
404    }
405   
406    int numAdded = 0;
407    int numRemoved = 0;
408    if ("union".equals(mergeType))
409    {
410      if ("union".equals(sourceMerge))
411      {
412        numAdded = itemList.addUnion(sourceLists);
413      }
414      else if ("intersection".equals(sourceMerge))
415      {
416        numAdded = itemList.addIntersection(sourceLists);
417      }
418      message = numAdded + " items added to this list";
419    }
420    else if ("intersection".equals(mergeType))
421    {
422      if ("union".equals(sourceMerge))
423      {
424        numRemoved = itemList.retainUnion(sourceLists);
425      }
426      else if ("intersection".equals(sourceMerge))
427      {
428        numRemoved = itemList.retainIntersection(sourceLists);
429      }
430      message = numRemoved + " items removed from this list";
431    }
432    else if ("complement".equals(mergeType))
433    {
434      if ("union".equals(sourceMerge))
435      {
436        numRemoved = itemList.removeUnion(sourceLists);
437      }
438      else if ("intersection".equals(sourceMerge))
439      {
440        numRemoved = itemList.removeIntersection(sourceLists);
441      }
442      message = numRemoved + " items removed from this list";
443    }
444    dc.commit();
445  } 
446  else
447  {
448    throw new WebException("popup", "Invalid command", "The command {1} is not recognised as a valid command.", cmd);
449  }
450}
451finally
452{
453  if (dc != null) dc.close();
454}
455
456if (forward != null)
457{
458  sc.setSessionSetting("alert-message", message);
459  pageContext.forward(forward);
460}
461else if (redirect != null)
462{
463  sc.setSessionSetting("alert-message", message);
464  response.sendRedirect(redirect);
465}
466else if (message == null)
467{
468  response.sendRedirect(root + "common/close_popup.jsp?refresh_opener=1&wait=0");
469}
470else
471{
472  response.sendRedirect(root + "common/close_popup.jsp?refresh_opener=1&message="+HTML.urlEncode(message));
473}
474%>
475
Note: See TracBrowser for help on using the repository browser.