source: trunk/www/common/annotations/inherit.jsp @ 6937

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

References #1941: Store experimental factor values as part experiments

Removing the annotation on a parent item will nullify the link from cloned annotations instead of removing the clones.

Other changes are related to fixing various NullPointerExceptions and other problems resulting from having "inherited" annotations without a parent item.

But more work is needed on this since the cloned annotations now end up in a state that is almost impossible to manage via the gui. The "batch inherit annotations" can be used to remove or update cloned annotation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 12.2 KB
Line 
1<%-- $Id: inherit.jsp 6937 2015-08-07 06:34:06Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson
5  Copyright (C) 2007 Nicklas Nordborg
6
7  This file is part of BASE - BioArray Software Environment.
8  Available at http://base.thep.lu.se/
9
10  BASE is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License
12  as published by the Free Software Foundation; either version 3
13  of the License, or (at your option) any later version.
14
15  BASE is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with BASE. If not, see <http://www.gnu.org/licenses/>.
22  ------------------------------------------------------------------
23
24  This page is used to display and modify the attributes of
25  the of a news item
26
27  @author Nicklas
28  @version 2.0
29--%>
30<%@ page pageEncoding="UTF-8" session="false"
31  import="net.sf.basedb.core.SessionControl"
32  import="net.sf.basedb.core.DbControl"
33  import="net.sf.basedb.core.Item"
34  import="net.sf.basedb.core.Type"
35  import="net.sf.basedb.core.BasicItem"
36  import="net.sf.basedb.core.Permission"
37  import="net.sf.basedb.core.Annotatable"
38  import="net.sf.basedb.core.AnnotationSet"
39  import="net.sf.basedb.core.Annotation"
40  import="net.sf.basedb.core.RawBioAssay"
41  import="net.sf.basedb.core.PhysicalBioAssay"
42  import="net.sf.basedb.core.DerivedBioAssay"
43  import="net.sf.basedb.core.Extract"
44  import="net.sf.basedb.core.ItemSubtype"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.Include"
47  import="net.sf.basedb.core.Nameable"
48  import="net.sf.basedb.core.ItemResultList"
49  import="net.sf.basedb.core.AnnotationType"
50  import="net.sf.basedb.core.PermissionDeniedException"
51  import="net.sf.basedb.util.AnnotationUtil"
52  import="net.sf.basedb.core.Subtypable"
53  import="net.sf.basedb.core.query.Orders"
54  import="net.sf.basedb.core.query.Hql"
55  import="net.sf.basedb.core.query.Expressions"
56  import="net.sf.basedb.core.query.Restrictions"
57  import="net.sf.basedb.util.Tree"
58  import="net.sf.basedb.clients.web.Base"
59  import="net.sf.basedb.clients.web.WebException"
60  import="net.sf.basedb.clients.web.util.HTML"
61  import="net.sf.basedb.util.Values"
62  import="net.sf.basedb.util.formatter.Formatter"
63  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
64  import="java.util.List"
65  import="java.util.Set"
66  import="java.util.HashSet"
67  import="java.util.Map"
68  import="java.util.HashMap"
69  import="org.json.simple.JSONArray"
70  import="org.json.simple.JSONObject"
71%>
72<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
73<%!
74private void loadParents(DbControl dc, Set<AnnotationSet> parentAnnotations, Set<Annotatable> parentItems, Annotatable current)
75{
76  Set<Annotatable> parents = AnnotationUtil.getAllAnnotatableParentItems(dc, current, null);
77  for (Annotatable parent : parents)
78  {
79    if (parent != null && parentItems.add(parent))
80    {
81      if (parent.hasPermission(Permission.USE) && parent.isAnnotated())
82      {
83        parentAnnotations.add(parent.getAnnotationSet());
84      }
85    }
86  }
87}
88
89JSONArray generateJoustTree(Set<AnnotationSet> parentAnnotations, Set<AnnotationSet> nonParents, Set<Annotation> inheritedAnnotations)
90{
91  String itemIcon = "Annotatable";
92  String annotationIcon = "Annotation";
93  String parameterIcon = "Parameter";
94  String nonParentIcon = "NonParent";
95  JSONArray json = new JSONArray();
96 
97  for (AnnotationSet as : parentAnnotations)
98  {
99    Annotatable item = null;
100    String itemType = as.getItemType().toString();
101    try
102    {
103      item = as.getItem();
104    }
105    catch (PermissionDeniedException ex)
106    {}
107    if (item instanceof Subtypable)
108    {
109      try
110      {
111        ItemSubtype subtype = ((Subtypable)item).getItemSubtype();
112        if (subtype != null) itemType = subtype.getName();
113      }
114      catch (PermissionDeniedException ex)
115      {}
116    }
117   
118    String icon = nonParents.contains(as) ? nonParentIcon : itemIcon;
119   
120    String joustId = "as-"+as.getId();
121    String input = "<input type=\"checkbox\""+
122      " name=\""+joustId+"\">";
123    String name = item == null ? "<i>- denied -</i>" : 
124      HTML.encodeTags(((Nameable)item).getName()) + " <span class=\"itemsubtype\">(" + itemType + ")</span>";
125   
126    ItemQuery<Annotation> query = as.getAnnotations();
127    query.restrict(Restrictions.eq(Hql.property("annotationType.disableInheritance"), Expressions.bool(false)));
128    List<Annotation> annotations = query.list(as.getDbControl());
129    if (annotations.size() == 0) continue; // With the next AnnotationSet/item
130     
131    JSONObject jsonJoust = newJoustEntry(null, icon, input+name, joustId);
132    jsonJoust.put("isOpen", 1);
133    jsonJoust.put("type", "annotation-set");
134    jsonJoust.put("externalId", as.getId());
135    json.add(jsonJoust);
136
137    SessionControl sc = as.getSessionControl();
138    for (Annotation a : annotations)
139    {
140      Formatter formatter = FormatterFactory.getAnnotationFormatter(sc, a, null);
141      boolean inherited = inheritedAnnotations != null && inheritedAnnotations.contains(a);
142      AnnotationType at = a.getAnnotationType();
143      String annotationName = at.getName();
144      boolean isParameter = at.isProtocolParameter();
145
146      joustId = "a-"+a.getId();
147      String values = Values.getString(a.getValues(null), ", ", true, formatter);
148      name = HTML.encodeTags(annotationName +
149        " [" + Values.trimString(values, 20)+"]");
150      input = "<input type=\"checkbox\""+
151        " name=\""+joustId+"\""+
152        (inherited ? " checked" : "")+
153        ">";
154     
155      JSONObject jsonAnnotation = newJoustEntry(jsonJoust, isParameter ? parameterIcon : annotationIcon, input+name, joustId);
156      jsonAnnotation.put("type", "annotation");
157      jsonAnnotation.put("externalId", a.getId());
158      jsonAnnotation.put("annotationType", HTML.encodeTags(annotationName));
159      jsonAnnotation.put("values", HTML.encodeTags(values));
160      jsonAnnotation.put("inherited", inherited ? 1 : 0);
161      jsonAnnotation.put("modified", 0);
162    }
163  }
164  return json;
165}
166
167JSONObject newJoustEntry(JSONObject jsonParent, String icon, String text, String id)
168{
169  JSONObject jsonJoust = new JSONObject();
170  jsonJoust.put("icon", icon);
171  jsonJoust.put("text", text);
172  jsonJoust.put("id", id);
173  if (jsonParent != null)
174  {
175    JSONArray jsonChildren = (JSONArray)jsonParent.get("children");
176    if (jsonChildren == null)
177    {
178      jsonChildren = new JSONArray();
179      jsonParent.put("children", jsonChildren);
180    }
181    jsonChildren.add(jsonJoust);
182  }
183  return jsonJoust;
184}
185%>
186<%
187final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
188final String ID = sc.getId();
189final float scale = Base.getScale(sc);
190final Item itemType = Item.valueOf(request.getParameter("item_type"));
191final int itemId = Values.getInt(request.getParameter("item_id"));
192final boolean standalone = Values.getBoolean(request.getParameter("standalone"));
193
194final DbControl dc = sc.newDbControl();
195ItemResultList<AnnotationType> annotationTypes = null;
196try
197{
198  final Annotatable item = itemId == 0 ? null : (Annotatable)itemType.getById(dc, itemId);
199  Set<AnnotationSet> parentAnnotations = new java.util.LinkedHashSet<AnnotationSet>();
200  Set<Annotatable> parentItems = new HashSet<Annotatable>();
201  Set<AnnotationSet> nonParents = new HashSet<AnnotationSet>();
202
203  if (item != null)
204  {
205    // Get all annotated parents and their annotation sets
206    loadParents(dc, parentAnnotations, parentItems, item);
207  }
208  if (standalone)
209  {
210    sc.getCurrentContext(itemType).setObject("item", item); 
211  }
212  String title = "Inherit annotations to " + 
213    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() : 
214    (item == null ? " new item" : item.toString())));
215
216  // Parent items may have been submitted by caller
217  String[] parents = request.getParameterValues("parents");
218  // Each parameter is ITEMTYPE:ID:ID:...
219  if (parents != null)
220  {
221    for (String parent : parents)
222    {
223      String[] temp = parent.split(":");
224      Item parentType = Item.valueOf(temp[0]);
225      for (int i = 1; i < temp.length; ++i)
226      {
227        int parentId = Values.getInt(temp[i], -1);
228        if (parentId != -1) 
229        {
230          Annotatable parentItem = (Annotatable)parentType.getById(dc, parentId);
231          if (parentItems.add(parentItem))
232          {
233            // This is a new parent
234            if (parentItem.hasPermission(Permission.USE) && parentItem.isAnnotated()) 
235            {
236              parentAnnotations.add(parentItem.getAnnotationSet());
237            }
238            loadParents(dc, parentAnnotations, parentItems, parentItem);
239          }
240        }
241      }
242    }
243  }
244 
245  // Get the currently inherited annotations
246  final AnnotationSet as = item != null && item.isAnnotated() ? item.getAnnotationSet() : null;
247  Set<Annotation> inheritedAnnotations = null;
248 
249  if (as != null)
250  {
251    ItemQuery<Annotation> inheritedQuery = as.getAnnotations(null);
252    inheritedQuery.restrict(
253        Restrictions.neq(
254          Hql.property("source"), 
255          Expressions.integer(Annotation.Source.PRIMARY.ordinal())
256      ));
257   
258    inheritedQuery.order(Orders.asc(Hql.property("annotationSet")));
259    inheritedQuery.order(Orders.asc(Hql.property("annotationType.name")));
260    inheritedAnnotations = new HashSet<Annotation>();
261    for (Annotation a : inheritedQuery.list(dc))
262    {
263      a = a.getInheritedFrom();
264      if (a != null)
265      {
266        inheritedAnnotations.add(a);
267        AnnotationSet from = a.getAnnotationSet();
268        if (!parentAnnotations.contains(from) && from.hasPermission(Permission.USE))
269        {
270          parentAnnotations.add(from);
271          nonParents.add(from);
272        }
273      }
274    }
275  }
276  JSONArray json = generateJoustTree(parentAnnotations, nonParents, inheritedAnnotations);
277  %>
278  <base:page type="popup" title="Inherit annotations">
279  <base:head  scripts="joust-2.js,~inherit.js" styles="joust-2.css">
280  <style>
281  .selected .itemsubtype
282  {
283    color: #E8E8E8;
284  }
285  </style>
286  </base:head>
287  <base:body>
288    <%
289    if (standalone)
290    {
291      %>
292      <h1><%=title%> <base:help helpid="annotations.inherit" /></h1>
293      <div class="content bottomborder">
294      <%
295    }
296    %>
297  <form name="annotations"> 
298  <div class="absolutefull">
299 
300    <div class="absolutefull bg-filled-100 rightborder" style="width: 28em;">
301   
302      <div class="absolutefull bottomborder" style="height: 2em;">
303      <%
304      if (parentAnnotations.size() > 0) 
305      {
306        %>
307        <table style="width: 100%;">
308        <tr>
309          <td style="padding-left: 4px; padding-right: 4px;"><base:icon image="filter.png"/></td>
310          <td style="width: 100%; padding-top: 1px;">
311            <input type="text" name="quickFilter" id="quickFilter" 
312              class="auto-init" data-auto-init="focus"
313              style="width: calc(100% - 10px);"
314              title="Type to filter annotation types">
315          </td>
316        </table>
317        <%
318      }
319      %>
320      </div>
321      <div class="absolutefull parameterlist" style="top: 2em; bottom: 3em;">
322        <div id="joust" class="joust absolutefull"
323          data-joust-tree="<%=HTML.encodeTags(json.toJSONString()) %>"
324          >
325          <%
326          if (parentAnnotations.size() == 0) 
327          {
328            %>
329            <div class="messagecontainer error" style="margin: 2em;">There are no parent items with annotations.</div>
330            <%
331          }
332          %>
333          <div id="noMatchingFilter" class="messagecontainer error" style="margin: 2em; display: none;">No annotations matches the filter.</div>
334        </div>
335      </div>
336     
337      <div class="absolutefull topborder" style="top: auto; bottom: 0px; height: 3em;">
338        <table style="height: 100%; margin:auto;"><tr><td>
339        <base:icon image="annotation.png" style="vertical-align: text-bottom;"/> = annotation
340        <base:icon image="parameter.png" style="vertical-align: text-bottom;"/> = protocol parameter<br>
341        <base:icon image="item-error.png" style="vertical-align: text-bottom;" /> = not a parent item
342        </td></tr></table>
343      </div>
344   
345    </div>
346   
347    <div class="absolutefull" style="left: 28em; padding: 1em;">
348      <div id="annotationType" style="font-weight: bold;"></div>
349      <div id="annotationValues"></div>
350    </div>
351 
352  </div>
353  </form>
354
355    <%
356    if (standalone)
357    {
358      %>
359      </div>
360      <base:buttongroup subclass="dialogbuttons">
361        <base:button id="btnSave" title="Save" />
362        <base:button id="close" title="Cancel" />
363      </base:buttongroup>
364      <form name="modified" method="post" action="index.jsp?ID=<%=ID%>">
365        <input type="hidden" name="cmd" value="SaveAnnotations">
366        <input type="hidden" name="item_type" value="<%=itemType.name()%>">
367        <input type="hidden" name="item_id" value="<%=itemId%>">
368      </form>
369      <%
370    }
371    %>
372  </base:body>
373  </base:page>
374  <%
375}
376finally
377{
378  if (dc != null) dc.close();
379}
380%>
381
Note: See TracBrowser for help on using the repository browser.