source: trunk/www/common/overview/info.jsp @ 6962

Last change on this file since 6962 was 6962, checked in by Nicklas Nordborg, 7 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.6 KB
Line 
1<%-- $Id: info.jsp 6962 2015-10-01 12:29:38Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2009 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<%@ page pageEncoding="UTF-8" session="false"
23  import="net.sf.basedb.core.SessionControl"
24  import="net.sf.basedb.core.DbControl"
25  import="net.sf.basedb.core.Project"
26  import="net.sf.basedb.core.Item"
27  import="net.sf.basedb.core.BasicItem"
28  import="net.sf.basedb.core.Nameable"
29  import="net.sf.basedb.core.Annotatable"
30  import="net.sf.basedb.core.AnnotationSet"
31  import="net.sf.basedb.core.AnnotationType"
32  import="net.sf.basedb.core.Annotation"
33  import="net.sf.basedb.core.ItemSubtype"
34  import="net.sf.basedb.core.Subtypable"
35  import="net.sf.basedb.core.AnyToAny"
36  import="net.sf.basedb.core.Protocol"
37  import="net.sf.basedb.core.Unit"
38  import="net.sf.basedb.core.FileStoreEnabled"
39  import="net.sf.basedb.core.FileSetMember"
40  import="net.sf.basedb.core.File"
41  import="net.sf.basedb.core.DataFileType"
42  import="net.sf.basedb.core.ItemContext"
43  import="net.sf.basedb.core.Permission"
44  import="net.sf.basedb.core.PermissionDeniedException"
45  import="net.sf.basedb.core.ItemNotFoundException"
46  import="net.sf.basedb.core.snapshot.SnapshotManager"
47  import="net.sf.basedb.core.snapshot.AnnotationSetSnapshot"
48  import="net.sf.basedb.core.snapshot.AnnotationSnapshot"
49  import="net.sf.basedb.core.snapshot.AnnotationTypeFilter"
50  import="net.sf.basedb.core.snapshot.AnnotationFilter"
51  import="net.sf.basedb.clients.web.Base"
52  import="net.sf.basedb.clients.web.util.HTML"
53  import="net.sf.basedb.clients.web.extensions.section.SectionAction"
54  import="net.sf.basedb.clients.web.extensions.JspContext"
55  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
56  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
57  import="net.sf.basedb.util.Values"
58  import="net.sf.basedb.util.NestedIterator"
59  import="net.sf.basedb.util.units.UnitConverter"
60  import="net.sf.basedb.util.formatter.Formatter"
61  import="net.sf.basedb.util.overview.GenericOverview"
62  import="net.sf.basedb.util.overview.OverviewUtil"
63  import="net.sf.basedb.util.overview.Node"
64  import="net.sf.basedb.util.overview.ValidationOptions"
65  import="net.sf.basedb.util.overview.Validator"
66  import="net.sf.basedb.util.overview.Severity"
67  import="net.sf.basedb.util.overview.Failure"
68  import="net.sf.basedb.util.overview.Fix"
69  import="net.sf.basedb.util.overview.extensions.ValidationRuleAction"
70  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
71  import="java.util.ArrayList"
72  import="java.util.Date"
73  import="java.util.List"
74  import="java.util.LinkedList"
75  import="java.util.Iterator"
76  import="java.util.Collection"
77  import="java.util.Collections"
78%>
79<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
80<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
81<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
82<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
83<%!
84private String getPath(DbControl dc, String ID, Node node)
85{
86  Node parent = node.getParent();
87  if (parent == null) return "";
88  String path = getPath(dc, ID, parent);
89  if (parent.getNodeType() == Node.Type.FOLDER)
90  {
91    //path += "/" + HTML.encodeTags(parent.getTitle());
92  }
93  else
94  {
95    BasicItem item = parent.getItem();
96    if (path.length() > 0)
97    {
98      path += " <b>›</b> ";
99    }
100    path += Base.getLink(ID, parent.getTitle(), item.getType(), item.getId(), item.hasPermission(Permission.WRITE));
101   
102    if (item instanceof Subtypable)
103    {
104      ItemSubtype subtype = ((Subtypable)parent.getItem(dc)).getItemSubtype();
105      if (subtype != null)
106      {
107        path += " <span class=\"itemsubtype\">(" + Base.getLinkedName(ID, subtype, false, true) + ")</span>";
108      }
109    }
110  }
111  return path;
112}
113%>
114<%
115final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
116final String ID = sc.getId();
117final float scale = Base.getScale(sc);
118final DbControl dc = sc.newDbControl();
119try
120{
121  final GenericOverview overview = OverviewUtil.getCurrentOverview(sc);
122  final ItemContext cc = sc.getCurrentContext(overview.getRootItem().getType());
123  final SnapshotManager snapshotManager = new SnapshotManager();
124  final AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter();
125  final AnnotationFilter annotationFilter = new AnnotationFilter();
126  ValidationOptions options = overview.getValidationOptions();
127  String nodeId = request.getParameter("nodeId");
128  Boolean showFailures = Values.getBoolean(request.getParameter("show_failures"), false);
129  Node node = overview.getNode(nodeId);
130  if (node == null) node = overview.getRootNode();
131
132  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, null, node);
133  ExtensionsInvoker<SectionAction> invoker = (ExtensionsInvoker<SectionAction>)ExtensionsControl.useExtensions(
134      jspContext, "net.sf.basedb.clients.web.overview.info-details");
135 
136  BasicItem item = node.getItem(dc);
137  List<Failure> failures = overview.getFailures();
138  if (failures == null) failures = new LinkedList<Failure>();
139 
140  Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
141
142  %>
143  <base:page title="" type="iframe">
144  <base:head styles="table.css" scripts="dragdrop.js,~info.js">
145    <ext:scripts context="<%=jspContext%>" />
146    <ext:stylesheets context="<%=jspContext%>" />
147  <style>
148  .itemsubtype .link
149  {
150    color: #777777;
151  }
152  .edit-annotation
153  {
154    float: right;
155  }
156  </style>
157  </base:head>
158
159    <base:body>
160      <div class="absolutefull auto-init" data-auto-init="drag-support">
161      <div>
162      <table class="fullform bottomborder outlined">
163      <tr>
164        <th>Path</th>
165        <td><%=getPath(dc, ID, node)%></td>
166      </tr>
167      <%
168      if (item instanceof FileSetMember)
169      {
170        FileSetMember member = null;
171        boolean notFound = false;
172        try
173        { 
174          member = FileSetMember.getById(dc, item.getId());
175        }
176        catch (ItemNotFoundException ex)
177        {
178          notFound = true;
179        }
180        File file = null;
181        DataFileType dft = null;
182        boolean deniedFile = false;
183        boolean deniedFileType = false;
184        if (member != null)
185        {
186          try
187          {
188            file = member.getFile();
189          }
190          catch (PermissionDeniedException ex)
191          {
192            deniedFile = true;
193          }
194          try
195          {
196            dft = member.getDataFileType();
197          }
198          catch (PermissionDeniedException ex)
199          {
200            deniedFileType = true;
201          }
202        }
203        if (dft != null || file != null)
204        {
205          %>
206          <tr>
207            <th><%=dft == null ? "Data file" : HTML.encodeTags(dft.getName())%></th>
208            <td>
209              <%=Base.getLinkedFile(ID, file, deniedFile, true, true, "../../")%>
210            </td>
211          </tr>
212          <%
213        }
214        else
215        {
216          %>
217          <tr>
218          <th><%=HTML.encodeTags(node.getTitle())%></th>
219          <td>
220            <%=notFound ? "<i>- not found -</i>" : "<i>- denied -</i>"%>
221          </td>
222          </tr>
223          <%
224        }
225      }
226      else if (item instanceof AnyToAny)
227      {
228        AnyToAny any = AnyToAny.getById(dc, item.getId());
229        String linkTo = null;
230        try
231        {
232          BasicItem to = any.getTo();
233          String name = to instanceof Nameable ? ((Nameable)to).getName() : to.toString();
234          linkTo = Base.getLink(ID, HTML.encodeTags(name), 
235              to.getType(), to.getId(), to.hasPermission(Permission.WRITE));
236        }
237        catch (PermissionDeniedException ex)
238        {
239          linkTo = any.getToType() + "[id=" + any.getToId() + "] (<i>denied</i>)";
240        }
241        catch (ItemNotFoundException ex)
242        {
243          linkTo = any.getToType() + "[id=" + any.getToId() + "] (<i>missing</i>)";
244        }
245        %>
246        <tr>
247          <th>Any-to-any link</th>
248          <td>
249            <table>
250            <tr>
251              <td><%=Base.getLinkedName(ID, any, false, true) %></td>
252              <td><base:icon image="bullet.png" /></td>
253              <td><%=linkTo%></td>
254            </tr>
255            </table>
256          </td>
257        </tr>
258        <%
259      }
260      else
261      {
262        %>
263        <tr>
264          <th><%=node.getNodeType() == Node.Type.FOLDER ? 
265              "Folder" : item != null ? item.getType().toString() : "Item"%></th>
266          <td>
267            <%
268            if (item != null)
269            {
270              %>
271              <%=Base.getLink(ID, node.getTitle(), item.getType(),item.getId(), item.hasPermission(Permission.WRITE))%>
272              <%
273              if (item instanceof Subtypable)
274              {
275                ItemSubtype subtype = ((Subtypable)item).getItemSubtype();
276                if (subtype != null)
277                {
278                  %>
279                  <span class="itemsubtype">(<%=Base.getLinkedName(ID, subtype, false, true)%>)</span>
280                  <%
281                }
282              }
283            }
284            else
285            {
286              %>
287              <%=HTML.encodeTags(node.getTitle())%>
288              <%
289            }
290            %>
291          </td>
292        </tr>
293        <%
294      }
295      %>
296      <tr>
297        <th>Errors (children)</th>
298        <%
299        if (showFailures)
300        {
301        %>
302          <td><%=node.getNumErrors()+node.getChildErrors()%> (<%=node.getChildErrors()%>)</td>
303        <%
304        }
305        else
306        {       
307        %>
308          <td><i>- n/a -</i></td>
309        <%
310        }
311        %>
312      </tr>
313      <tr>
314        <th>Warnings (children)</th>
315        <%
316        if (showFailures)
317        {
318        %>
319          <td><%=node.getNumWarnings()+node.getChildWarnings()%> (<%=node.getChildWarnings()%>)</td>
320        <%
321        }
322        else
323        {       
324        %>
325          <td><i>- n/a -</i></td>
326        <%
327        }
328        %>
329      </tr>
330      <%
331      if (item instanceof Nameable)
332      {
333        Nameable nameable = (Nameable)item;
334        %>
335        <tr>
336          <th>Description</th>
337          <td><%=HTML.niceFormat(nameable.getDescription())%></td>
338        </tr>
339        <%
340      }
341      %>
342      </table>
343      </div>
344      <%
345      List<AnnotationSnapshot> annotations = new LinkedList<AnnotationSnapshot>();
346      String annotationsTitle = "";
347      Annotatable annotatable = null;
348      if (item instanceof Annotation)
349      {
350        Annotation a = Annotation.getById(dc, item.getId());
351        AnnotationSetSnapshot snapshot = snapshotManager.getSnapshot(dc, a.getAnnotationSet().getId());
352        annotationFilter.setAnnotation(a);
353        annotations.addAll(snapshotManager.findAnnotations(dc, snapshot, annotationFilter, true));
354       
355        // Find the annotatable parent node
356        Node parentNode = node;
357        while (parentNode != null)
358        {
359          BasicItem parentItem = parentNode.getItem();
360          if (parentItem instanceof Annotatable)
361          {
362            annotatable = (Annotatable)parentItem;
363            break;
364          }
365          parentNode = parentNode.getParent();
366        }
367        annotationsTitle = "Annotation values";
368      }
369      else if (item instanceof AnnotationType)
370      {
371        // Find the annotatable parent
372        Node parentNode = node;
373        while (parentNode != null)
374        {
375          BasicItem parentItem = parentNode.getItem();
376          if (parentItem instanceof Annotatable && !(parentItem instanceof Protocol))
377          {
378            annotatable = (Annotatable)parentItem.getType().getById(dc, parentItem.getId());
379            if (annotatable.isAnnotated())
380            {
381              annotationTypeFilter.setAnnotationType((AnnotationType)item);
382              annotations.addAll(snapshotManager.findAnnotations(dc, annotatable, annotationTypeFilter, true));
383            }
384            annotationsTitle = "Annotation values";
385            break;
386          }
387          parentNode = parentNode.getParent();
388        }
389      }
390      else if (item instanceof Annotatable)
391      {
392        annotationsTitle = "Annotations &amp; protocol parameters";
393        annotatable = (Annotatable)item.getType().getById(dc, item.getId());
394        if (annotatable.isAnnotated())
395        {
396          annotations.addAll(snapshotManager.findAnnotations(dc, annotatable, null, true));
397        }
398       
399      }
400      if (annotations != null && annotations.size() > 0)
401      {
402        Collections.sort(annotations, AnnotationSnapshot.sortByAnnotationType(dc));
403        %>
404        <base:section
405          id="allAnnotations"
406          title="<%="Annotations &amp; parameters (" +  annotations.size() + ")"%>"
407          context="<%=cc %>">
408       
409        <tbl:table id="annotations">
410          <tbl:columndef id="annotation" title="Annotation/parameter" />
411          <tbl:columndef id="values" title="Values" />
412          <tbl:columndef 
413            id="item"
414            title="Parent item"
415          />
416          <tbl:columndef 
417            id="note"
418            title="Note"
419          />
420          <tbl:columndef
421            id="lastModified"
422            title="Last modified"
423            formatter="<%=dateTimeFormatter %>"
424          />
425          <tbl:data>
426            <tbl:headers>
427              <tbl:headerrow>
428                <tbl:columnheaders />
429              </tbl:headerrow>
430            </tbl:headers>
431            <tbl:rows>
432              <%
433              for (AnnotationSnapshot snapshot : annotations)
434              {
435                AnnotationType at = snapshot.getAnnotationType(dc);
436               
437                // Unit and formatter for the values
438                Formatter formatter = FormatterFactory.getTypeFormatter(sc, at.getValueType());
439                Unit unit = snapshot.getActualUnit(dc);
440                UnitConverter converter = null;
441                if (unit != null)
442                {
443                  converter = unit.getUnitConverter(at.getDefaultUnit());
444                  formatter = unit.getFormatter(formatter);
445                }
446                // Get values
447                List<?> values = snapshot.getActualValues(converter, at.getValueType());
448
449                // Inheritance information
450                Date lastModified = snapshot.getThisLastUpdate();
451                boolean isUpToDate = snapshot.isUpToDate();
452                AnnotationSnapshot inherited = snapshot.getInheritedFrom();
453                Annotatable inheritedFrom = null;
454                if (inherited != null)
455                {
456                  if (lastModified == null)
457                  {
458                    lastModified = inherited.getThisLastUpdate();
459                  }
460                  try
461                  {
462                    inheritedFrom = inherited.getThisItem(dc);
463                  }
464                  catch (Throwable t)
465                  {}
466                }
467               
468                String icon = at != null && at.isProtocolParameter() ? 
469                    "parameter.png" : "annotation.png";
470                boolean editPermission = annotatable.hasPermission(Permission.WRITE);
471                %>
472                <tbl:row>
473                  <tbl:cell column="annotation"><base:icon image="<%=icon%>" />
474                    <%=Base.getLinkedName(ID, at, false, true)%>
475                  </tbl:cell>
476                  <tbl:cell column="values">
477                    <%=Values.getString(values, ", ", true, formatter)%>
478                    <base:icon id="<%=Integer.toString(snapshot.getThisAnnotationId())%>" 
479                      image="<%=isUpToDate ? "edit.png" : "edit-outofsync.png"%>" 
480                      subclass="edit-annotation auto-init" 
481                      data-auto-init="edit-annotation"
482                      data-item-type="<%=annotatable.getType().name()%>" 
483                      data-item-id="<%=annotatable.getId()%>" 
484                      data-annotation-type-id="<%=at.getId()%>"
485                      data-annotation-id="<%=snapshot.getThisAnnotationId()%>"
486                      tooltip="Edit this annotation" visible="<%=editPermission %>"/>
487                  </tbl:cell>
488                  <tbl:cell column="item">
489                    <%
490                    if (inheritedFrom != null)
491                    {
492                      String ownerName = inheritedFrom instanceof Nameable ?
493                          ((Nameable)inheritedFrom).getName() : inheritedFrom.toString();
494                      %>
495                      <%=Base.getLink(ID, ownerName, inheritedFrom.getType(), inheritedFrom.getId(), inheritedFrom.hasPermission(Permission.WRITE)) %>
496                      <%
497                    }
498                    else if (snapshot.getSource() == Annotation.Source.CLONED)
499                    {
500                      %>
501                      <i>- missing -</i>
502                      <%
503                    }
504                    %>
505                  </tbl:cell>
506                  <tbl:cell column="note"><%=snapshot.getSource() == Annotation.Source.CLONED ? "Cloned" + (isUpToDate ? "; up-to-date" : "; modified") : "" %></tbl:cell>
507                  <tbl:cell column="lastModified" value="<%=lastModified %>" />
508                </tbl:row>
509                <%
510              }
511              %>
512            </tbl:rows>
513          </tbl:data>       
514        </tbl:table>
515        </base:section>
516        <%
517      }     
518      if (showFailures)
519      {
520        %>
521        <base:section
522          id="failures"
523          title="<%="Failure details (" + (node.getNumErrors() + node.getNumWarnings()) + ")"%>"
524          context="<%=cc %>"
525          >
526        <table>
527        <%
528        int numFailures = 0;
529        for (Failure failure : failures)
530        {
531          ValidationRuleAction validator = failure.getValidator();
532          Severity severity = options.getSeverity(validator);
533          if (failure.getNode() == node && severity != Severity.IGNORE)
534          {
535            numFailures++;
536            List<Fix> fixes = failure.getFixes();
537            %>
538            <tr>
539              <td><base:icon image="<%=severity == Severity.ERROR ? "error.png" : "warning.png"%>" style="padding-right: 4px;"/></td>
540              <td><b><%=HTML.encodeTags(failure.getMessage())%></b></td>
541            </tr>
542            <tr>
543              <td></td>
544              <td style="padding-bottom: 0.3em;">
545                <%=HTML.encodeTags(validator.getDescription())%><br>
546                <%
547                if (fixes != null && fixes.size() > 0)
548                {
549                  for (Fix fix : fixes)
550                  {
551                    if (fix == null) continue;
552                    BasicItem fixItem = fix.getItem();
553                    boolean enabled = fixItem.hasPermission(Permission.WRITE);
554                    AnnotationType at = fix.getAnnotationType();
555                    Annotation a = fix.getAnnotation();
556                    String autoInit = "";
557                    if (enabled)
558                    {
559                      if (fix.isAnnotationFix())
560                      {
561                        autoInit = "edit-annotation";
562                      }
563                      else if (fix.isDataFileFix())
564                      {
565                        autoInit = "edit-data-file";
566                      }
567                      else
568                      {
569                        autoInit = "edit-item";
570                      }
571                    }
572                    %>
573                    <base:icon image="fixit.png" 
574                      style="padding-bottom: 4px;" 
575                      id="<%=Integer.toString(fix.hashCode())%>"
576                      enabled="<%=enabled %>"
577                      subclass="auto-init"
578                      data-auto-init="<%=autoInit%>"
579                      data-item-type="<%=fixItem.getType().name()%>"
580                      data-item-id="<%=fixItem.getId()%>"
581                      data-annotation-type-id="<%=at != null ? at.getId() : ""%>"
582                      data-annotation-id="<%=a != null ? a.getId() : "" %>"
583                      tooltip="<%=enabled ? "Edit this item to fix the problem" : "You do not have permission to modify this item" %>"
584                    ><%=HTML.encodeTags(fix.getMessage())%></base:icon><br>
585                    <%
586                  }
587                }
588                %>
589              </td>
590            </tr>
591            <%
592          }
593        }
594        %>
595        </table>
596        <%
597        if (numFailures == 0)
598        {
599          %>
600          <div class="messagecontainer note">
601          No validation failures on this item
602          </div>
603          <%
604        }
605        %>
606        </base:section>
607        <%
608      }
609     
610      for (SectionAction section : invoker)
611      {
612        %>
613        <base:section 
614          id="<%=section.getId() %>" 
615          showclazz="<%=section.getShowClazz() %>"
616          hideclazz="<%=section.getHideClazz() %>"
617          style="<%=section.getStyle() %>"
618          contentstyle="<%=section.getContentStyle() %>"
619          title="<%=section.getTitle() %>"
620          context="<%=cc %>"
621          ><%=section.getContent() %></base:section>
622        <%
623      }
624      %>
625      </div>
626    </base:body>
627  </base:page>
628  <%
629}
630finally
631{
632  if (dc != null) dc.close();
633}
634%>
Note: See TracBrowser for help on using the repository browser.