source: trunk/www/common/annotations/list_annotations.jsp @ 7213

Last change on this file since 7213 was 7213, checked in by Nicklas Nordborg, 6 years ago

References #2034: New permission for annotating items

The "Edit annotation" icon in the "Annotations & parameters" tab should be enabled when the logged in user has RESTRICTED_WRITE permission.

The "Save" button in the "Edit annotations" dialog should be enabled if the logged in user has RESTRICTED_WRITE permission.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 18.7 KB
Line 
1<%-- $Id: list_annotations.jsp 7213 2016-10-19 12:18:53Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson
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  @version 2.0
24--%>
25<%@page import="java.util.Collections"%>
26<%@page import="net.sf.basedb.util.units.UnitConverter"%>
27<%@ page pageEncoding="UTF-8" session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.Permission"
32  import="net.sf.basedb.core.AnnotationType"
33  import="net.sf.basedb.core.Protocol"
34  import="net.sf.basedb.core.AnnotationSet"
35  import="net.sf.basedb.core.Annotation"
36  import="net.sf.basedb.core.Annotatable"
37  import="net.sf.basedb.core.AnnotatableProxy"
38  import="net.sf.basedb.core.Unit"
39  import="net.sf.basedb.core.Nameable"
40  import="net.sf.basedb.core.Subtypable"
41  import="net.sf.basedb.core.ItemSubtype"
42  import="net.sf.basedb.core.BioPlate"
43  import="net.sf.basedb.core.BioPlateType"
44  import="net.sf.basedb.core.ItemQuery"
45  import="net.sf.basedb.core.ItemResultList"
46  import="net.sf.basedb.core.Include"
47  import="net.sf.basedb.core.PermissionDeniedException"
48  import="net.sf.basedb.core.query.Orders"
49  import="net.sf.basedb.core.query.Hql"
50  import="net.sf.basedb.core.query.Restrictions"
51  import="net.sf.basedb.core.query.Expressions"
52  import="net.sf.basedb.core.snapshot.AnnotationSetSnapshot"
53  import="net.sf.basedb.core.snapshot.AnnotationSnapshot"
54  import="net.sf.basedb.core.snapshot.SnapshotManager"
55  import="net.sf.basedb.clients.web.Base"
56  import="net.sf.basedb.clients.web.util.HTML"
57  import="net.sf.basedb.util.NameableComparator"
58  import="net.sf.basedb.util.formatter.Formatter"
59  import="net.sf.basedb.util.formatter.PrefixSuffixFormatter"
60  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
61  import="net.sf.basedb.util.Values"
62  import="java.util.ArrayList"
63  import="java.util.List"
64  import="java.util.Set"
65  import="java.util.HashSet"
66  import="java.util.TreeSet"
67  import="java.util.Map"
68  import="java.util.HashMap"
69  import="java.util.Date"
70%>
71<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
72<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
73
74<%
75final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
76final String ID = sc.getId();
77final Item itemType = Item.valueOf(request.getParameter("item_type"));
78final int itemId = Values.getInt(request.getParameter("item_id"));
79final float scale = Base.getScale(sc);
80final DbControl dc = sc.newDbControl();
81
82Set<AnnotationType> annotationTypes = null;
83Set<AnnotationType> protocolParameters = null;
84Map<AnnotationType, AnnotationSnapshot> existing = null;
85
86try
87{
88  final Annotatable item = (Annotatable)itemType.getById(dc, itemId);
89  final boolean writePermission = item.hasPermission(Permission.RESTRICTED_WRITE);
90  final SnapshotManager manager = new SnapshotManager();
91 
92  ItemQuery<AnnotationType> annotationTypeQuery = null;
93  String message = null;
94  boolean isProxy = item instanceof AnnotatableProxy;
95
96  // Load all annotation types that are possible for this item type
97  if (isProxy)
98  {
99    AnnotatableProxy proxy = (AnnotatableProxy)item;
100    annotationTypeQuery = Base.getAnnotationTypesQuery(proxy);
101    message = proxy.getAnnotationMessage();
102  }
103  else
104  {
105    annotationTypeQuery = Base.getAnnotationTypesQuery(itemType, false);
106  }
107  annotationTypes = new TreeSet<AnnotationType>(new NameableComparator(false));
108  annotationTypes.addAll(annotationTypeQuery.list(dc));
109
110  final AnnotationSetSnapshot snapshot = item.isAnnotated() ? 
111      manager.getSnapshot(dc, item.getAnnotationSet().getId()) : null;
112  List<AnnotationSnapshot> inheritedAnnotations = null;
113  if (snapshot != null)
114  {
115    // Load the existing primary and inherited annotations
116    existing = new HashMap<AnnotationType, AnnotationSnapshot>();
117    inheritedAnnotations = new ArrayList<AnnotationSnapshot>();
118    for (AnnotationSnapshot a : manager.findAnnotations(dc, snapshot, null, true))
119    {
120      AnnotationType at = a.getAnnotationType(dc);
121      if (a.getSource() == Annotation.Source.PRIMARY)
122      {
123        existing.put(a.getAnnotationType(dc), a);
124      }
125      else
126      {
127        inheritedAnnotations.add(a);
128      }
129    }
130    Collections.sort(inheritedAnnotations, AnnotationSnapshot.sortByAnnotationType(dc));
131    annotationTypes.addAll(existing.keySet());
132  }
133 
134  // Load the possible protocol parameters
135  Protocol protocol = null;
136  boolean readProtocol = true;
137  try
138  {
139    protocol = item.getProtocol();
140  }
141  catch (PermissionDeniedException ex)
142  {
143    readProtocol = false;
144  }
145  ItemQuery<AnnotationType> parameterQuery = Base.getProtocolParametersQuery(protocol);
146  if (parameterQuery != null)
147  {
148    protocolParameters = new HashSet<AnnotationType>(parameterQuery.list(dc));
149    annotationTypes.removeAll(protocolParameters);
150  }
151  // Load the current subtype
152  // NOTE! User may have selected a different subtype in the form than what is
153  // currently saved so if a subtype_id is sent in the request we use that
154  String selectedCategoryName = null;
155  try
156  {
157    ItemSubtype subtype = null;
158    if (item instanceof Subtypable)
159    {
160      subtype = ((Subtypable)item).getItemSubtype();
161    }
162    else if (item instanceof BioPlate)
163    {
164      BioPlateType bpt = ((BioPlate)item).getBioPlateType();
165      subtype = bpt.getItemSubtype();
166      if (subtype == null) selectedCategoryName = bpt.getName();
167    }
168    if (subtype != null) selectedCategoryName = subtype.getName();
169  }
170  catch (PermissionDeniedException ex)
171  {}
172  Set<AnnotationType> annotationTypesInCategory = new HashSet<AnnotationType>();
173  if (selectedCategoryName != null)
174  {
175    ItemQuery<AnnotationType> query = AnnotationType.getQuery(item.getType());
176    query.setIncludes(Include.ALL);
177    query.join(Hql.innerJoin("categories", "ct"));
178    query.restrict(Restrictions.eq(Hql.property("ct", "name"), Expressions.string(selectedCategoryName)));
179    annotationTypesInCategory.addAll(query.list(dc));
180  }
181  Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
182  %>
183  <base:page type="iframe" id="list-annotations">
184  <base:head scripts="~list.js" styles="table.css">
185  <style>
186    #annotations-data.all
187    {}
188   
189    #annotations-data.values .novalues
190    {
191      display: none;
192    }
193   
194    #annotations-data.category .nocategory
195    {
196      display: none;
197    }
198   
199    .edit-annotation
200    {
201      float: right;
202    }
203  </style>
204  </base:head>
205  <base:body>
206    <%
207    if (message != null)
208    {
209      %>
210      <div class="messagecontainer note"><%=message%></div>
211      <%
212    }
213    %>
214    <base:section
215      id="primaryAnnotations"
216      title="<%="Primary annotations (" + annotationTypes.size() + ")"%>"
217      >
218      <%
219      int allWithValues = 0;
220      int allOfCategory = 0;
221      if (annotationTypes.size() == 0)
222      {
223        %>
224        <div class="messagecontainer note">
225        No annotation types has been defined for this type of item
226        (or you don't have permission to view them).
227        </div>
228        <%
229      }
230      else
231      {
232        %>
233        <tbl:table
234          id="annotations"
235          columns="all"
236          >
237          <tbl:columndef 
238            id="annotation"
239            title="Annotation"
240          />
241          <tbl:columndef 
242            id="values"
243            title="Values"
244          />
245          <tbl:columndef
246            id="lastModified"
247            title="Last modified"
248            formatter="<%=dateTimeFormatter%>"
249          />
250          <tbl:columndef 
251            id="description"
252            title="Description"
253          />
254          <div class="panelgroup topborder leftborder rightborder bg-filled-100">
255            <tbl:panel style="height: auto; padding: 2px;">
256              <b>View:</b> 
257              <%
258              if (selectedCategoryName != null)
259              {
260                %>
261                <label><input type="radio" name="view" id="view_category" value="category" checked>All of <i><%=HTML.encodeTags(selectedCategoryName)%></i> category</label> (<span id="allOfCategory">?</span>)
262                <%
263              }
264              %>
265              <label><input type="radio" name="view" id="view_values" value="values" <%=selectedCategoryName == null ? "checked" : ""%>>All with values</label> (<span id="allWithValues">?</span>)
266              <label><input type="radio" name="view" id="view_all" value="all">All annotations</label> (<%=annotationTypes.size()%>)
267            </tbl:panel>
268          </div>
269          <tbl:data id="annotations-data">
270            <tbl:headers>
271              <tbl:headerrow>
272                <tbl:columnheaders />
273              </tbl:headerrow>
274            </tbl:headers>
275            <tbl:rows>
276            <%
277            for (AnnotationType at : annotationTypes)
278            {
279              // Permission for creating a new annotation
280              boolean annotatePermission = writePermission & at.hasPermission(Permission.USE);
281              AnnotationSnapshot a = existing != null ? existing.get(at) : null;
282              List<?> values = null;
283              Formatter formatter = null;
284              if (a != null)
285              {
286                Annotation ann = a.getThisAnnotation(dc);
287                // Permission on this annotation
288                annotatePermission = ann.hasPermission(Permission.WRITE);
289                values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
290                formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
291              }
292              if (values != null || !at.isRemoved())
293              {
294                String rowClass = "";
295                if (values == null || values.size() == 0) 
296                {
297                  rowClass += " novalues";
298                }
299                else
300                {
301                  allWithValues++;
302                }
303                if (!annotationTypesInCategory.contains(at)) 
304                {
305                  rowClass += " nocategory";
306                }
307                else
308                {
309                  allOfCategory++;
310                }
311                %>
312                <tbl:row subclass="<%=rowClass%>">
313                  <tbl:cell column="annotation"><base:icon 
314                    image="deleted.png" 
315                    tooltip="This item has been scheduled for deletion" 
316                    visible="<%=at.isRemoved()%>"
317                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
318                  <tbl:cell column="values">
319                    <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
320                    <base:icon image="edit.png" subclass="edit-annotation auto-init link" 
321                      data-auto-init="edit-annotation" 
322                      data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
323                      data-annotation-type="<%=at.getId()%>"
324                      data-item-type="<%=itemType.name()%>" 
325                      data-item-id="<%=itemId %>"
326                      tooltip="Modify the values of this annotation"
327                      visible="<%=annotatePermission %>"
328                    />
329                  </tbl:cell>
330                  <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
331                  <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
332                </tbl:row>
333                <%
334              }
335            }
336            %>
337            </tbl:rows>
338          </tbl:data>
339        </tbl:table>
340        <%
341      }
342      %>
343      <div id="annotations-stat" class="datacontainer"
344        data-all-with-values="<%=allWithValues %>"
345        data-all-of-category="<%=allOfCategory%>"
346      ></div>
347    </base:section>
348
349    <%
350    if (protocolParameters != null)
351    {
352      %>
353      <base:section 
354        id="parameterSection" 
355        title="<%="Protocol parameters for " + HTML.encodeTags(protocol.getName()) + 
356          " (" + protocolParameters.size() + ")"%>"
357        >
358        <%
359        if (protocolParameters.size() == 0)
360        {
361          %>
362          <div class="messagecontainer note">
363          No protocol parameters has been defined for the protocol
364          <%=Base.getLinkedName(ID, protocol, !readProtocol, true)%> 
365          (or you don't have permission to view them).
366          </div>
367          <%
368        }
369        else
370        {
371          %>
372          <tbl:table
373            id="parameters"
374            columns="all"
375            >
376            <tbl:columndef 
377              id="parameter"
378              title="Parameter"
379            />
380            <tbl:columndef 
381              id="values"
382              title="Values"
383            />
384            <tbl:columndef
385              id="lastModified"
386              title="Last modified"
387              formatter="<%=dateTimeFormatter%>"
388            />
389            <tbl:columndef 
390              id="description"
391              title="Description"
392            />
393            <tbl:data>
394              <tbl:headers>
395                <tbl:headerrow>
396                  <tbl:columnheaders />
397                </tbl:headerrow>
398              </tbl:headers>
399              <tbl:rows>
400              <%
401              for (AnnotationType at : protocolParameters)
402              {
403                // Permission for creating a new annotation
404                boolean annotatePermission = writePermission & at.hasPermission(Permission.USE);
405                AnnotationSnapshot a = existing != null ? existing.get(at) : null;
406                Formatter formatter = null;
407                List<?> values = null;
408                if (a != null)
409                {
410                  Annotation ann = a.getThisAnnotation(dc);
411                  // Permission on this annotation
412                  annotatePermission = ann.hasPermission(Permission.WRITE);
413                  values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
414                  formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
415                }
416                if (values != null || !at.isRemoved())
417                {
418                  %>
419                  <tbl:row>
420                    <tbl:cell column="parameter"><base:icon 
421                      image="deleted.png" 
422                      tooltip="This item has been scheduled for deletion" 
423                      visible="<%=at.isRemoved()%>"
424                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
425                    <tbl:cell column="values">
426                      <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
427                      <base:icon image="edit.png" subclass="edit-annotation auto-init link" 
428                        data-auto-init="edit-annotation" 
429                        data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
430                        data-annotation-type="<%=at.getId()%>"
431                        data-item-type="<%=itemType.name()%>" 
432                        data-item-id="<%=itemId %>"
433                        tooltip="Modify the values of this protocol parameter" 
434                        visible="<%=annotatePermission %>"
435                      />
436                    </tbl:cell>
437                    <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
438                    <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
439                  </tbl:row>
440                  <%
441                }
442              }
443              %>
444              </tbl:rows>
445            </tbl:data>
446          </tbl:table>
447          <%
448        }
449        %>
450      </base:section>
451      <%
452    }
453    if (!isProxy)
454    {
455      int numInherited = inheritedAnnotations == null ? 0 : inheritedAnnotations.size();
456      %>
457      <base:section 
458        id="inherited"
459        title="<%="Inherited annotations (" + numInherited + ")"%>"         
460        >
461        <%
462        if (numInherited == 0)
463        {
464          %>
465          <div class="messagecontainer note">
466          No annotations are inherited by this item.
467          (or you don't have permission to view them).
468          </div>
469          <%
470        }
471        else
472        {
473        %>
474        <tbl:table
475          id="inheritedAnnotations"
476          columns="all"
477          >
478          <tbl:columndef 
479            id="annotation"
480            title="Annotation"
481          />
482          <tbl:columndef 
483            id="values"
484            title="Values"
485          />
486          <tbl:columndef 
487            id="item"
488            title="Parent item"
489          />
490          <tbl:columndef 
491            id="note"
492            title="Note"
493          />
494          <tbl:columndef
495            id="lastModified"
496            title="Last modified"
497            formatter="<%=dateTimeFormatter %>"
498          />
499          <tbl:columndef 
500            id="description"
501            title="Description"
502          />
503          <tbl:data>
504            <tbl:headers>
505              <tbl:headerrow>
506                <tbl:columnheaders />
507              </tbl:headerrow>
508            </tbl:headers>
509            <tbl:rows>
510            <%
511            for (AnnotationSnapshot a : inheritedAnnotations)
512            {
513              boolean annotatePermission = a.hasPermission(dc, Permission.WRITE);
514              AnnotationType at = a.getAnnotationType(dc);
515              AnnotationSnapshot from = a.getInheritedFrom();
516             
517              // About this annotation
518              String name = HTML.encodeTags(at.getName());
519              String description = HTML.encodeTags(at.getDescription());
520              Date lastModified = a.getThisLastUpdate();
521              boolean isUpToDate = a.isUpToDate();
522             
523              // Which item are we inheriting from?
524              Nameable fromItem = null;
525              String fromType = null;
526              boolean writeInherited = false;
527              if (from != null)
528              {
529                fromType = from.getThisItemType().toString();
530                if (lastModified == null)
531                {
532                  lastModified = from.getThisLastUpdate();
533                }
534                try
535                {
536                  fromItem = (Nameable)from.getThisItem(dc);
537                  writeInherited = fromItem.hasPermission(Permission.WRITE);
538                  if (fromItem instanceof Subtypable)
539                  {
540                    ItemSubtype subtype = ((Subtypable)fromItem).getItemSubtype();
541                    if (subtype != null) fromType = subtype.getName();
542                  }
543                }
544                catch (PermissionDeniedException ex)
545                {}
546              }
547             
548              // Values, units, etc.
549              Formatter formatter = FormatterFactory.getTypeFormatter(sc, at.getValueType());
550              Unit unit = a.getActualUnit(dc);
551              UnitConverter converter = null;
552              if (unit != null)
553              {
554                converter = unit.getUnitConverter(at.getDefaultUnit());
555                formatter = unit.getFormatter(formatter);
556              }
557              List<?> values = a.getActualValues(converter, at.getValueType());
558              %>
559              <tbl:row>
560                <tbl:cell column="annotation"><%=Base.getLinkedName(ID, at, at == null, true)%></tbl:cell>
561                <tbl:cell column="values">
562                  <%=values == null || values.size() == 0 ? 
563                    "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
564                  <base:icon image="<%=isUpToDate ? "edit.png" : "edit-outofsync.png"%>" 
565                    subclass="edit-annotation auto-init link" 
566                    data-auto-init="edit-annotation" 
567                    data-annotation="<%= a.getThisAnnotationId()%>"
568                    data-annotation-type="<%=at.getId()%>"
569                    data-item-type="<%=itemType.name()%>" 
570                    data-item-id="<%=itemId %>"
571                    tooltip="Modify the values of this annotation"
572                    visible="<%=annotatePermission %>"
573                  />
574                </tbl:cell>
575                <tbl:cell column="item"><%=from == null ? "<i>- missing -</i>" : Base.getLinkedName(ID, fromItem, fromItem == null, true)%><%=fromItem != null ? " <span class=\"itemsubtype\">("+fromType+")</span>" : ""%></tbl:cell>
576                <tbl:cell column="note"><%=a.getSource() == Annotation.Source.CLONED ? "Cloned" + (isUpToDate ? "; up-to-date" : "; modified") : "" %></tbl:cell>
577                <tbl:cell column="lastModified" value="<%=lastModified %>"></tbl:cell>
578                <tbl:cell column="description"><%=description%></tbl:cell>
579              </tbl:row>
580              <%
581            }
582            %>
583            </tbl:rows>
584          </tbl:data>
585        </tbl:table>
586        <%
587      }
588      %>
589      </base:section>
590     
591      <%
592    }
593    %>
594  </base:body>
595  </base:page>
596  <%
597}
598finally
599{
600  if (dc != null) dc.close();
601}
602
603%>
Note: See TracBrowser for help on using the repository browser.