source: trunk/www/common/expression_builder.jsp @ 2993

Last change on this file since 2993 was 2993, checked in by Nicklas Nordborg, 17 years ago

Fixes #215: Incorrect use of DynamicSpotQuery? in table view, plot function, filter function, etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 15.1 KB
Line 
1<%-- $Id: expression_builder.jsp 2993 2006-12-01 14:34:35Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 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 modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA. 
22  ------------------------------------------------------------------
23
24  @author Nicklas
25  @version 2.0
26--%>
27<%@ page session="false"
28  import="net.sf.basedb.core.DbControl"
29  import="net.sf.basedb.core.SessionControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.BioAssaySet"
32  import="net.sf.basedb.core.RawDataType"
33  import="net.sf.basedb.core.RawDataTypes"
34  import="net.sf.basedb.core.RawDataProperty"
35  import="net.sf.basedb.core.ExtendedProperty"
36  import="net.sf.basedb.core.ExtendedProperties"
37  import="net.sf.basedb.core.Formula"
38  import="net.sf.basedb.core.ReporterList"
39  import="net.sf.basedb.core.ItemQuery"
40  import="net.sf.basedb.core.Include"
41  import="net.sf.basedb.core.query.Orders"
42  import="net.sf.basedb.core.query.Hql"
43  import="net.sf.basedb.util.Enumeration"
44  import="net.sf.basedb.util.jep.Jep"
45  import="net.sf.basedb.clients.web.Base"
46  import="net.sf.basedb.util.Values"
47  import="net.sf.basedb.clients.web.util.HTML"
48  import="net.sf.basedb.clients.web.DynamicUtil"
49  import="net.sf.basedb.clients.web.taglib.table.TableColumn"
50  import="java.util.List"
51  import="java.util.LinkedList"
52%>
53<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
54<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
55<%
56  String title = request.getParameter("title");
57  String form = request.getParameter("form");
58  String textarea = request.getParameter("textarea");
59  Formula.Type formulaType = Formula.Type.valueOf(request.getParameter("formulatype"));
60  RawDataType rawDataType = RawDataTypes.getRawDataType(request.getParameter("rawdatatype"));
61  int bioAssaySetId = Values.getInt(request.getParameter("bioassayset_id"), -1);
62  boolean restrictions = Values.getBoolean(request.getParameter("restrictions"));
63  int channels = Values.getInt(request.getParameter("channels"));
64  final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
65 
66  DbControl dc = sc.newDbControl();
67  try
68  {
69    BioAssaySet bas = bioAssaySetId == -1 ? null : BioAssaySet.getById(dc, bioAssaySetId);
70    int maxRawMappings = bas == null ? 1 : bas.getMaxRawMappingsForSpot();
71
72    List<TableColumn> spotProperties = new LinkedList<TableColumn>();
73    DynamicUtil.addSpotColumns(spotProperties, dc, channels);
74    List<TableColumn> rawProperties = new LinkedList<TableColumn>();
75    if (rawDataType != null)
76    {
77      DynamicUtil.addFormulaColumns(spotProperties, dc, rawDataType, Formula.Type.COLUMN_EXPRESSION, "", "", maxRawMappings == 1);
78      if (bas != null) DynamicUtil.addExtraColumns(spotProperties, dc, bas, "", "", "[Xtra] ");
79      if (maxRawMappings == 1) DynamicUtil.addRawDataColumns(rawProperties, dc, rawDataType, "", "", "");
80    }
81    List<TableColumn> reporterProperties = new LinkedList<TableColumn>();
82    DynamicUtil.addReporterColumns(reporterProperties, dc, "", "", "");
83   
84    ItemQuery<ReporterList> reporterListQuery = ReporterList.getQuery();
85    reporterListQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
86    reporterListQuery.order(Orders.asc(Hql.property("name")));
87    List<ReporterList> reporterLists = reporterListQuery.list(dc);
88   
89  %>
90  <base:page type="popup" title="<%=title%>">
91  <base:head scripts="table.js" styles="toolbar.css">
92    <script language="JavaScript">
93    function getText()
94    {
95      document.forms['expression'].expression.value = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'].value;
96    }
97    function setExpressionAndClose()
98    {
99      var textElement = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'];
100      var value = document.forms['expression'].expression.value;
101      if (textElement.type == 'text') value = value.replace(/\n/g, '');
102      textElement.value = value;
103      window.close();
104    }
105    function insertSelected(list, prefix, suffix)
106    {
107      var value = list[list.selectedIndex].value;
108      if (value != '')
109      {
110        if (prefix) value = prefix + value;
111        if (!suffix) suffix = '';
112        encloseSelection(value, suffix);
113      }
114      list.selectedIndex = 0;
115    }
116    function insertReporterListFunction()
117    {
118      var frm = document.forms['expression'];
119      var listFunction = frm.listFunction[frm.listFunction.selectedIndex].value;
120      var listId = frm.reporterList[frm.reporterList.selectedIndex].value;
121      encloseSelection(listFunction+'(' + listId + ')', '');
122      frm.reporterList.selectedIndex = 0;
123    }
124 
125    /*
126      Enclose the selected text with prefix and suffix. Code taken
127      from Trac: http://projects.edgewall.com/trac/
128    */
129    function encloseSelection(prefix, suffix)
130    {
131      var frm = document.forms['expression'];
132      var textarea = frm.expression;
133      textarea.focus();
134        var start, end, sel, scrollPos, subst;
135        if (typeof(document["selection"]) != "undefined")
136        {
137          sel = document.selection.createRange().text;
138        }
139        else if (typeof(textarea["setSelectionRange"]) != "undefined")
140        {
141          start = textarea.selectionStart;
142          end = textarea.selectionEnd;
143          scrollPos = textarea.scrollTop;
144          sel = textarea.value.substring(start, end);
145        }
146        if (sel.match(/ $/))
147        {
148          // exclude ending space char, if any
149            sel = sel.substring(0, sel.length - 1);
150            suffix = suffix + " ";
151        }
152        subst = prefix + sel + suffix;
153        if (typeof(document["selection"]) != "undefined")
154        {
155          var range = document.selection.createRange().text = subst;
156          textarea.caretPos -= suffix.length;
157        }
158        else if (typeof(textarea["setSelectionRange"]) != "undefined")
159        {
160          textarea.value = textarea.value.substring(0, start) + subst +
161                           textarea.value.substring(end);
162          if (sel)
163          {
164            textarea.setSelectionRange(start + subst.length, start + subst.length);
165          }
166          else
167          {
168            textarea.setSelectionRange(start + prefix.length, start + prefix.length);
169          }
170          textarea.scrollTop = scrollPos;
171        }
172      }
173   
174    var properties = new Array();
175    <%
176    for (TableColumn tc : rawProperties)
177    {
178      %>
179      properties['raw.<%=tc.getProperty()%>'] = 1;
180      <%
181    }
182    for (TableColumn tc : reporterProperties)
183    {
184      %>
185      properties['reporter.<%=tc.getProperty()%>'] = 1;
186      <%
187    }
188    %>
189     
190    function validateOnClick()
191    {
192      var frm = document.forms['expression'];
193      if (frm.expression.value != '')
194      {
195        try
196        {
197          var result = eval(frm.expression.value);
198          alert('The expressions seems to be ok.\nNote! This feature is experimental and may not be 100% correct.');
199        }
200        catch (er)
201        {
202          alert(er + '\nNote! This feature is experimental and may not be 100% correct.');
203        }
204      }
205    }
206   
207    function raw(property)
208    {
209      <%
210      if (maxRawMappings != 1)
211      {
212        %>
213        throw 'Cannot use function raw() for bioassayset that has multiple mappings to raw data';
214        <%
215      }
216      %>
217      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
218      if (!property) throw 'Property must be specified for function raw()';
219      if (rdt == '') throw 'Cannot use function raw(). No raw data type selected';
220      if (!properties['raw.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
221      return Math.random() * 100;
222    }
223   
224    function mean(property)
225    {
226      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
227      if (!property) throw 'Property must be specified for function mean()';
228      if (rdt == '') throw 'Cannot use function mean(). No raw data type selected';
229      if (!properties['property.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
230      return Math.random() * 100;
231    }
232 
233    function ch(channel)
234    {
235      var type = '<%=formulaType.name()%>';
236      if (type == '<%=Formula.Type.INTENSITY_EXPRESSION.name()%>')
237      {
238        // Channel function not available
239        throw 'Function ch() is not available for ' + type;
240      }
241 
242      var channels = <%=channels%>;
243      if (!channel || channel <= 0 || channel > channels) throw 'Invalid channel: ' + channel + '; must be between 1 and '+ channels;
244      return channel;
245    }
246   
247    function rep(property)
248    {
249      if (!property) throw 'Property must be specified for function rep()';
250      if (!properties['reporter.'+property]) throw 'Property '+property+' not found for reporter';
251      return Math.random() * 100;
252    }
253   
254    function xtra(arg)
255    {
256      if (!arg) throw 'One argument is required for function xtra()';
257      return Math.random() * 100;
258    }
259   
260    function log(value)
261    {
262      return Math.log(value);
263    }
264    function log2(value)
265    {
266      return Math.log(value);
267    }
268    function ln(value)
269    {
270      return Math.log(value);
271    }
272    function sqrt(value)
273    {
274      return Math.sqrt(value);
275    }
276    function abs(value)
277    {
278      return Math.abs(value);
279    }
280    function exp(value)
281    {
282      return Math.exp(value);
283    }
284    function score(reporterListId)
285    {
286      return Math.random() * 100;
287    }
288    </script>
289  </base:head>
290  <base:body onload="getText()">
291 
292    <form name="expression" onsubmit="return false;">
293 
294        <h3 class="docked">Expression builder <base:help helpid="expressionbuilder" /></h3>
295       
296        <tbl:toolbar>
297          <tbl:label
298            style="width: 100px;"
299            title="Operators:"
300          />
301          <tbl:button 
302            title="AND"
303            tooltip="BOOLEAN AND: expr1 &amp;&amp; expr2"
304            onclick="encloseSelection(' &amp;&amp; ', '')"
305            visible="<%=restrictions%>"
306          />
307          <tbl:button 
308            title="OR"
309            tooltip="BOOLEAN OR: expr1 || expr2"
310            onclick="encloseSelection(' || ', '')"
311            visible="<%=restrictions%>"
312          />
313          <tbl:button 
314            title="NOT"
315            tooltip="BOOLEAN NOT: !expr1"
316            onclick="encloseSelection('!', '')"
317            visible="<%=restrictions%>"
318          />
319          <tbl:button 
320            title="=="
321            tooltip="EQUAL: expr1 == expr2"
322            onclick="encloseSelection(' == ', '')"
323            visible="<%=restrictions%>"
324          />
325          <tbl:button 
326            title="!="
327            tooltip="INEQUAL: expr1 != expr2"
328            onclick="encloseSelection(' != ', '')"
329            visible="<%=restrictions%>"
330          />
331          <tbl:button 
332            title="&lt;"
333            tooltip="LESS: expr1 &lt; expr2"
334            onclick="encloseSelection(' &lt; ', '')"
335            visible="<%=restrictions%>"
336          />
337          <tbl:button 
338            title="&lt;="
339            tooltip="LESS OR EQUAL: expr1 &lt;= expr2"
340            onclick="encloseSelection(' &lt;= ', '')"
341            visible="<%=restrictions%>"
342          />
343          <tbl:button 
344            title="&gt;="
345            tooltip="MORE OR EQUAL: expr1 &gt;= expr2"
346            onclick="encloseSelection(' &gt;= ', '')"
347            visible="<%=restrictions%>"
348          />
349          <tbl:button 
350            title="&gt;"
351            tooltip="MORE: expr1 &gt; expr2"
352            onclick="encloseSelection(' &gt; ', '')"
353            visible="<%=restrictions%>"
354          />
355          <tbl:button 
356            title="+"
357            tooltip="ADD: expr1 + expr2"
358            onclick="encloseSelection(' + ', '')"
359          />
360          <tbl:button 
361            title="-"
362            tooltip="SUBTRACT: expr1 - expr2"
363            onclick="encloseSelection(' - ', '')"
364          />
365          <tbl:button 
366            title="*"
367            tooltip="MULTIPLY: expr1 * expr2"
368            onclick="encloseSelection(' * ', '')"
369          />
370          <tbl:button 
371            title="/"
372            tooltip="DIVIDE: expr1 / expr2"
373            onclick="encloseSelection(' / ', '')"
374          />
375          <tbl:button 
376            title="( )"
377            tooltip="PARENTHESIS: (expr1)"
378            onclick="encloseSelection('(', ')')"
379          />
380        </tbl:toolbar>
381        <tbl:toolbar
382          style="border-top: 0px;"
383          >
384          <tbl:label
385            title="Functions:"
386            style="width: 100px;"
387          />
388          <%
389          Enumeration<String, String> functions = Jep.getFunctions();
390          for (int i = 0; i < functions.size(); ++i)
391          {
392            String function = functions.getKey(i);
393            %>
394            <tbl:button 
395              title="<%=function%>"
396              tooltip="<%=functions.getValue(i)%>"
397              onclick="<%="encloseSelection('" + function +"(', ')')"%>"
398            />
399            <%
400          }
401          %>
402        </tbl:toolbar>
403        <tbl:toolbar
404          style="border-top: 0px;">
405          <td class="label">Spot:
406            <select name="spot" onchange="insertSelected(this)" >
407            <option value="">- select -
408            <%
409            for (TableColumn tc : spotProperties)
410            {
411              if (tc.getJepExpression() != null)
412              {
413                %>
414                <option value="<%=tc.getJepExpression()%>" 
415                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
416                <%
417              }
418            }
419            %>
420            </select>   
421          </td>
422          <%
423          if (rawDataType != null && rawDataType.isStoredInDb() && rawProperties.size() > 0)
424          {
425            %>
426            <td class="label">Raw data:
427              <select name="rawdata" onchange="insertSelected(this)" >
428              <option value="">- select -
429              <%
430              for (TableColumn tc : rawProperties)
431              {
432                %>
433                <option value="<%=tc.getJepExpression()%>" 
434                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
435                <%
436              }
437              %>
438              </select>
439            </td>
440            <%
441          }
442          %>
443         
444          <td class="label">Reporter:
445            <select name="reporter" onchange="insertSelected(this)">
446            <option value="">- select -
447              <%
448              for (TableColumn tc : reporterProperties)
449              {
450                %>
451                <option value="<%=tc.getJepExpression()%>" 
452                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
453                <%
454              }
455              %>
456            </select>
457        </tbl:toolbar>
458        <tbl:toolbar
459          style="border-top: 0px;"
460          visible="<%=reporterLists.size() > 0%>">
461          <td class="label">
462            Reporter lists:
463           
464            <select name="listFunction" >
465            <option value="score">score
466            <%
467            if (restrictions)
468            {
469              %>
470              <option value="inList">in
471              <option value="notInList">not in
472              <%
473            }
474            %>
475            </select>
476           
477            <select name="reporterList" onchange="insertReporterListFunction()">
478            <option value="">- select -
479              <%
480              for (ReporterList list : reporterLists)
481              {
482                %>
483                <option value="<%=list.getId()%>" 
484                  title="<%=HTML.encodeTags(list.getDescription())%>"><%=HTML.encodeTags(list.getName())%>
485                <%
486              }
487              %>
488            </select>
489          </td>
490        </tbl:toolbar>
491        <br>
492        <b>Expression</b><br>
493        <textarea name="expression" rows="16" cols="80" wrap="soft" style="width: 100%;"></textarea>
494
495        <br><br>
496        <table align="center">
497        <tr>
498          <td width="33%"><base:button 
499            onclick="validateOnClick()" title="Validate&hellip;" 
500            image="validate_formula.gif"
501            tooltip="Validate the expression. EXPERIMENTAL!!" /></td>
502          <td width="33%"><base:button onclick="setExpressionAndClose()" title="Ok" /></td>
503          <td width="33%"><base:button onclick="window.close()" title="Cancel" /></td>
504         
505        </tr>
506        </table>
507 
508    </form>
509  </base:body>
510  </base:page>
511  <%
512  }
513finally
514{
515  if (dc != null) dc.close();
516}
517%> 
Note: See TracBrowser for help on using the repository browser.