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

Last change on this file since 8083 was 8083, checked in by Nicklas Nordborg, 11 months ago

Merge BASE 3.19.4 to the trunk.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 29.0 KB
Line 
1<%-- $Id: list_annotations.jsp 8083 2022-10-20 12:56:36Z 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 pageEncoding="UTF-8" session="false"
26  import="net.sf.basedb.core.SessionControl"
27  import="net.sf.basedb.core.DbControl"
28  import="net.sf.basedb.core.Item"
29  import="net.sf.basedb.core.Permission"
30  import="net.sf.basedb.core.AnnotationType"
31  import="net.sf.basedb.core.Protocol"
32  import="net.sf.basedb.core.Project"
33  import="net.sf.basedb.core.AnnotationSet"
34  import="net.sf.basedb.core.Annotation"
35  import="net.sf.basedb.core.Annotatable"
36  import="net.sf.basedb.core.AnnotatableProxy"
37  import="net.sf.basedb.core.Unit"
38  import="net.sf.basedb.core.Nameable"
39  import="net.sf.basedb.core.Subtypable"
40  import="net.sf.basedb.core.ItemSubtype"
41  import="net.sf.basedb.core.BioPlate"
42  import="net.sf.basedb.core.BioPlateType"
43  import="net.sf.basedb.core.RawDataType"
44  import="net.sf.basedb.core.RawBioAssay"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.ItemResultList"
47  import="net.sf.basedb.core.Include"
48  import="net.sf.basedb.core.PermissionDeniedException"
49  import="net.sf.basedb.core.query.Orders"
50  import="net.sf.basedb.core.query.Hql"
51  import="net.sf.basedb.core.query.Restrictions"
52  import="net.sf.basedb.core.query.Expressions"
53  import="net.sf.basedb.core.snapshot.AnnotationSetSnapshot"
54  import="net.sf.basedb.core.snapshot.AnnotationSnapshot"
55  import="net.sf.basedb.core.snapshot.SnapshotManager"
56  import="net.sf.basedb.core.snapshot.ProjectFilter"
57  import="net.sf.basedb.core.snapshot.AnnotationTypeFilter"
58  import="net.sf.basedb.clients.web.Base"
59  import="net.sf.basedb.clients.web.util.HTML"
60  import="net.sf.basedb.util.NameableComparator"
61  import="net.sf.basedb.util.units.UnitConverter"
62  import="net.sf.basedb.util.formatter.Formatter"
63  import="net.sf.basedb.util.formatter.PrefixSuffixFormatter"
64  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
65  import="net.sf.basedb.util.Values"
66  import="net.sf.basedb.util.filter.Filter"
67  import="net.sf.basedb.util.filter.AllOfFilter"
68  import="java.util.Arrays"
69  import="java.util.Collections"
70  import="java.util.ArrayList"
71  import="java.util.List"
72  import="java.util.Set"
73  import="java.util.HashSet"
74  import="java.util.TreeSet"
75  import="java.util.Map"
76  import="java.util.HashMap"
77  import="java.util.Date"
78%>
79<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
80<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
81
82<%
83final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
84final String ID = sc.getId();
85final Item itemType = Item.valueOf(request.getParameter("item_type"));
86final int itemId = Values.getInt(request.getParameter("item_id"));
87final float scale = Base.getScale(sc);
88final DbControl dc = sc.newDbControl(":List annotations");
89
90Set<AnnotationType> annotationTypes = null;
91Set<AnnotationType> protocolParameters = null;
92Map<AnnotationType, AnnotationSnapshot> existing = null;
93
94boolean hasProjectSpecificAnnotationType = false;
95AnnotationTypeFilter annotationTypeFilter = null;
96Filter<AnnotationSnapshot> projectFilter = null;
97
98try
99{
100  final Annotatable item = (Annotatable)itemType.getById(dc, itemId);
101  final boolean writePermission = item.hasPermission(Permission.RESTRICTED_WRITE);
102  final SnapshotManager manager = new SnapshotManager();
103 
104  ItemQuery<AnnotationType> annotationTypeQuery = null;
105  String message = null;
106  boolean isProxy = item instanceof AnnotatableProxy;
107
108  // Load all annotation types that are possible for this item type
109  if (isProxy)
110  {
111    AnnotatableProxy proxy = (AnnotatableProxy)item;
112    annotationTypeQuery = Base.getAnnotationTypesQuery(proxy);
113    message = proxy.getAnnotationMessage();
114  }
115  else
116  {
117    annotationTypeQuery = Base.getAnnotationTypesQuery(itemType, false);
118  }
119  annotationTypes = new TreeSet<AnnotationType>(new NameableComparator<>(false));
120  annotationTypes.addAll(annotationTypeQuery.list(dc));
121
122  final AnnotationSetSnapshot snapshot = item.isAnnotated() ? 
123      manager.getSnapshot(dc, item.getAnnotationSet().getId()) : null;
124  List<AnnotationSnapshot> inheritedAnnotations = null;
125  if (snapshot != null)
126  {
127    // Load the existing primary and inherited annotations
128    existing = new HashMap<AnnotationType, AnnotationSnapshot>();
129    inheritedAnnotations = new ArrayList<AnnotationSnapshot>();
130    for (AnnotationSnapshot a : manager.findAnnotations(dc, snapshot, null, true))
131    {
132      AnnotationType at = a.getAnnotationType(dc);
133      if (a.getSource() == Annotation.Source.PRIMARY)
134      {
135        existing.put(a.getAnnotationType(dc), a);
136        hasProjectSpecificAnnotationType |= at.getProjectAnnotations();
137      }
138      else
139      {
140        inheritedAnnotations.add(a);
141      }
142    }
143    Collections.sort(inheritedAnnotations, AnnotationSnapshot.sortByAnnotationType(dc));
144    annotationTypes.addAll(existing.keySet());
145  }
146 
147  if (hasProjectSpecificAnnotationType)
148  {
149    manager.setAllProjects();
150    annotationTypeFilter = new AnnotationTypeFilter();
151    projectFilter = new AllOfFilter<>(Arrays.asList(annotationTypeFilter, new ProjectFilter(dc)));
152  }
153 
154  // Load the possible protocol parameters
155  Protocol protocol = null;
156  boolean readProtocol = true;
157  try
158  {
159    protocol = item.getProtocol();
160  }
161  catch (PermissionDeniedException ex)
162  {
163    readProtocol = false;
164  }
165  ItemQuery<AnnotationType> parameterQuery = Base.getProtocolParametersQuery(protocol);
166  if (parameterQuery != null)
167  {
168    protocolParameters = new HashSet<AnnotationType>(parameterQuery.list(dc));
169    annotationTypes.removeAll(protocolParameters);
170  }
171 
172  // Load the current subtype
173  // NOTE! User may have selected a different subtype in the form than what is
174  // currently saved so if a subtype_id is sent in the request we use that
175  String selectedCategoryName = null;
176  try
177  {
178    ItemSubtype subtype = null;
179    if (item instanceof Subtypable)
180    {
181      subtype = ((Subtypable)item).getItemSubtype();
182    }
183    else if (item instanceof BioPlate)
184    {
185      BioPlateType bpt = ((BioPlate)item).getBioPlateType();
186      subtype = bpt.getItemSubtype();
187      if (subtype == null) selectedCategoryName = bpt.getName();
188    }
189    else if (item instanceof RawBioAssay)
190    {
191      RawDataType rdt = ((RawBioAssay)item).getRawDataType();
192      selectedCategoryName = rdt.getName();
193    }
194    if (subtype != null) selectedCategoryName = subtype.getName();
195  }
196  catch (PermissionDeniedException ex)
197  {}
198  Set<AnnotationType> annotationTypesInCategory = new HashSet<AnnotationType>();
199  if (selectedCategoryName != null)
200  {
201    ItemQuery<AnnotationType> query = AnnotationType.getQuery(item.getType());
202    query.setIncludes(Include.ALL);
203    query.join(Hql.innerJoin("categories", "ct"));
204    query.restrict(Restrictions.eq(Hql.property("ct", "name"), Expressions.string(selectedCategoryName)));
205    annotationTypesInCategory.addAll(query.list(dc));
206  }
207  Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
208  String projectValuesTitle = "<div class=\"project-values\"><div>Project values</div><div></div><div></div><div class=\"last-modified\">Last modified</div></div>";
209  %>
210  <base:page type="iframe" id="list-annotations">
211  <base:head scripts="~list.js" styles="table.css">
212  <style>
213    #annotations-data.all
214    {}
215   
216    #annotations-data.values .novalues
217    {
218      display: none;
219    }
220   
221    #annotations-data.category .nocategory
222    {
223      display: none;
224    }
225   
226    .edit-annotation
227    {
228      float: right;
229    }
230   
231    .project-values
232    {
233      display: grid;
234      grid-template-columns: 1fr 1fr 18px 12em;
235    }
236   
237    .project-values div
238    {
239      padding: 1px 2px;
240      border-bottom-width: 1px;
241      border-bottom-style: dotted;
242    }
243   
244    /* Remove borders on last row */
245    .project-values div:nth-last-child(-n+4)
246    {
247      border-bottom-width: 0;
248    }
249   
250    .project-values .default-value
251    {
252      font-style: italic;
253    }
254   
255    .project-values .current-value::before
256    {
257      font-weight: bold;
258      content: '›';
259      margin-right: 2px;
260    }
261
262    .project-values .other-value::before
263    {
264      font-weight: bold;
265      content: '›';
266      color: transparent;
267      margin-right: 2px;
268    }
269   
270    /* Span accross first 2 columns */
271    .project-values .no-default
272    {
273      font-style: italic;
274      grid-column-start: 1;
275      grid-column-end: 3;
276    }
277   
278    .last-modified
279    {
280      white-space: nowrap;
281      border-left-width: 1px;
282      border-left-style: dotted;
283    }
284  </style>
285  </base:head>
286  <base:body>
287    <%
288    if (message != null)
289    {
290      %>
291      <div class="messagecontainer note"><%=message%></div>
292      <%
293    }
294    %>
295    <base:section
296      id="primaryAnnotations"
297      title="<%="Primary annotations (" + annotationTypes.size() + ")"%>"
298      >
299      <%
300      int allWithValues = 0;
301      int allOfCategory = 0;
302      if (annotationTypes.size() == 0)
303      {
304        %>
305        <div class="messagecontainer note">
306        No annotation types has been defined for this type of item
307        (or you don't have permission to view them).
308        </div>
309        <%
310      }
311      else
312      {
313        %>
314        <tbl:table
315          id="annotations"
316          columns="all"
317          stickyheaders="<%=null%>"
318          >
319          <tbl:columndef 
320            id="annotation"
321            title="Annotation"
322          />
323          <tbl:columndef 
324            id="values"
325            title="<%=hasProjectSpecificAnnotationType ? "Current values" : "Values" %>"
326          />
327          <tbl:columndef
328            id="projectValues"
329            title="<%=projectValuesTitle%>"
330            tooltip="Project values"
331            show="<%=hasProjectSpecificAnnotationType ? "always" : "never" %>"
332            style="padding: 0;"
333          />
334          <tbl:columndef
335            id="lastModified"
336            title="Last modified"
337            formatter="<%=dateTimeFormatter%>"
338            show="<%=hasProjectSpecificAnnotationType ? "never" : "always" %>"
339          />
340          <tbl:columndef 
341            id="description"
342            title="Description"
343          />
344          <tbl:data id="annotations-data">
345            <tbl:headers>
346              <tbl:headerrow>
347                <tbl:header colspan="5" subclass="bottomborder" style="padding: 5px;">
348                  <b>View:</b> 
349                  <%
350                  if (selectedCategoryName != null)
351                  {
352                    %>
353                    <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>)
354                    <%
355                  }
356                  %>
357                  <label><input type="radio" name="view" id="view_values" value="values" <%=selectedCategoryName == null ? "checked" : ""%>>All with values</label> (<span id="allWithValues">?</span>)
358                  <label><input type="radio" name="view" id="view_all" value="all">All annotations</label> (<%=annotationTypes.size()%>)
359                </tbl:header>
360              </tbl:headerrow>
361              <tbl:headerrow>
362                <tbl:columnheaders />
363              </tbl:headerrow>
364            </tbl:headers>
365            <tbl:rows>
366            <%
367            for (AnnotationType at : annotationTypes)
368            {
369              // Permission for creating a new annotation
370              boolean annotatePermission = writePermission & at.hasPermission(Permission.USE);
371              AnnotationSnapshot a = existing != null ? existing.get(at) : null;
372              List<?> values = null;
373              Formatter<Object> formatter = null;
374              boolean projectSpecific = false;
375              if (a != null)
376              {
377                Annotation ann = a.getThisAnnotation(dc);
378                // Permission on this annotation
379                annotatePermission = ann.hasPermission(Permission.WRITE);
380                values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
381                formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
382                projectSpecific = a.getProjectId() != 0;
383              }
384              if (values != null || !at.isRemoved())
385              {
386                String rowClass = "";
387                if (values == null || values.size() == 0) 
388                {
389                  rowClass += " novalues";
390                }
391                else
392                {
393                  allWithValues++;
394                }
395                if (!annotationTypesInCategory.contains(at)) 
396                {
397                  rowClass += " nocategory";
398                }
399                else
400                {
401                  allOfCategory++;
402                }
403                %>
404                <tbl:row subclass="<%=rowClass%>">
405                  <tbl:cell column="annotation"><base:icon 
406                    image="deleted.png" 
407                    tooltip="This item has been scheduled for deletion" 
408                    visible="<%=at.isRemoved()%>"
409                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
410                  <tbl:cell column="values" clazz="<%=projectSpecific ? "cell ps-annotation" : "cell" %>" disableOverflowCheck="true">
411                    <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
412                    <base:icon image="<%=a==null?"edit_create.png":"edit.png" %>" subclass="edit-annotation auto-init link" 
413                      data-auto-init="edit-annotation" 
414                      data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
415                      data-annotation-type="<%=at.getId()%>"
416                      data-item-type="<%=itemType.name()%>" 
417                      data-item-id="<%=itemId %>"
418                      tooltip="<%=a==null?"Create this annotation":"Modify the values of this annotation"%>"
419                      visible="<%=annotatePermission %>"
420                    />
421                  </tbl:cell>
422                  <tbl:cell column="projectValues" disableOverflowCheck="true" style="padding:0;">
423                    <div class="project-values">
424                    <%
425                    if (at.getProjectAnnotations())
426                    {
427                      annotationTypeFilter.setAnnotationType(at);
428                      List<AnnotationSnapshot> projectValues = manager.findAnnotations(dc, snapshot, projectFilter, false);
429                      projectValues.sort(AnnotationSnapshot.sortByProject(dc, true));
430                      int numValues = projectValues.size();
431                      if (numValues == 0 || projectValues.get(0).getProjectId() != 0)
432                      {
433                        %>
434                        <div class="no-default"><%=numValues > 0 ? "No default value":""%></div>
435                        <div><base:icon image="edit_create.png" subclass="edit-annotation auto-init link" 
436                            data-auto-init="edit-annotation" 
437                            data-annotation="0"
438                            data-annotation-type="<%=at.getId()%>"
439                            data-project="0"
440                            data-item-type="<%=itemType.name()%>" 
441                            data-item-id="<%=itemId %>"
442                            tooltip="Create a default value"
443                            visible="<%=annotatePermission %>"
444                          /></div>
445                        <div class="last-modified"></div>
446                        <%
447                      }
448                      if (numValues > 0)
449                      {
450                        for (AnnotationSnapshot pv : projectValues)
451                        {
452                          boolean isDefault = pv.getProjectId() == 0;
453                          boolean isCurrent = pv == a;
454                          Annotation ann = pv.getThisAnnotation(dc);
455                          values = pv.getActualValues(ann.getUnitConverter(null), ann.getValueType());
456                          formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
457                          if (numValues > 1)
458                          {
459                            %>
460                            <div class="<%=isCurrent?"current-value":"other-value"%><%=isDefault ? " default-value":""%>"><%=isDefault ? "Default" : pv.getProject(dc).getName() %></div>
461                            <div><%=Values.getString(values, ", ", true, formatter) %></div>
462                            <%
463                          }
464                          else
465                          {
466                            %>
467                            <div></div><div></div>
468                            <%
469                          }
470                          %>
471                          <div><base:icon image="edit.png" subclass="edit-annotation auto-init link" 
472                              data-auto-init="edit-annotation" 
473                              data-annotation="<%=pv.getThisAnnotationId()%>"
474                              data-annotation-type="<%=at.getId()%>"
475                              data-project="<%=pv.getProjectId()%>"
476                              data-item-type="<%=itemType.name()%>" 
477                              data-item-id="<%=itemId %>"
478                              tooltip="<%=isDefault ? "Modify the default value" : "Modify the value in this project"%>"
479                              visible="<%=annotatePermission %>"
480                            /></div>
481                          <div class="last-modified"><%=dateTimeFormatter.format(pv.getThisLastUpdate())%></div>
482                          <%
483                        }
484                      }
485                    }
486                    else if (a != null)
487                    {
488                      %>
489                      <div></div><div></div><div></div>
490                      <div class="last-modified"><%=dateTimeFormatter.format(a.getThisLastUpdate())%></div>
491                      <%
492                    }
493                    %>
494                    </div>
495                  </tbl:cell>
496                  <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
497                  <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
498                </tbl:row>
499                <%
500              }
501            }
502            %>
503            </tbl:rows>
504          </tbl:data>
505        </tbl:table>
506        <%
507      }
508      %>
509      <div id="annotations-stat" class="datacontainer"
510        data-all-with-values="<%=allWithValues %>"
511        data-all-of-category="<%=allOfCategory%>"
512      ></div>
513    </base:section>
514
515    <%
516    if (protocolParameters != null)
517    {
518      %>
519      <base:section 
520        id="parameterSection" 
521        title="<%="Protocol parameters for " + HTML.encodeTags(protocol.getName()) + 
522          " (" + protocolParameters.size() + ")"%>"
523        >
524        <%
525        if (protocolParameters.size() == 0)
526        {
527          %>
528          <div class="messagecontainer note">
529          No protocol parameters has been defined for the protocol
530          <%=Base.getLinkedName(ID, protocol, !readProtocol, true)%> 
531          (or you don't have permission to view them).
532          </div>
533          <%
534        }
535        else
536        {
537          %>
538          <tbl:table
539            id="parameters"
540            columns="all"
541            >
542            <tbl:columndef 
543              id="parameter"
544              title="Parameter"
545            />
546            <tbl:columndef 
547              id="values"
548              title="<%=hasProjectSpecificAnnotationType ? "Current values" : "Values" %>"
549            />
550            <tbl:columndef
551              id="projectValues"
552              title="<%=projectValuesTitle%>"
553              tooltip="Project values"
554              show="<%=hasProjectSpecificAnnotationType ? "always" : "never" %>"
555              style="padding: 0;"
556            />
557            <tbl:columndef
558              id="lastModified"
559              title="Last modified"
560              formatter="<%=dateTimeFormatter%>"
561              show="<%=hasProjectSpecificAnnotationType ? "never" : "always" %>"
562            />
563            <tbl:columndef 
564              id="description"
565              title="Description"
566            />
567            <tbl:data>
568              <tbl:headers>
569                <tbl:headerrow>
570                  <tbl:columnheaders />
571                </tbl:headerrow>
572              </tbl:headers>
573              <tbl:rows>
574              <%
575              for (AnnotationType at : protocolParameters)
576              {
577                // Permission for creating a new annotation
578                boolean annotatePermission = writePermission & at.hasPermission(Permission.USE);
579                AnnotationSnapshot a = existing != null ? existing.get(at) : null;
580                List<?> values = null;
581                Formatter<Object> formatter = null;
582                boolean projectSpecific = false;
583                if (a != null)
584                {
585                  Annotation ann = a.getThisAnnotation(dc);
586                  // Permission on this annotation
587                  annotatePermission = ann.hasPermission(Permission.WRITE);
588                  values = a.getActualValues(ann.getUnitConverter(null), ann.getValueType());
589                  formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
590                  projectSpecific = a.getProjectId() != 0;
591                }
592                if (values != null || !at.isRemoved())
593                {
594                  %>
595                  <tbl:row>
596                    <tbl:cell column="parameter"><base:icon 
597                      image="deleted.png" 
598                      tooltip="This item has been scheduled for deletion" 
599                      visible="<%=at.isRemoved()%>"
600                    /><%=Base.getLinkedName(ID, at, false, true)%></tbl:cell>
601                    <tbl:cell column="values" clazz="<%=projectSpecific ? "cell ps-annotation" : "cell" %>" disableOverflowCheck="true">
602                      <%=values == null || values.size() == 0 ? "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
603                      <base:icon image="<%=a==null?"edit_create.png":"edit.png" %>" subclass="edit-annotation auto-init link" 
604                        data-auto-init="edit-annotation" 
605                        data-annotation="<%=a!=null ? a.getThisAnnotationId() : 0 %>"
606                        data-annotation-type="<%=at.getId()%>"
607                        data-item-type="<%=itemType.name()%>" 
608                        data-item-id="<%=itemId %>"
609                        tooltip="<%=a==null?"Create this protocol parameter":"Modify the values of this protocol parameter"%>"
610                        visible="<%=annotatePermission %>"
611                      />
612                    </tbl:cell>
613                    <tbl:cell column="projectValues" disableOverflowCheck="true" style="padding:0;"> 
614                      <div class="project-values">
615                      <%
616                      if (at.getProjectAnnotations())
617                      {
618                        annotationTypeFilter.setAnnotationType(at);
619                        List<AnnotationSnapshot> projectValues = manager.findAnnotations(dc, snapshot, projectFilter, false);
620                        projectValues.sort(AnnotationSnapshot.sortByProject(dc, true));
621                        int numValues = projectValues.size();
622                        if (numValues == 0 || projectValues.get(0).getProjectId() != 0)
623                        {
624                          %>
625                          <div class="no-default"><%=numValues > 0 ? "No default value":""%></div>
626                          <div><base:icon image="edit_create.png" subclass="edit-annotation auto-init link" 
627                              data-auto-init="edit-annotation" 
628                              data-annotation="0"
629                              data-annotation-type="<%=at.getId()%>"
630                              data-project="0"
631                              data-item-type="<%=itemType.name()%>" 
632                              data-item-id="<%=itemId %>"
633                              tooltip="Create a default value"
634                              visible="<%=annotatePermission %>"
635                            /></div>
636                          <div class="last-modified"></div>
637                          <%
638                        }
639                        if (numValues > 0)
640                        {
641                          for (AnnotationSnapshot pv : projectValues)
642                          {
643                            boolean isDefault = pv.getProjectId() == 0;
644                            boolean isCurrent = pv == a;
645                            Annotation ann = pv.getThisAnnotation(dc);
646                            values = pv.getActualValues(ann.getUnitConverter(null), ann.getValueType());
647                            formatter = FormatterFactory.getAnnotationFormatter(sc, ann, null);
648                            if (numValues > 1)
649                            {
650                              %>
651                              <div class="<%=isCurrent?"current-value":"other-value"%><%=isDefault ? " default-value":""%>"><%=isDefault ? "Default" : pv.getProject(dc).getName() %></div>
652                              <div><%=Values.getString(values, ", ", true, formatter) %></div>
653                              <%
654                            }
655                            else
656                            {
657                              %>
658                              <div></div><div></div>
659                              <%
660                            }
661                            %>
662                            <div><base:icon image="edit.png" subclass="edit-annotation auto-init link" 
663                                data-auto-init="edit-annotation" 
664                                data-annotation="<%=pv.getThisAnnotationId()%>"
665                                data-annotation-type="<%=at.getId()%>"
666                                data-project="<%=pv.getProjectId()%>"
667                                data-item-type="<%=itemType.name()%>" 
668                                data-item-id="<%=itemId %>"
669                                tooltip="Modify the values of this protocol parameter"
670                                visible="<%=annotatePermission %>"
671                            /></div>
672                            <div class="last-modified"><%=dateTimeFormatter.format(pv.getThisLastUpdate())%></div>
673                            <%
674                          }
675                        }
676                      }
677                      else if (a != null)
678                      {
679                        %>
680                        <div></div><div></div><div></div>
681                        <div class="last-modified"><%=dateTimeFormatter.format(a.getThisLastUpdate())%></div>
682                        <%
683                      }
684                      %>
685                      </div>
686                    </tbl:cell>
687                    <tbl:cell column="lastModified" value="<%=a == null ? null : a.getThisLastUpdate() %>" />
688                    <tbl:cell column="description"><%=HTML.encodeTags(at.getDescription())%></tbl:cell>
689                  </tbl:row>
690                  <%
691                }
692              }
693              %>
694              </tbl:rows>
695            </tbl:data>
696          </tbl:table>
697          <%
698        }
699        %>
700      </base:section>
701      <%
702    }
703    if (!isProxy)
704    {
705      int numInherited = inheritedAnnotations == null ? 0 : inheritedAnnotations.size();
706      %>
707      <base:section 
708        id="inherited"
709        title="<%="Inherited annotations (" + numInherited + ")"%>"         
710        >
711        <%
712        if (numInherited == 0)
713        {
714          %>
715          <div class="messagecontainer note">
716          No annotations are inherited by this item.
717          (or you don't have permission to view them).
718          </div>
719          <%
720        }
721        else
722        {
723        %>
724        <tbl:table
725          id="inheritedAnnotations"
726          columns="all"
727          >
728          <tbl:columndef 
729            id="annotation"
730            title="Annotation"
731          />
732          <tbl:columndef 
733            id="values"
734            title="Values"
735          />
736          <tbl:columndef 
737            id="item"
738            title="Parent item"
739          />
740          <tbl:columndef 
741            id="note"
742            title="Note"
743          />
744          <tbl:columndef
745            id="lastModified"
746            title="Last modified"
747            formatter="<%=dateTimeFormatter %>"
748          />
749          <tbl:columndef 
750            id="description"
751            title="Description"
752          />
753          <tbl:data>
754            <tbl:headers>
755              <tbl:headerrow>
756                <tbl:columnheaders />
757              </tbl:headerrow>
758            </tbl:headers>
759            <tbl:rows>
760            <%
761            for (AnnotationSnapshot a : inheritedAnnotations)
762            {
763              boolean annotatePermission = a.hasPermission(dc, Permission.WRITE);
764              AnnotationType at = a.getAnnotationType(dc);
765              AnnotationSnapshot from = a.getInheritedFrom();
766             
767              // About this annotation
768              String name = HTML.encodeTags(at.getName());
769              String description = HTML.encodeTags(at.getDescription());
770              Date lastModified = a.getThisLastUpdate();
771              boolean isUpToDate = a.isUpToDate();
772             
773              // Which item are we inheriting from?
774              Nameable fromItem = null;
775              String fromType = null;
776              boolean writeInherited = false;
777              if (from != null)
778              {
779                fromType = from.getThisItemType().toString();
780                if (lastModified == null)
781                {
782                  lastModified = from.getThisLastUpdate();
783                }
784                try
785                {
786                  fromItem = (Nameable)from.getThisItem(dc);
787                  writeInherited = fromItem.hasPermission(Permission.WRITE);
788                  if (fromItem instanceof Subtypable)
789                  {
790                    ItemSubtype subtype = ((Subtypable)fromItem).getItemSubtype();
791                    if (subtype != null) fromType = subtype.getName();
792                  }
793                }
794                catch (PermissionDeniedException ex)
795                {}
796              }
797             
798              // Values, units, etc.
799              Formatter<Object> formatter = FormatterFactory.getTypeFormatter(sc, at.getValueType());
800              Unit unit = a.getActualUnit(dc);
801              UnitConverter converter = null;
802              if (unit != null)
803              {
804                converter = unit.getUnitConverter(at.getDefaultUnit());
805                formatter = unit.getFormatter(formatter);
806              }
807              List<?> values = a.getActualValues(converter, at.getValueType());
808              List<?> defaultValues = null;
809              boolean projectSpecific = a.getProjectId() != 0;
810              if (projectSpecific)
811              {
812                Annotation ann = a.getThisAnnotation(dc);
813                if (ann.isOverridingDefault())
814                {
815                  Annotation defAnn = ann.getDefaultAnnotation();
816                  Annotation defFrom = defAnn.getInheritedFrom();
817                  defaultValues = defAnn.getSource() == Annotation.Source.CLONED ? defAnn.getValues() : defFrom.getValues();
818                }
819              }
820              %>
821              <tbl:row>
822                <tbl:cell column="annotation"><%=Base.getLinkedName(ID, at, at == null, true)%></tbl:cell>
823                <tbl:cell column="values" clazz="<%=projectSpecific ? "cell ps-annotation" : "cell" %>" disableOverflowCheck="true">
824                  <%=values == null || values.size() == 0 ? 
825                    "<i>- no values -</i>" : Values.getString(values, ", ", true, formatter)%>
826                  <base:icon image="<%=isUpToDate ? "edit.png" : "edit-outofsync.png"%>" 
827                    subclass="edit-annotation auto-init link" 
828                    data-auto-init="edit-annotation" 
829                    data-annotation="<%= a.getThisAnnotationId()%>"
830                    data-annotation-type="<%=at.getId()%>"
831                    data-item-type="<%=itemType.name()%>" 
832                    data-item-id="<%=itemId %>"
833                    tooltip="Modify the values of this annotation"
834                    visible="<%=annotatePermission %>"
835                  />
836                </tbl:cell>
837                <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>
838                <tbl:cell column="note">
839                  <%=a.getSource() == Annotation.Source.CLONED ? "Cloned" + (isUpToDate ? "; up-to-date" : "; modified") : "" %>
840                    <%
841                    if (projectSpecific && at.getProjectAnnotations())
842                    {
843                      %>
844                      <%=defaultValues == null || defaultValues.size() == 0 ? "No default value" : "Default value: " + Values.getString(defaultValues, ", ", true, formatter)%>
845                      <%
846                    }
847                    %>
848                </tbl:cell>
849                <tbl:cell column="lastModified" value="<%=lastModified %>"></tbl:cell>
850                <tbl:cell column="description"><%=description%></tbl:cell>
851              </tbl:row>
852              <%
853            }
854            %>
855            </tbl:rows>
856          </tbl:data>
857        </tbl:table>
858        <%
859      }
860      %>
861      </base:section>
862     
863      <%
864    }
865    %>
866  </base:body>
867  </base:page>
868  <%
869}
870finally
871{
872  if (dc != null) dc.close();
873}
874
875%>
Note: See TracBrowser for help on using the repository browser.