source: trunk/www/views/jobs/view_job.jsp @ 5924

Last change on this file since 5924 was 5924, checked in by Nicklas Nordborg, 10 years ago

References #1655: GUI improvements

Plot functions for spot data and in experiment explorer.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 21.0 KB
Line 
1<%-- $Id: view_job.jsp 5924 2012-01-13 13:10:52Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Gregory Vincic
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  @author Nicklas
25  @version 2.0
26--%>
27<%@ page pageEncoding="UTF-8" session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.SystemItems"
31  import="net.sf.basedb.core.Item"
32  import="net.sf.basedb.core.ItemContext"
33  import="net.sf.basedb.core.Permission"
34  import="net.sf.basedb.core.Job"
35  import="net.sf.basedb.core.JobAgent"
36  import="net.sf.basedb.core.BasicItem"
37  import="net.sf.basedb.core.Nameable"
38  import="net.sf.basedb.core.File"
39  import="net.sf.basedb.core.Path"
40  import="net.sf.basedb.core.User"
41  import="net.sf.basedb.core.ChangeHistory"
42  import="net.sf.basedb.core.ItemResultIterator"
43  import="net.sf.basedb.core.ItemQuery"
44  import="net.sf.basedb.core.ItemResultList" 
45  import="net.sf.basedb.core.PermissionDeniedException"
46  import="net.sf.basedb.core.PluginDefinition"
47  import="net.sf.basedb.core.PluginConfiguration"
48  import="net.sf.basedb.core.PluginType"
49  import="net.sf.basedb.core.ParameterInfo"
50  import="net.sf.basedb.core.query.Orders"
51  import="net.sf.basedb.core.query.Hql"
52  import="net.sf.basedb.core.plugin.GuiContext"
53  import="net.sf.basedb.core.plugin.NonRestartable"
54  import="net.sf.basedb.core.plugin.Plugin"
55  import="net.sf.basedb.core.signal.SignalTransporter"
56  import="net.sf.basedb.core.signal.Signal"
57  import="net.sf.basedb.plugins.util.Parameters"
58  import="net.sf.basedb.clients.web.Base"
59  import="net.sf.basedb.clients.web.ChangeHistoryUtil"
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.Date"
65  import="java.util.Map"
66  import="java.util.Set"
67  import="java.util.List"
68  import="java.util.Collections"
69  import="java.util.Collection"
70%>
71<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
72<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
73<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
74<%!
75  private static final Item itemType = Item.JOB;
76  private static final GuiContext guiContext = new GuiContext(itemType, GuiContext.Type.ITEM);
77
78  private String getItemName(BasicItem item)
79  {
80    String itemName = "";
81    if (item instanceof File)
82    {
83      itemName = ((File)item).getPath().toString();
84    }
85    else if (item instanceof Nameable)
86    {
87      itemName = ((Nameable)item).getName();
88    }
89    else
90    {
91      itemName = item.toString();
92    }
93    return itemName;
94  }
95%>
96<%
97final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
98final String ID = sc.getId();
99final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
100final int itemId = cc.getId();
101final String tab = Values.getString(request.getParameter("tab"), "properties");
102final float scale = Base.getScale(sc);
103final DbControl dc = sc.newDbControl();
104try
105{
106  Job job = Job.getById(dc, itemId);
107  String title = "View job -- " + HTML.encodeTags(job.getName());
108 
109  final boolean writePermission = job.hasPermission(Permission.WRITE);
110  final boolean deletePermission = job.hasPermission(Permission.DELETE);
111  final boolean isRemoved = job.isRemoved();
112  final boolean isUsed = isRemoved && job.isUsed();
113  final boolean deletePermanentlyPermission = deletePermission && !isUsed;
114 
115  boolean readCurrentConfig = true;
116  PluginConfiguration currentConfig = null;
117  try
118  {
119    currentConfig = job.getPluginConfiguration();
120  }
121  catch (PermissionDeniedException ex)
122  {
123    readCurrentConfig = false;
124  }
125  boolean readAgent = true;
126  JobAgent agent = null;
127  try
128  {
129    agent = job.getJobAgent();
130  }
131  catch (PermissionDeniedException ex)
132  {
133    readAgent = false;
134  }
135
136  int parameterVersion = job.getParameterVersion();
137  int latestParameterVersion = currentConfig == null ? parameterVersion : currentConfig.getParameterVersion();
138
139  final Job.Status status = job.getStatus();
140  final boolean autoUpdate = status == Job.Status.WAITING || 
141    status == Job.Status.PREPARED || status == Job.Status.EXECUTING || status == Job.Status.ABORTING;
142  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
143  Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
144  Set<String> jobParameters = job.getParameterNames();
145  File logFile = null;
146  if (!autoUpdate && jobParameters != null && jobParameters.contains(Parameters.LOGFILE_PARAMETER))
147  {
148    try
149    {
150      Object temp = job.getParameterValue(Parameters.LOGFILE_PARAMETER);
151      if (temp instanceof File)
152      {
153        logFile = (File)temp;
154      }
155      else if (temp instanceof String)
156      {
157        logFile = File.getByPath(dc, new Path((String)temp, Path.Type.FILE), false);
158      }
159    }
160    catch (Throwable t)
161    {}
162  }
163 
164  // Check if the plug-in supports the "Abort" signal
165  boolean supportsAbort = status == Job.Status.WAITING && writePermission;
166  if (status == Job.Status.EXECUTING && writePermission)
167  {
168    try
169    {
170      SignalTransporter signalTransporter = job.getSignalTransporter();
171      Collection<Signal> supportedSignals = signalTransporter != null ? 
172        signalTransporter.getSupportedSignals() : null;
173      supportsAbort = signalTransporter != null && 
174        (supportedSignals == null || supportedSignals.contains(Signal.ABORT));
175    }
176    catch (Exception ex)
177    {}
178  }
179  %>
180  <base:page type="popup" title="<%=title%>"> 
181  <base:head scripts="tabcontrol.js,table.js,ajax.js,json2.js" styles="tabcontrol.css,progressbar.css,table.css">
182  <script language="JavaScript">
183  function autoUpdate()
184  {
185    var autoUpdate = <%=autoUpdate ? "true" : "false"%>;
186    if (autoUpdate) sendProgressUpdateRequest();
187  }
188  function abortJob()
189  {
190    if (confirm('Are you sure? This action may not be undone'))
191    {
192      location.href = 'index.jsp?ID=<%=ID%>&cmd=AbortJob&item_id=<%=itemId%>';
193    }
194  }
195  function restartJob(clearDryRun)
196  {
197    var parameterVersion = <%=parameterVersion%>;
198    var latestVersion = <%=latestParameterVersion%>;
199    var useLatestConfiguration = 0;
200    if (parameterVersion != latestVersion)
201    {
202      var msg = 'The configuration parameters for the plugin has changed since\n';
203      msg += 'the job was added to the job queue. Do you want to use the new\n';
204      msg += 'configuration parameters?\n\n';
205      msg += 'Ok / Yes = Use the new parameters (version = '+latestVersion + ')\n';
206      msg += 'Cancel / No = Use the current parameters (version = ' + parameterVersion + ')';
207      if (confirm(msg)) useLatestConfiguration = 1;
208    }
209    var url = 'index.jsp?ID=<%=ID%>&cmd=RestartJob&item_id=<%=itemId%>';
210    url += '&useLatestConfiguration='+useLatestConfiguration;
211    if (clearDryRun) url += '&clearDryRun=' + clearDryRun;
212    location.href = url;
213  }
214  function reconfigureJob()
215  {
216    location.href = '../../common/plugin/index.jsp?ID=<%=ID%>&cmd=ConfigureJob&job_id=<%=itemId%>';
217  }
218 
219    function deleteItemPermanently()
220    {
221      Main.deleteItemPermanently('<%=ID%>', true, '<%=itemType.name()%>', <%=itemId%>, '&callback=itemDeleted');
222    }
223    function itemDeleted()
224    {
225      location.href = getRoot() + 'common/close_popup.jsp?ID=<%=ID%>&refresh_opener=1&wait=0';
226    }
227    function showUsingItems()
228    {
229      Main.showUsingItems('<%=ID%>', '<%=itemType.name()%>', <%=itemId%>);
230    }
231   
232    var lastStatus = '<%=status.name()%>';
233    function sendProgressUpdateRequest()
234    {
235      var request = Ajax.getXmlHttpRequest();
236      var url = 'ajax.jsp?ID=<%=ID%>&cmd=GetProgress&item_id=<%=itemId%>&'+Math.random();
237      request.open("GET", url, true);
238      Ajax.setReadyStateHandler(request, progressUpdateCallback);
239      request.send(null);
240    }
241    function progressUpdateCallback(request)
242    {
243      var progress = Ajax.parseJsonResponse(request.responseText);
244      if (progress && progress.status == 'ok')
245      {
246        var status = progress.jobStatus;
247        var message = progress.message;
248        var percentComplete = progress.percentComplete;
249        var runningTime = progress.runningTime;
250       
251        if (lastStatus != status) location.reload();
252        if (status == 'EXECUTING')
253        {
254          displayProgress(percentComplete, message, runningTime);
255        }
256      }
257      setTimeout('sendProgressUpdateRequest()', 1500);
258    }
259
260    function displayProgress(percentDone, message, runningTime)
261    {
262      // Percent complete
263      var doneElement = document.getElementById('percentDone');
264      var remainElement = document.getElementById('percentRemain');
265      var unknownElement = document.getElementById('percentUnknown');
266      if (percentDone == -1)
267      {
268        Main.hide('percentDone');
269        Main.hide('percentRemain');
270        Main.show('percentUnknown');
271        Main.hide('percentText');
272      }
273      else
274      {
275        Main.hide('percentUnknown');
276        Main.show('percentText');
277        document.getElementById('percentText').innerHTML = percentDone+'%';
278        doneElement.style.width = percentDone+'%';
279        remainElement.style.width = (100-percentDone)+'%';
280        Main.showHide('percentDone', percentDone > 0);
281        Main.showHide('percentRemain', percentDone < 100);
282      }
283
284      // Message
285      document.getElementById('message').innerHTML = message;
286
287      // Running time
288      document.getElementById('runningTime').innerHTML = runningTime;
289    }
290  </script>
291  </base:head>
292  <base:body onload="autoUpdate()">
293    <h1><%=title%> <base:help tabcontrol="main" /></h1>
294    <t:tabcontrol id="main" 
295      subclass="content dialogtabcontrol"
296      active="<%=tab%>" position="bottom">
297    <t:tab id="properties" title="Properties" helpid="job.view.properties">
298      <table class="fullform outlined">
299      <%
300      if (isRemoved)
301      {
302        %>
303        <tr>
304          <td colspan="2" style="background: #E8E8E8; border-bottom: 1px solid #A0A0A0;">
305          <div class="itemstatus">
306            <base:icon 
307              image="<%=deletePermanentlyPermission ? "deleted.gif" : "deleted_disabled.gif"%>"
308              onclick="<%=deletePermanentlyPermission ? "deleteItemPermanently()" : null%>"
309              tooltip="<%=deletePermanentlyPermission ? "Permanently delete this item" : null%>"
310              visible="<%=isRemoved%>"> This item has been flagged for deletion<br></base:icon>
311            <base:icon image="used.gif" 
312              onclick="showUsingItems()"
313              tooltip="Show the items that are using this one"
314              visible="<%=isUsed%>"> This item is used by other items and can't be permanently deleted<br></base:icon>
315          </div>
316          </td>
317        </tr>
318        <%
319      }
320      %>
321      <tr>
322        <th style="border-top: 0px;">Name</th>
323        <td><%=HTML.encodeTags(job.getName())%></td>
324      </tr>
325      <tr>
326        <th>Plugin</th>
327        <td>
328          <base:propertyvalue item="<%=job%>" property="pluginDefinition.name" /> 
329          <%=job.getPluginVersion() == null ?
330            "" : "(version " + HTML.encodeTags(job.getPluginVersion()) + ")"%>
331        </td>
332      </tr>
333      <%
334      if (currentConfig != null)
335      {
336        %>
337        <tr>
338          <th class="subprompt">- configuration</th>
339          <td>
340            <base:propertyvalue item="<%=job%>" property="pluginConfiguration.name" />
341          </td>
342        </tr>
343        <%
344      }
345      %>
346      <tr>
347        <th>User</th>
348        <td>
349          <base:propertyvalue item="<%=job%>" property="owner.name" />
350        </td>
351      </tr>
352      <tr>
353        <th>Experiment</th>
354        <td>
355          <base:propertyvalue item="<%=job%>" property="experiment.name" />
356        </td>
357      </tr>
358      <tr>
359        <th>Status</th>
360        <td>
361          <div class="<%=job.getStatus() == Job.Status.ERROR ? "error messagecontainer" : ""%>" style="margin: 1px 0px;">
362          <%=job.getStatus()%><%=job.isDryRun() ? " (dry-run)" : "" %>:
363          <span id="message" ><%=HTML.niceFormat(job.getStatusMessage())%></span>
364          </div>
365        </td>
366      </tr>
367      <tr>
368        <th class="subprompt">- percent complete</th>
369        <td>
370          <table class="progressbar">
371          <tr>
372          <td>
373            <table id="bar" style="width: 200px;">
374            <tr>
375              <%
376              int percent = job.getPercentComplete();
377              %>
378              <td id="percentDone" style="width: <%=percent%>%; <%=percent <= 0 ? "display: none;" : ""%>">&nbsp;</td>
379              <td id="percentRemain" style="width: <%=100-percent%>%; <%=percent == 100 || percent == -1 ? "display: none;" : ""%>">&nbsp;</td>
380              <td id="percentUnknown" width="100%" 
381                style="<%=percent != -1 ? "display: none" : "" %>">unknown</td>
382            </tr>
383            </table>
384          </td>
385          <td id="percentText" 
386            style="<%=percent < 0 ? "display: none;" : "" %>"><%=percent%>%</td>
387            <%
388            if (logFile != null)
389            {
390              %>
391              <td  style="padding-left: 10px;"><base:button image="view.gif" 
392                title="View log&hellip;"
393                onclick="<%="Main.viewFile('" + ID + "', " + logFile.getId() + ")"%>"
394                tooltip="View the log file with detailed information about this job"
395                /></td>
396              <%
397            }
398            %>
399          </tr>
400          </table>
401        </td>
402      </tr>
403      <tr>
404        <th>Description</th>
405        <td><%=HTML.niceFormat(job.getDescription())%></td>
406      </tr>
407      <tr>
408        <th>Created</th>
409        <td>
410          <%=dateTimeFormatter.format(job.getCreated())%>
411        </td>
412      </tr>
413      <tr>
414        <th class="subprompt">- scheduled</th>
415        <td>
416          <%=dateTimeFormatter.format(job.getScheduled())%>
417        </td>
418      </tr>
419      <tr>
420        <th class="subprompt">- priority</th>
421        <td>
422          <%=job.getPriority()%> (1 = highest, 10 = lowest)
423        </td>
424      </tr>
425      <tr>
426        <th>Running time</th>
427        <td id="runningTime">
428          <%
429          Date started = job.getStarted();
430          if (started != null)
431          {
432            Date ended = job.getEnded();
433            if (ended == null) ended = new Date();
434            long runningTime = ended.getTime() - started.getTime();
435            %>
436            <%=Values.formatTime(runningTime / 1000)%>
437            <%
438          }
439          %>
440        </td>
441      </tr>
442      <tr>
443        <th class="subprompt">- started</th>
444        <td>
445          <%=dateTimeFormatter.format(job.getStarted())%>
446        </td>
447      </tr>
448      <tr>
449        <th class="subprompt">- ended</th>
450        <td>
451          <%=dateTimeFormatter.format(job.getEnded())%>
452        </td>
453      </tr>
454      <tr>
455        <th>Server</th>
456        <td>
457          <%=HTML.encodeTags(job.getServer())%>
458        </td>
459      </tr>
460      <tr>
461        <th>Job agent</th>
462        <td><%=Base.getEncodedName(agent, !readAgent)%></td>
463      </tr>
464      <tr class="dynamic">
465        <th></th>
466        <td></td>
467      </tr>
468      </table>
469      </t:tab>
470      <%
471      if (job.getStackTrace() != null)
472      {
473        %>
474        <t:tab id="stacktrace" title="Stack trace" helpid="job.view.stacktrace">
475          <div style="font-family: monospace; padding: 5px;">
476          <%=HTML.niceFormat(job.getStackTrace().replaceAll("\t", "&nbsp;&nbsp;"))%>
477          </div>
478        </t:tab>
479        <%
480      }
481      %>
482      <t:tab id="parameters" title="Parameters" helpid="job.view.parameters">
483        <table class="fullform outlined">
484        <tbody class="sectionheader">
485          <tr>
486            <th colspan="2">Job parameters</th>
487          </tr>
488        </tbody>
489        <tbody>
490        <%
491        List<String> names = new java.util.ArrayList<String>(jobParameters);
492        Collections.sort(names);
493        for (String name : names)
494        {
495          StringBuilder sb = new StringBuilder();
496          String displayValue = "";
497          String description = "";
498          try
499          {
500            ParameterInfo pi = job.getParameterInfo(name);
501            if (pi.getLabel() != null) name = HTML.encodeTags(pi.getLabel());
502            description = HTML.encodeTags(pi.getDescription());
503            List<?> values = pi.getValues();
504            int i = 0;
505            for (Object value : values)
506            {
507              if (value != null)
508              {
509                if (i > 0) sb.append(", ");
510                i++;
511                if (value instanceof BasicItem)
512                {
513                  sb.append(HTML.encodeTags(getItemName((BasicItem)value)));
514                }
515                else if (value instanceof Date)
516                {
517                  sb.append(dateFormatter.format((Date)value));
518                }
519                else
520                {
521                  sb.append(HTML.encodeTags(value.toString()));
522                }
523              }
524            }
525            displayValue = sb.toString();
526          }
527          catch (Throwable ex)
528          {
529            displayValue = "<i>ERROR: "+ex.getMessage()+"</i>";
530          }
531          %>
532          <tr>
533            <th><span title="<%=description%>"><%=name%></span></th>
534            <td>
535              <%=displayValue%>
536            </td>
537          </tr>
538          <%
539        }
540        %>
541        <%
542        if (!readCurrentConfig)
543        {
544          %>
545          </tbody>
546          <tbody class="sectionheader">
547            <tr>
548              <th colspan="2">Plugin configuration parameters</th>
549            </tr>
550          </tbody>
551          <tbody>
552          <tr>
553            <th></th>
554            <td><i>- denied -</i></td>
555          </tr>
556          <%
557        }
558        else if (currentConfig != null)
559        {
560          %>
561          </tbody>
562          <tbody class="sectionheader">
563            <tr>
564              <th colspan="2">Plugin configuration parameters</th>
565            </tr>
566          </tbody>
567          <tbody>
568          <tr>
569            <th><span 
570              title="The version of the parmeters used for this job, current version in paranthesis">Parameter version</span></td>
571            <td><%=parameterVersion%> (<%=latestParameterVersion %>)</th>
572          </tr>
573          <%
574          names = new java.util.ArrayList<String>(currentConfig.getParameterNames(parameterVersion));
575          Collections.sort(names);
576          for (String name : names)
577          {
578            StringBuilder sb = new StringBuilder();
579            String displayValue = "";
580            String description = "";
581            try
582            {
583              ParameterInfo pi = currentConfig.getParameterInfo(name, parameterVersion);
584              if (pi.getLabel() != null) name = HTML.encodeTags(pi.getLabel());
585              description = HTML.encodeTags(pi.getDescription());
586              List<?> values = pi.getValues();
587              int i = 0;
588              for (Object value : values)
589              {
590                if (value != null)
591                {
592                  if (i > 0) sb.append(", ");
593                  i++;
594                  if (value instanceof BasicItem)
595                  {
596                    sb.append(HTML.encodeTags(getItemName((BasicItem)value)));
597                  }
598                  else if (value instanceof Date)
599                  {
600                    sb.append(dateFormatter.format((Date)value));
601                  }
602                  else
603                  {
604                    sb.append(HTML.encodeTags(value.toString()));
605                  }
606                }
607              }
608              displayValue = sb.toString();
609            }
610            catch (Throwable ex)
611            {
612              displayValue = "<i>ERROR: "+ex.getMessage()+"</i>";
613            }
614            %>
615            <tr>
616              <th><span title="<%=description%>"><%=name%></span></th>
617              <td>
618                <%=displayValue%>
619              </td>
620            </tr>
621            <%
622          }
623          %>
624          <%
625        }
626        %>
627        <tr class="dynamic">
628          <th></th>
629          <td></td>
630        </tr>
631        </tbody>
632        </table>
633      </t:tab>
634     
635      <t:tab id="changes" title="Changed items"
636        tooltip="Display a log of all modifications made by this job"
637        visible="<%=!autoUpdate && ChangeHistoryUtil.showChangeHistoryTab(sc) %>">
638        <%
639        ItemQuery<ChangeHistory> query = ChangeHistory.getChangesBy(job);
640        query.order(Orders.asc(Hql.property("id")));
641        ItemResultIterator<ChangeHistory> changes = query.iterate(dc);
642        int numChanges = 0;
643        %>
644        <tbl:table id="history" clazz="itemlist" columns="all">
645          <tbl:columndef id="changeType" title="Change type" />
646          <tbl:columndef id="item" title="Item" />
647          <tbl:columndef id="info" title="Info" />
648         
649          <tbl:data>
650            <tbl:columns>
651            </tbl:columns>
652            <tbl:rows>
653            <%
654            while (changes.hasNext())
655            {
656              numChanges++;
657              ChangeHistory change = changes.next();
658              %>
659              <tbl:row>
660                <tbl:cell column="changeType"><%=change.getChangeType()%> <%=change.getItemType()%></tbl:cell>
661                <tbl:cell column="item"><%=ChangeHistoryUtil.getItem(dc, change, false, false)%></tbl:cell>
662                <tbl:cell column="info"><%=HTML.encodeTags(change.getChangeInfo())%></tbl:cell>
663              </tbl:row>
664              <%
665            }
666            %>
667            </tbl:rows>
668          </tbl:data>
669          <%
670          if (numChanges == 0)
671          {
672            %>
673            <tbl:panel>
674            No log entries found for this job. NOTE! This job may have made
675            other changes that are not recorded by the logging mechanism.
676            </tbl:panel>
677            <%
678          }
679          %>
680        </tbl:table>
681      </t:tab>
682      </t:tabcontrol>
683 
684    <base:buttongroup subclass="dialogbuttons">
685      <%
686      if (supportsAbort)
687      {
688        %>
689        <base:button onclick="abortJob()" title="Abort&hellip;" image="abort.png" />
690        <%
691      }
692      %>
693      <%
694      if (job.getStatus() == Job.Status.ERROR && job.getJobType() == Job.Type.RUN_PLUGIN)
695      {
696        boolean restartable = !job.getPluginDefinition().supports("net.sf.basedb.core.plugin.NonRestartable");       
697        if (restartable)
698        {
699          %>
700          <base:button onclick="restartJob(0)" title="Restart job" 
701            image="refresh.gif" 
702            tooltip="Try to run this job again with the same parameters"
703          />
704          <base:button onclick="reconfigureJob()" title="Re-configure job"
705            image="runplugin.gif"
706            tooltip="Change the parameters for this job and try again"
707            visible="<%=job.hasContext()%>"
708          />
709          <%
710        }
711      }
712      if (job.getStatus() == Job.Status.DONE && job.isDryRun())
713      {
714        %>
715        <base:button onclick="restartJob(1)" title="Really run" 
716          image="refresh.gif" 
717          tooltip="Run this dry-run job for real"
718        />
719        <%
720      }
721      %>
722      <base:button onclick="window.close()" title="Close" />
723    </base:buttongroup>
724  </base:body>
725  </base:page>
726  <%
727}
728finally
729{
730  if (dc != null) dc.close();
731}
732
733%>
Note: See TracBrowser for help on using the repository browser.