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

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

References #1941: Store experimental factor values as part experiments

Using a different "Edit" icon for cloned annotations that are out-of-sync.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 18.1 KB
Line 
1<%-- $Id: list_annotations.jsp 6962 2015-10-01 12:29:38Z 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.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              AnnotationSnapshot a = existing != null ? existing.get(at) : null;
280              List<?> values = null;
281              Formatter formatter = null;
282              if (a != null)
283              {
284                Annotation ann = a.getThisAnnotation(dc);
285                values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
286                formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
287              }
288              if (values != null || !at.isRemoved())
289              {
290                String rowClass = "";
291                if (values == null || values.size() == 0) 
292                {
293                  rowClass += " novalues";
294                }
295                else
296                {
297                  allWithValues++;
298                }
299                if (!annotationTypesInCategory.contains(at)) 
300                {
301                  rowClass += " nocategory";
302                }
303                else
304                {
305                  allOfCategory++;
306                }
307                %>
308                <tbl:row subclass="<%=rowClass%>">
309                  <tbl:cell column="annotation"><base:icon 
310                    image="deleted.png" 
311                    tooltip="This item has been scheduled for deletion" 
312                    visible="<%=at.isRemoved()%>"
313                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
314                  <tbl:cell column="values">
315                    <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
316                    <base:icon image="edit.png" subclass="edit-annotation auto-init link" 
317                      data-auto-init="edit-annotation" 
318                      data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
319                      data-annotation-type="<%=at.getId()%>"
320                      data-item-type="<%=itemType.name()%>" 
321                      data-item-id="<%=itemId %>"
322                      tooltip="Modify the values of this annotation"
323                      visible="<%=writePermission %>"
324                    />
325                  </tbl:cell>
326                  <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
327                  <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
328                </tbl:row>
329                <%
330              }
331            }
332            %>
333            </tbl:rows>
334          </tbl:data>
335        </tbl:table>
336        <%
337      }
338      %>
339      <div id="annotations-stat" class="datacontainer"
340        data-all-with-values="<%=allWithValues %>"
341        data-all-of-category="<%=allOfCategory%>"
342      ></div>
343    </base:section>
344
345    <%
346    if (protocolParameters != null)
347    {
348      %>
349      <base:section 
350        id="parameterSection" 
351        title="<%="Protocol parameters for " + HTML.encodeTags(protocol.getName()) + 
352          " (" + protocolParameters.size() + ")"%>"
353        >
354        <%
355        if (protocolParameters.size() == 0)
356        {
357          %>
358          <div class="messagecontainer note">
359          No protocol parameters has been defined for the protocol
360          <%=Base.getLinkedName(ID, protocol, !readProtocol, true)%> 
361          (or you don't have permission to view them).
362          </div>
363          <%
364        }
365        else
366        {
367          %>
368          <tbl:table
369            id="parameters"
370            columns="all"
371            >
372            <tbl:columndef 
373              id="parameter"
374              title="Parameter"
375            />
376            <tbl:columndef 
377              id="values"
378              title="Values"
379            />
380            <tbl:columndef
381              id="lastModified"
382              title="Last modified"
383              formatter="<%=dateTimeFormatter%>"
384            />
385            <tbl:columndef 
386              id="description"
387              title="Description"
388            />
389            <tbl:data>
390              <tbl:headers>
391                <tbl:headerrow>
392                  <tbl:columnheaders />
393                </tbl:headerrow>
394              </tbl:headers>
395              <tbl:rows>
396              <%
397              for (AnnotationType at : protocolParameters)
398              {
399                AnnotationSnapshot a = existing != null ? existing.get(at) : null;
400                Formatter formatter = null;
401                List<?> values = null;
402                if (a != null)
403                {
404                  Annotation ann = a.getThisAnnotation(dc);
405                  values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
406                  formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
407                }
408                if (values != null || !at.isRemoved())
409                {
410                  %>
411                  <tbl:row>
412                    <tbl:cell column="parameter"><base:icon 
413                      image="deleted.png" 
414                      tooltip="This item has been scheduled for deletion" 
415                      visible="<%=at.isRemoved()%>"
416                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
417                    <tbl:cell column="values">
418                      <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
419                      <base:icon image="edit.png" subclass="edit-annotation auto-init link" 
420                        data-auto-init="edit-annotation" 
421                          data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
422                          data-annotation-type="<%=at.getId()%>"
423                          data-item-type="<%=itemType.name()%>" 
424                          data-item-id="<%=itemId %>"
425                          tooltip="Modify the values of this protocol parameter" 
426                        visible="<%=writePermission %>"
427                      />
428                    </tbl:cell>
429                    <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
430                    <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
431                  </tbl:row>
432                  <%
433                }
434              }
435              %>
436              </tbl:rows>
437            </tbl:data>
438          </tbl:table>
439          <%
440        }
441        %>
442      </base:section>
443      <%
444    }
445    if (!isProxy)
446    {
447      int numInherited = inheritedAnnotations == null ? 0 : inheritedAnnotations.size();
448      %>
449      <base:section 
450        id="inherited"
451        title="<%="Inherited annotations (" + numInherited + ")"%>"         
452        >
453        <%
454        if (numInherited == 0)
455        {
456          %>
457          <div class="messagecontainer note">
458          No annotations are inherited by this item.
459          (or you don't have permission to view them).
460          </div>
461          <%
462        }
463        else
464        {
465        %>
466        <tbl:table
467          id="inheritedAnnotations"
468          columns="all"
469          >
470          <tbl:columndef 
471            id="annotation"
472            title="Annotation"
473          />
474          <tbl:columndef 
475            id="values"
476            title="Values"
477          />
478          <tbl:columndef 
479            id="item"
480            title="Parent item"
481          />
482          <tbl:columndef 
483            id="note"
484            title="Note"
485          />
486          <tbl:columndef
487            id="lastModified"
488            title="Last modified"
489            formatter="<%=dateTimeFormatter %>"
490          />
491          <tbl:columndef 
492            id="description"
493            title="Description"
494          />
495          <tbl:data>
496            <tbl:headers>
497              <tbl:headerrow>
498                <tbl:columnheaders />
499              </tbl:headerrow>
500            </tbl:headers>
501            <tbl:rows>
502            <%
503            for (AnnotationSnapshot a : inheritedAnnotations)
504            {
505              AnnotationType at = a.getAnnotationType(dc);
506              AnnotationSnapshot from = a.getInheritedFrom();
507             
508              // About this annotation
509              String name = HTML.encodeTags(at.getName());
510              String description = HTML.encodeTags(at.getDescription());
511              Date lastModified = a.getThisLastUpdate();
512              boolean isUpToDate = a.isUpToDate();
513             
514              // Which item are we inheriting from?
515              Nameable fromItem = null;
516              String fromType = null;
517              boolean writeInherited = false;
518              if (from != null)
519              {
520                fromType = from.getThisItemType().toString();
521                if (lastModified == null)
522                {
523                  lastModified = from.getThisLastUpdate();
524                }
525                try
526                {
527                  fromItem = (Nameable)from.getThisItem(dc);
528                  writeInherited = fromItem.hasPermission(Permission.WRITE);
529                  if (fromItem instanceof Subtypable)
530                  {
531                    ItemSubtype subtype = ((Subtypable)fromItem).getItemSubtype();
532                    if (subtype != null) fromType = subtype.getName();
533                  }
534                }
535                catch (PermissionDeniedException ex)
536                {}
537              }
538             
539              // Values, units, etc.
540              Formatter formatter = FormatterFactory.getTypeFormatter(sc, at.getValueType());
541              Unit unit = a.getActualUnit(dc);
542              UnitConverter converter = null;
543              if (unit != null)
544              {
545                converter = unit.getUnitConverter(at.getDefaultUnit());
546                formatter = unit.getFormatter(formatter);
547              }
548              List<?> values = a.getActualValues(converter, at.getValueType());
549              %>
550              <tbl:row>
551                <tbl:cell column="annotation"><%=Base.getLinkedName(ID, at, at == null, true)%></tbl:cell>
552                <tbl:cell column="values">
553                  <%=values == null || values.size() == 0 ? 
554                    "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
555                  <base:icon image="<%=isUpToDate ? "edit.png" : "edit-outofsync.png"%>" 
556                    subclass="edit-annotation auto-init link" 
557                    data-auto-init="edit-annotation" 
558                    data-annotation="<%= a.getThisAnnotationId()%>"
559                    data-annotation-type="<%=at.getId()%>"
560                    data-item-type="<%=itemType.name()%>" 
561                    data-item-id="<%=itemId %>"
562                    tooltip="Modify the values of this annotation"
563                    visible="<%=writePermission %>"
564                  />
565                </tbl:cell>
566                <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>
567                <tbl:cell column="note"><%=a.getSource() == Annotation.Source.CLONED ? "Cloned" + (isUpToDate ? "; up-to-date" : "; modified") : "" %></tbl:cell>
568                <tbl:cell column="lastModified" value="<%=lastModified %>"></tbl:cell>
569                <tbl:cell column="description"><%=description%></tbl:cell>
570              </tbl:row>
571              <%
572            }
573            %>
574            </tbl:rows>
575          </tbl:data>
576        </tbl:table>
577        <%
578      }
579      %>
580      </base:section>
581     
582      <%
583    }
584    %>
585  </base:body>
586  </base:page>
587  <%
588}
589finally
590{
591  if (dc != null) dc.close();
592}
593
594%>
Note: See TracBrowser for help on using the repository browser.