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

Last change on this file since 3675 was 3675, checked in by Jari Häkkinen, 14 years ago

Fixing copyright statements. Fixing svn properties.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 15.7 KB
Line 
1<%-- $Id: expression_builder.jsp 3675 2007-08-16 14:16:43Z jari $
2  ------------------------------------------------------------------
3  Copyright (C) 2006, 2007 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        var expression = frm.expression.value.replace('if(', 'jepIf(');
196        try
197        {
198          var result = eval(expression);
199          alert('The expressions seems to be ok.\nNote! This feature is experimental and may not be 100% correct.');
200        }
201        catch (er)
202        {
203          alert(er + '\nNote! This feature is experimental and may not be 100% correct.');
204        }
205      }
206    }
207   
208    function raw(property)
209    {
210      <%
211      if (maxRawMappings != 1)
212      {
213        %>
214        throw 'Cannot use function raw() for bioassayset that has multiple mappings to raw data';
215        <%
216      }
217      %>
218      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
219      if (!property) throw 'Property must be specified for function raw()';
220      if (rdt == '') throw 'Cannot use function raw(). No raw data type selected';
221      if (!properties['raw.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
222      return Math.random() * 100;
223    }
224   
225    function mean(property)
226    {
227      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
228      if (!property) throw 'Property must be specified for function mean()';
229      if (rdt == '') throw 'Cannot use function mean(). No raw data type selected';
230      if (!properties['property.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
231      return Math.random() * 100;
232    }
233 
234    function ch(channel)
235    {
236      var type = '<%=formulaType.name()%>';
237      if (type == '<%=Formula.Type.INTENSITY_EXPRESSION.name()%>')
238      {
239        // Channel function not available
240        throw 'Function ch() is not available for ' + type;
241      }
242 
243      var channels = <%=channels%>;
244      if (!channel || channel <= 0 || channel > channels) throw 'Invalid channel: ' + channel + '; must be between 1 and '+ channels;
245      return channel;
246    }
247   
248    function rep(property)
249    {
250      if (!property) throw 'Property must be specified for function rep()';
251      if (!properties['reporter.'+property]) throw 'Property '+property+' not found for reporter';
252      return Math.random() * 100;
253    }
254   
255    function xtra(arg)
256    {
257      if (!arg) throw 'One argument is required for function xtra()';
258      return Math.random() * 100;
259    }
260   
261    function log(value)
262    {
263      return Math.log(value);
264    }
265    function log2(value)
266    {
267      return Math.log(value);
268    }
269    function ln(value)
270    {
271      return Math.log(value);
272    }
273    function sqrt(value)
274    {
275      return Math.sqrt(value);
276    }
277    function abs(value)
278    {
279      return Math.abs(value);
280    }
281    function exp(value)
282    {
283      return Math.exp(value);
284    }
285    function score(reporterListId)
286    {
287      return Math.random() * 100;
288    }
289    function jepIf(condition, ifTrue, ifFalse)
290    {
291      if (condition == undefined || ifTrue == undefined || ifFalse == undefined)
292      {
293        throw 'if() needs 3 arguments';
294      }
295      return condition ? ifTrue : ifFalse;
296    }
297    </script>
298  </base:head>
299  <base:body onload="getText()">
300 
301    <form name="expression" onsubmit="return false;">
302 
303        <h3 class="docked">Expression builder <base:help helpid="expressionbuilder" /></h3>
304       
305        <tbl:toolbar>
306          <tbl:label
307            style="width: 100px;"
308            title="Operators:"
309          />
310          <tbl:button 
311            title="AND"
312            tooltip="BOOLEAN AND: expr1 &amp;&amp; expr2"
313            onclick="encloseSelection(' &amp;&amp; ', '')"
314          />
315          <tbl:button 
316            title="OR"
317            tooltip="BOOLEAN OR: expr1 || expr2"
318            onclick="encloseSelection(' || ', '')"
319          />
320          <tbl:button 
321            title="NOT"
322            tooltip="BOOLEAN NOT: !expr1"
323            onclick="encloseSelection('!', '')"
324          />
325          <tbl:button 
326            title="=="
327            tooltip="EQUAL: expr1 == expr2"
328            onclick="encloseSelection(' == ', '')"
329          />
330          <tbl:button 
331            title="!="
332            tooltip="INEQUAL: expr1 != expr2"
333            onclick="encloseSelection(' != ', '')"
334          />
335          <tbl:button 
336            title="&lt;"
337            tooltip="LESS: expr1 &lt; expr2"
338            onclick="encloseSelection(' &lt; ', '')"
339          />
340          <tbl:button 
341            title="&lt;="
342            tooltip="LESS OR EQUAL: expr1 &lt;= expr2"
343            onclick="encloseSelection(' &lt;= ', '')"
344          />
345          <tbl:button 
346            title="&gt;="
347            tooltip="MORE OR EQUAL: expr1 &gt;= expr2"
348            onclick="encloseSelection(' &gt;= ', '')"
349            visible="<%=restrictions%>"
350          />
351          <tbl:button 
352            title="&gt;"
353            tooltip="MORE: expr1 &gt; expr2"
354            onclick="encloseSelection(' &gt; ', '')"
355          />
356          <tbl:button 
357            title="+"
358            tooltip="ADD: expr1 + expr2"
359            onclick="encloseSelection(' + ', '')"
360          />
361          <tbl:button 
362            title="-"
363            tooltip="SUBTRACT: expr1 - expr2"
364            onclick="encloseSelection(' - ', '')"
365          />
366          <tbl:button 
367            title="*"
368            tooltip="MULTIPLY: expr1 * expr2"
369            onclick="encloseSelection(' * ', '')"
370          />
371          <tbl:button 
372            title="/"
373            tooltip="DIVIDE: expr1 / expr2"
374            onclick="encloseSelection(' / ', '')"
375          />
376          <tbl:button 
377            title="( )"
378            tooltip="PARENTHESIS: (expr1)"
379            onclick="encloseSelection('(', ')')"
380          />
381        </tbl:toolbar>
382        <tbl:toolbar
383          style="border-top: 0px;"
384          >
385          <tbl:label
386            title="Functions:"
387            style="width: 100px;"
388          />
389          <%
390          Enumeration<String, String> functions = Jep.getFunctions();
391          for (int i = 0; i < functions.size(); ++i)
392          {
393            String function = functions.getKey(i);
394            %>
395            <tbl:button 
396              title="<%=function%>"
397              tooltip="<%=functions.getValue(i)%>"
398              onclick="<%="encloseSelection('" + function +"(', ')')"%>"
399            />
400            <%
401          }
402          %>
403          <tbl:label
404            title="Constants:"
405            style="width: 100px;"
406          />
407          <tbl:button 
408            title="null"
409            tooltip="The null (unknown) value"
410            onclick="<%="encloseSelection('', 'null')"%>"
411          />
412          <tbl:button 
413            title="pi"
414            tooltip="<%="The pi value: " + Math.PI %>"
415            onclick="<%="encloseSelection('', '"+Math.PI+"')"%>"
416          />
417          <tbl:button 
418            title="e"
419            tooltip="<%="The base of the natural logarithm: " + Math.E%>"
420            onclick="<%="encloseSelection('', '"+Math.E+"')"%>"
421          />
422        </tbl:toolbar>
423        <tbl:toolbar
424          style="border-top: 0px;">
425          <td class="label">Spot:
426            <select name="spot" onchange="insertSelected(this)" >
427            <option value="">- select -
428            <%
429            for (TableColumn tc : spotProperties)
430            {
431              if (tc.getJepExpression() != null)
432              {
433                %>
434                <option value="<%=tc.getJepExpression()%>" 
435                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
436                <%
437              }
438            }
439            %>
440            </select>   
441          </td>
442          <%
443          if (rawDataType != null && rawDataType.isStoredInDb() && rawProperties.size() > 0)
444          {
445            %>
446            <td class="label">Raw data:
447              <select name="rawdata" onchange="insertSelected(this)" >
448              <option value="">- select -
449              <%
450              for (TableColumn tc : rawProperties)
451              {
452                %>
453                <option value="<%=tc.getJepExpression()%>" 
454                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
455                <%
456              }
457              %>
458              </select>
459            </td>
460            <%
461          }
462          %>
463         
464          <td class="label">Reporter:
465            <select name="reporter" onchange="insertSelected(this)">
466            <option value="">- select -
467              <%
468              for (TableColumn tc : reporterProperties)
469              {
470                %>
471                <option value="<%=tc.getJepExpression()%>" 
472                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
473                <%
474              }
475              %>
476            </select>
477        </tbl:toolbar>
478        <tbl:toolbar
479          style="border-top: 0px;"
480          visible="<%=reporterLists.size() > 0%>">
481          <td class="label">
482            Reporter lists:
483           
484            <select name="listFunction" >
485            <option value="score">score
486            <%
487            if (restrictions)
488            {
489              %>
490              <option value="inList">in
491              <option value="notInList">not in
492              <%
493            }
494            %>
495            </select>
496           
497            <select name="reporterList" onchange="insertReporterListFunction()">
498            <option value="">- select -
499              <%
500              for (ReporterList list : reporterLists)
501              {
502                %>
503                <option value="<%=list.getId()%>" 
504                  title="<%=HTML.encodeTags(list.getDescription())%>"><%=HTML.encodeTags(list.getName())%>
505                <%
506              }
507              %>
508            </select>
509          </td>
510        </tbl:toolbar>
511        <br>
512        <b>Expression</b><br>
513        <textarea name="expression" rows="16" cols="80" wrap="soft" style="width: 100%;"></textarea>
514
515        <br><br>
516        <table align="center">
517        <tr>
518          <td width="33%"><base:button 
519            onclick="validateOnClick()" title="Validate&hellip;" 
520            image="validate_formula.gif"
521            tooltip="Validate the expression. EXPERIMENTAL!!" /></td>
522          <td width="33%"><base:button onclick="setExpressionAndClose()" title="Ok" /></td>
523          <td width="33%"><base:button onclick="window.close()" title="Cancel" /></td>
524         
525        </tr>
526        </table>
527 
528    </form>
529  </base:body>
530  </base:page>
531  <%
532  }
533finally
534{
535  if (dc != null) dc.close();
536}
537%> 
Note: See TracBrowser for help on using the repository browser.