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

Last change on this file since 5705 was 5705, checked in by Nicklas Nordborg, 12 years ago

References #1590: Documentation cleanup

User documentation chapters 7, 8 and 9 except for screenshots.

Re-ordered some properties in the View job dialog.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 20.9 KB
Line 
1<%-- $Id: view_job.jsp 5705 2011-08-22 12:21:49Z 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('percent');
272      }
273      else
274      {
275        Main.hide('percentUnknown');
276        Main.show('percent');
277        document.getElementById('percent').innerHTML = '&nbsp;' + 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    <h3 class="docked"><%=title%> <base:help tabcontrol="main" /></h3>
294    <t:tabcontrol id="main" active="<%=tab%>" position="bottom" contentstyle="<%="height: "+(int)(scale*350)+"px;"%>">
295    <t:tab id="properties" title="Properties" helpid="job.view.properties">
296
297      <%
298      if (job.isRemoved())
299      {
300        %>
301        <div class="itemstatus">
302          <base:icon 
303            image="<%=deletePermanentlyPermission ? "deleted.gif" : "deleted_disabled.gif"%>"
304            onclick="<%=deletePermanentlyPermission ? "deleteItemPermanently()" : null%>"
305            tooltip="<%=deletePermanentlyPermission ? "Permanently delete this item" : null%>"
306            visible="<%=isRemoved%>"> This item has been flagged for deletion<br></base:icon>
307          <base:icon image="used.gif" 
308            onclick="showUsingItems()"
309            tooltip="Show the items that are using this one"
310            visible="<%=isUsed%>"> This item is used by other items and can't be permanently deleted<br></base:icon>
311        </div>
312        <%
313      }
314      %>
315      <table class="form" cellspacing=0>
316      <tr>
317        <td class="prompt">Name</td>
318        <td><%=HTML.encodeTags(job.getName())%></td>
319      </tr>
320      <tr valign="top">
321        <td class="prompt">Plugin</td>
322        <td>
323          <base:propertyvalue item="<%=job%>" property="pluginDefinition.name" /> 
324          <%=job.getPluginVersion() == null ?
325            "" : "(version " + HTML.encodeTags(job.getPluginVersion()) + ")"%>
326        </td>
327      </tr>
328      <%
329      if (currentConfig != null)
330      {
331        %>
332        <tr valign="top">
333          <td class="subprompt">-configuration</td>
334          <td>
335            <base:propertyvalue item="<%=job%>" property="pluginConfiguration.name" />
336          </td>
337        </tr>
338        <%
339      }
340      %>
341      <tr valign="top">
342        <td class="prompt">User</td>
343        <td>
344          <base:propertyvalue item="<%=job%>" property="owner.name" />
345        </td>
346      </tr>
347      <tr valign="top">
348        <td class="prompt">Experiment</td>
349        <td>
350          <base:propertyvalue item="<%=job%>" property="experiment.name" />
351        </td>
352      </tr>
353      <tr>
354        <td class="prompt">Description</td>
355        <td><%=HTML.niceFormat(job.getDescription())%></td>
356      </tr>
357      <tr valign="top">
358        <td class="prompt">Priority</td>
359        <td>
360          <%=job.getPriority()%> (1 = highest, 10 = lowest)
361        </td>
362      </tr>
363      <tr valign="top">
364        <td class="prompt">Status</td>
365        <td <%=job.getStatus() == Job.Status.ERROR ? "class=\"error\" style=\"text-align: left;\"" : "" %>>
366          <%=job.getStatus()%><%=job.isDryRun() ? " (dry-run)" : "" %>:
367          <span id="message"><%=HTML.niceFormat(job.getStatusMessage())%></span>
368        </td>
369      </tr>
370      <tr valign="middle">
371        <td class="prompt">Percent complete</td>
372        <td>
373          <table border=0 cellspacing=0 cellpadding=0>
374          <tr>
375          <td valign="middle" style="max-width: 100px;">
376            <table width="100px" class="progressbar" border=0 cellspacing=0 cellpadding=0>
377            <tr>
378              <%
379              int percent = job.getPercentComplete();
380              %>
381              <td id="percentDone" class="done" width="<%=percent%>%" 
382                style="<%=percent <= 0 ? "display: none;" : ""%>">&nbsp;</td>
383              <td id="percentRemain" class="remain" width="<%=100-percent%>%"
384                style="<%=percent == 100 || percent == -1 ? "display: none;" : ""%>">&nbsp;</td>
385              <td id="percentUnknown" width="100%" class="unknown"
386                style="<%=percent != -1 ? "display: none" : "" %>">unknown</td>
387            </tr>
388            </table>
389          </td>
390          <td id="percent" 
391            style="<%=percent < 0 ? "display: none;" : "" %>">&nbsp;<%=percent%>%</td>
392          <%
393          if (logFile != null)
394          {
395            %>
396            <td valign="middle" style="padding-left: 10px;"><base:button image="view.gif" 
397                title="View log&hellip;"
398                onclick="<%="Main.viewFile('" + ID + "', " + logFile.getId() + ")"%>"
399                tooltip="View the log file with detailed information about this job"
400                /></td>
401              <%
402            }
403            %>
404          </tr>
405          </table>
406        </td>
407      </tr>
408      <tr valign="top">
409        <td class="prompt">Created</td>
410        <td>
411          <%=dateTimeFormatter.format(job.getCreated())%>
412        </td>
413      </tr>
414      <tr valign="top">
415        <td class="prompt">Scheduled</td>
416        <td>
417          <%=dateTimeFormatter.format(job.getScheduled())%>
418        </td>
419      </tr>
420      <tr valign="top">
421        <td class="prompt">Started</td>
422        <td>
423          <%=dateTimeFormatter.format(job.getStarted())%>
424        </td>
425      </tr>
426      <tr valign="top">
427        <td class="prompt">Ended</td>
428        <td>
429          <%=dateTimeFormatter.format(job.getEnded())%>
430        </td>
431      </tr>
432      <tr valign="top">
433        <td class="prompt">Running time</td>
434        <td id="runningTime">
435          <%
436          Date started = job.getStarted();
437          if (started != null)
438          {
439            Date ended = job.getEnded();
440            if (ended == null) ended = new Date();
441            long runningTime = ended.getTime() - started.getTime();
442            %>
443            <%=Values.formatTime(runningTime / 1000)%>
444            <%
445          }
446          %>
447        </td>
448      </tr>
449      <tr valign="top">
450        <td class="prompt">Server</td>
451        <td>
452          <%=HTML.encodeTags(job.getServer())%>
453        </td>
454      </tr>
455      <tr valign="top">
456        <td class="prompt">Job agent</td>
457        <td><%=Base.getEncodedName(agent, !readAgent)%></td>
458      </tr>
459      </table>
460      </t:tab>
461      <%
462      if (job.getStackTrace() != null)
463      {
464        %>
465        <t:tab id="stacktrace" title="Stack trace" helpid="job.view.stacktrace">
466          <div style="font-family: monospace">
467          <%=HTML.niceFormat(job.getStackTrace())%>
468          </div>
469        </t:tab>
470        <%
471      }
472      %>
473 
474      <t:tab id="parameters" title="Parameters" helpid="job.view.parameters">
475        <h4>Job parameters</h4>
476        <table class="form" cellspacing=0>
477        <%
478        List<String> names = new java.util.ArrayList<String>(jobParameters);
479        Collections.sort(names);
480        for (String name : names)
481        {
482          StringBuilder sb = new StringBuilder();
483          String displayValue = "";
484          String description = "";
485          try
486          {
487            ParameterInfo pi = job.getParameterInfo(name);
488            if (pi.getLabel() != null) name = HTML.encodeTags(pi.getLabel());
489            description = HTML.encodeTags(pi.getDescription());
490            List<?> values = pi.getValues();
491            int i = 0;
492            for (Object value : values)
493            {
494              if (value != null)
495              {
496                if (i > 0) sb.append(", ");
497                i++;
498                if (value instanceof BasicItem)
499                {
500                  sb.append(HTML.encodeTags(getItemName((BasicItem)value)));
501                }
502                else if (value instanceof Date)
503                {
504                  sb.append(dateFormatter.format((Date)value));
505                }
506                else
507                {
508                  sb.append(HTML.encodeTags(value.toString()));
509                }
510              }
511            }
512            displayValue = sb.toString();
513          }
514          catch (Throwable ex)
515          {
516            displayValue = "<i>ERROR: "+ex.getMessage()+"</i>";
517          }
518          %>
519          <tr>
520            <td class="prompt"><span title="<%=description%>"><%=name%></span></td>
521            <td>
522              <%=displayValue%>
523            </td>
524          </tr>
525          <%
526        }
527        %>
528        </table>
529
530        <%
531        if (!readCurrentConfig)
532        {
533          %>
534          <h4>Plugin configuration parameters</h4>
535          <i>- denied -</i>
536          <%
537        }
538        else if (currentConfig != null)
539        {
540          %>
541          <h4>Plugin configuration parameters</h4>
542          <table class="form" cellspacing=0>
543          <tr>
544            <td class="prompt"><span 
545              title="The version of the parmeters used for this job, current version in paranthesis">Parameter version</span></td>
546            <td><%=parameterVersion%> (<%=latestParameterVersion %>)</td>
547          </tr>
548          <%
549          names = new java.util.ArrayList<String>(currentConfig.getParameterNames(parameterVersion));
550          Collections.sort(names);
551          for (String name : names)
552          {
553            StringBuilder sb = new StringBuilder();
554            String displayValue = "";
555            String description = "";
556            try
557            {
558              ParameterInfo pi = currentConfig.getParameterInfo(name, parameterVersion);
559              if (pi.getLabel() != null) name = HTML.encodeTags(pi.getLabel());
560              description = HTML.encodeTags(pi.getDescription());
561              List<?> values = pi.getValues();
562              int i = 0;
563              for (Object value : values)
564              {
565                if (value != null)
566                {
567                  if (i > 0) sb.append(", ");
568                  i++;
569                  if (value instanceof BasicItem)
570                  {
571                    sb.append(HTML.encodeTags(getItemName((BasicItem)value)));
572                  }
573                  else if (value instanceof Date)
574                  {
575                    sb.append(dateFormatter.format((Date)value));
576                  }
577                  else
578                  {
579                    sb.append(HTML.encodeTags(value.toString()));
580                  }
581                }
582              }
583              displayValue = sb.toString();
584            }
585            catch (Throwable ex)
586            {
587              displayValue = "<i>ERROR: "+ex.getMessage()+"</i>";
588            }
589            %>
590            <tr>
591              <td class="prompt"><span title="<%=description%>"><%=name%></span></td>
592              <td>
593                <%=displayValue%>
594              </td>
595            </tr>
596            <%
597          }
598          %>
599          </table>
600          <%
601        }
602        %>
603       
604      </t:tab>
605     
606      <t:tab id="changes" title="Changed items"
607        tooltip="Display a log of all modifications made by this job"
608        visible="<%=!autoUpdate && ChangeHistoryUtil.showChangeHistoryTab(sc) %>">
609        <%
610        ItemQuery<ChangeHistory> query = ChangeHistory.getChangesBy(job);
611        query.order(Orders.asc(Hql.property("id")));
612        ItemResultIterator<ChangeHistory> changes = query.iterate(dc);
613        int numChanges = 0;
614        %>
615        <tbl:table id="history" clazz="itemlist" columns="all">
616          <tbl:columndef id="changeType" title="Change type" />
617          <tbl:columndef id="item" title="Item" />
618          <tbl:columndef id="info" title="Info" />
619         
620          <tbl:data>
621            <tbl:columns>
622            </tbl:columns>
623            <tbl:rows>
624            <%
625            while (changes.hasNext())
626            {
627              numChanges++;
628              ChangeHistory change = changes.next();
629              %>
630              <tbl:row>
631                <tbl:cell column="changeType"><%=change.getChangeType()%> <%=change.getItemType()%></tbl:cell>
632                <tbl:cell column="item"><%=ChangeHistoryUtil.getItem(dc, change, false, false)%></tbl:cell>
633                <tbl:cell column="info"><%=HTML.encodeTags(change.getChangeInfo())%></tbl:cell>
634              </tbl:row>
635              <%
636            }
637            %>
638            </tbl:rows>
639          </tbl:data>
640          <%
641          if (numChanges == 0)
642          {
643            %>
644            <tbl:panel>
645            No log entries found for this job. NOTE! This job may have made
646            other changes that are not recorded by the logging mechanism.
647            </tbl:panel>
648            <%
649          }
650          %>
651        </tbl:table>
652       
653      </t:tab>
654     
655      </t:tabcontrol>
656 
657    <base:buttongroup align="center">
658      <%
659      if (supportsAbort)
660      {
661        %>
662        <base:button onclick="abortJob()" title="Abort&hellip;" image="abort.png" />
663        <%
664      }
665      %>
666      <%
667      if (job.getStatus() == Job.Status.ERROR && job.getJobType() == Job.Type.RUN_PLUGIN)
668      {
669        boolean restartable = !job.getPluginDefinition().supports("net.sf.basedb.core.plugin.NonRestartable");       
670        if (restartable)
671        {
672          %>
673          <base:button onclick="restartJob(0)" title="Restart job" 
674            image="refresh.gif" 
675            tooltip="Try to run this job again with the same parameters"
676          />
677          <base:button onclick="reconfigureJob()" title="Re-configure job"
678            image="runplugin.gif"
679            tooltip="Change the parameters for this job and try again"
680            visible="<%=job.hasContext()%>"
681          />
682          <%
683        }
684      }
685      if (job.getStatus() == Job.Status.DONE && job.isDryRun())
686      {
687        %>
688        <base:button onclick="restartJob(1)" title="Really run" 
689          image="refresh.gif" 
690          tooltip="Run this dry-run job for real"
691        />
692        <%
693      }
694      %>
695      <base:button onclick="window.close()" title="Close" />
696    </base:buttongroup>
697  </base:body>
698  </base:page>
699  <%
700}
701finally
702{
703  if (dc != null) dc.close();
704}
705
706%>
Note: See TracBrowser for help on using the repository browser.