source: trunk/www/admin/plugindefinitions/list_plugins.jsp @ 3452

Last change on this file since 3452 was 3452, checked in by Nicklas Nordborg, 15 years ago

Fixes #558 and #568

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 20.9 KB
Line 
1<%-- $Id: list_plugins.jsp 3452 2007-06-05 11:58:36Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) Authors contributing to this file.
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
9  modify it under the terms of the GNU General Public License
10  as published by the Free Software Foundation; either version 2
11  of the License, or (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU 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,
21  Boston, MA  02111-1307, USA.
22  ------------------------------------------------------------------
23
24  @author Nicklas
25  @version 2.0
26--%>
27<%@ page session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.PluginDefinition"
32  import="net.sf.basedb.core.PluginConfiguration"
33  import="net.sf.basedb.core.ItemQuery"
34  import="net.sf.basedb.core.Include"
35  import="net.sf.basedb.core.Type"
36  import="net.sf.basedb.core.ItemResultIterator"
37  import="net.sf.basedb.core.ItemResultList"
38  import="net.sf.basedb.core.ItemContext"
39  import="net.sf.basedb.core.Permission"
40  import="net.sf.basedb.core.PluginDefinition"
41  import="net.sf.basedb.core.query.Orders"
42  import="net.sf.basedb.core.query.Hql"
43  import="net.sf.basedb.core.query.Expressions"
44  import="net.sf.basedb.core.query.Restrictions"
45  import="net.sf.basedb.core.plugin.GuiContext"
46  import="net.sf.basedb.core.plugin.Plugin"
47  import="net.sf.basedb.util.Enumeration"
48  import="net.sf.basedb.util.JarClassLoader"
49  import="net.sf.basedb.util.ToStringComparator"
50  import="net.sf.basedb.clients.web.Base"
51  import="net.sf.basedb.clients.web.ModeInfo"
52  import="net.sf.basedb.clients.web.PermissionUtil"
53  import="net.sf.basedb.clients.web.util.HTML"
54  import="net.sf.basedb.util.Values"
55  import="java.util.List"
56  import="java.util.Map"
57  import="java.util.Set"
58  import="java.util.EnumSet"
59  import="java.util.TreeSet"
60%>
61<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
62<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
63<%!
64  private static final Item itemType = Item.PLUGINDEFINITION;
65  private static final GuiContext guiContext = new GuiContext(itemType, GuiContext.Type.LIST);
66  private static final Enumeration<String, String> itemTypes = new Enumeration<String, String>();
67  private static final Enumeration<String, String> mainTypes = new Enumeration<String, String>();
68
69  static
70  {
71    Set<Item> temp = new TreeSet<Item>(new ToStringComparator<Item>(false));
72    temp.addAll(EnumSet.complementOf(EnumSet.of(Item.SYSTEM)));
73    for (Item item : temp)
74    {
75      itemTypes.add(Integer.toString(item.getValue()), item.toString());
76    }
77    for (Plugin.MainType v : Plugin.MainType.values())
78    {
79      mainTypes.add(Integer.toString(v.getValue()), v.toString());
80    }
81  }
82%>
83<%
84final SessionControl sc = Base.getExistingSessionControl(pageContext, Permission.DENIED, itemType);
85final String ID = sc.getId();
86final boolean createPermission = sc.hasPermission(Permission.CREATE, itemType);
87final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
88
89final ModeInfo mode = ModeInfo.get(request.getParameter("mode"));
90final String callback = request.getParameter("callback");
91final String title = mode.generateTitle("plugin", "plugins");
92final DbControl dc = sc.newDbControl();
93ItemResultIterator<PluginDefinition> plugins = null;
94try
95{
96  // Query for plugins relatated to the current type
97  final ItemQuery<PluginConfiguration> configQuery = PluginConfiguration.getQuery();
98  configQuery.include(cc.getInclude());
99  configQuery.restrict(Restrictions.eq(Hql.property("pluginDefinition"), Expressions.parameter("plugin")));
100  configQuery.order(Orders.asc(Hql.property("name"))); 
101  final boolean createConfigurationPermission = sc.hasPermission(Permission.CREATE, Item.PLUGINCONFIGURATION); 
102
103  Map<Plugin.MainType, Integer> pluginCount = PluginDefinition.countPlugins(dc, guiContext);
104  try
105  {
106    final ItemQuery<PluginDefinition> query = Base.getConfiguredQuery(cc, true, PluginDefinition.getQuery(), mode);
107    query.join(Hql.leftJoin("guiContexts", "ctx"));
108    query.setDistinct(true);
109    plugins = query.iterate(dc);
110  }
111  catch (Throwable t)
112  {
113    cc.setMessage(t.getMessage());
114  }
115  int numListed = 0;
116  %>
117  <base:page title="<%=title==null ? "Plugins" : title%>" type="<%=mode.getPageType()%>">
118  <base:head scripts="menu.js,table.js" styles="menu.css,table.css">
119    <script language="JavaScript">
120    var submitPage = 'index.jsp';
121    var formId = 'plugins';
122    function newItem()
123    {
124      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', 0, true);
125    }
126    function editItem(itemId)
127    {
128      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', itemId, true);
129    }
130    function viewItem(itemId)
131    {
132      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', itemId, false);
133    }
134    function itemOnClick(evt, itemId)
135    {
136      Table.itemOnClick(formId, evt, itemId, '<%=mode.getName()%>', viewItem, editItem, returnSelected);
137    }
138    function deleteItems()
139    {
140      var frm = document.forms[formId];
141      if (Forms.numChecked(frm) == 0)
142      {
143        alert('Please select at least one item in the list');
144        return;
145      }
146      frm.action = submitPage;
147      frm.cmd.value = 'DeleteItems';
148      frm.submit();
149    }
150    function restoreItems()
151    {
152      var frm = document.forms[formId];
153      if (Forms.numChecked(frm) == 0)
154      {
155        alert('Please select at least one item in the list');
156        return;
157      }
158      frm.action = submitPage;
159      frm.cmd.value = 'RestoreItems';
160      frm.submit();
161    }
162    function takeOwnership()
163    {
164      var frm = document.forms[formId];
165      if (Forms.numChecked(frm) == 0)
166      {
167        alert('Please select at least one item in the list');
168        return;
169      }
170      if (confirm('Are you sure that you want to take ownership of the selected items? It can\'t be undone.'))
171      {
172        frm.action = submitPage;
173        frm.cmd.value = 'TakeOwnershipOfItems';
174        frm.submit();
175      }
176    }
177    function unloadItems()
178    {
179      var frm = document.forms[formId];
180      if (Forms.numChecked(frm) == 0)
181      {
182        alert('Please select at least one item in the list');
183        return;
184      }
185      frm.action = submitPage;
186      frm.cmd.value = 'UnloadItems';
187      frm.submit();
188    }
189    function shareItem(itemId)
190    {
191      Main.openPopup('index.jsp?ID=<%=ID%>&cmd=ShareItem&item_id='+itemId, 'SharePlugins', 500, 400);
192    }
193    function shareItems()
194    {
195      Table.shareItems(submitPage, '<%=ID%>', formId, '<%=itemType.name()%>', 'ShareItems');
196    }
197    function configureColumns()
198    {
199      Table.configureColumns('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>');
200    }
201    function runPlugin(cmd)
202    {
203      Table.submitToPopup(formId, cmd, 740, 540);
204    }
205    function returnSelected()
206    {
207      Table.returnSelected(formId, <%=callback != null ? "window.opener."+callback : "null" %>);
208      window.close();
209    }
210    function presetOnChange()
211    {
212      Table.presetOnChange('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>');
213    }
214    function newConfiguration(pluginId)
215    {
216      Main.viewOrEditItem('<%=ID%>', 'PLUGINCONFIGURATION', 0, true, '&plugindefinition_id='+pluginId);
217    }
218    </script>
219  </base:head>
220 
221  <base:body>
222    <%
223    if (cc.getMessage() != null)
224    {
225      %>
226      <div class="error"><%=cc.getMessage()%></div>
227      <%
228      cc.setMessage(null);
229    }
230    %>
231    <tbl:table 
232      id="plugins" 
233      clazz="itemlist" 
234      columns="<%=cc.getSetting("columns")%>"
235      sortby="<%=cc.getSortProperty()%>" 
236      direction="<%=cc.getSortDirection()%>"
237      title="<%=title%>"
238      action="index.jsp"
239      sc="<%=sc%>"
240      item="<%=itemType%>"
241      >
242      <tbl:hidden 
243        name="mode" 
244        value="<%=mode.getName()%>" 
245      />
246      <tbl:hidden 
247        name="callback" 
248        value="<%=callback%>" 
249        skip="<%=callback == null%>" 
250      />
251      <tbl:columndef 
252        id="name"
253        property="name"
254        datatype="string"
255        title="Name"
256        sortable="true" 
257        filterable="true"
258        exportable="true"
259        show="always" 
260      />
261      <tbl:columndef 
262        id="pluginType"
263        property="mainType"
264        datatype="int"
265        enumeration="<%=mainTypes%>"
266        title="Type"
267        sortable="true" 
268        filterable="true"
269        exportable="true"
270      />
271      <tbl:columndef 
272        id="className"
273        property="className"
274        datatype="string"
275        title="Class"
276        sortable="true" 
277        filterable="true"
278        exportable="true"
279      />
280      <tbl:columndef 
281        id="jarPath"
282        property="jarPath"
283        datatype="string"
284        title="Path"
285        sortable="true" 
286        filterable="true"
287        exportable="true"
288      />
289      <tbl:columndef 
290        id="version"
291        property="versionString"
292        datatype="string"
293        title="Version"
294        sortable="true" 
295        filterable="true"
296        exportable="true"
297      />
298      <tbl:columndef 
299        id="configurations"
300        title="Configurations"
301      />
302      <tbl:columndef 
303        id="contact"
304        property="contact"
305        datatype="string"
306        title="Contact"
307        sortable="true" 
308        filterable="true"
309        exportable="true"
310      />
311      <tbl:columndef 
312        id="copyright"
313        property="copyright"
314        datatype="string"
315        title="Copyright"
316        sortable="true" 
317        filterable="true"
318        exportable="true"
319      />
320      <tbl:columndef 
321        id="email"
322        property="email"
323        datatype="string"
324        title="Email"
325        sortable="true" 
326        filterable="true"
327        exportable="true"
328      />
329      <tbl:columndef 
330        id="url"
331        property="url"
332        datatype="string"
333        title="URL"
334        sortable="true" 
335        filterable="true"
336        exportable="true"
337      />
338      <tbl:columndef 
339        id="interactive"
340        property="interactive"
341        datatype="boolean"
342        title="Is interactive"
343        sortable="true" 
344        filterable="true"
345        exportable="true"
346      />
347      <tbl:columndef 
348        id="supportsConfigurations"
349        property="supportsConfigurations"
350        datatype="boolean"
351        title="Support config"
352        sortable="true" 
353        filterable="true"
354        exportable="true"
355      />
356      <tbl:columndef 
357        id="requiresConfiguration"
358        property="requiresConfiguration"
359        datatype="boolean"
360        title="Requires config"
361        sortable="true" 
362        filterable="true"
363        exportable="true"
364      />
365      <tbl:columndef 
366        id="usePermissions"
367        property="usePermissions"
368        datatype="boolean"
369        title="Uses permissions"
370        sortable="true" 
371        filterable="true"
372        exportable="true"
373      />
374      <tbl:columndef 
375        id="allowImmediateExecution"
376        property="allowImmediateExecution"
377        datatype="boolean"
378        title="Immediate execution"
379        sortable="true" 
380        filterable="true"
381        exportable="true"
382      />
383      <tbl:columndef 
384        id="contexts"
385        property="$ctx.itemType"
386        exportproperty="guiContexts.itemType"
387        datatype="int"
388        enumeration="<%=itemTypes%>"
389        title="Items"
390        sortable="false" 
391        filterable="true"
392        exportable="false"
393      />
394      <tbl:columndef 
395        id="maxMemory"
396        property="maxMemory"
397        datatype="long"
398        title="Max memory"
399        sortable="true" 
400        filterable="true"
401        exportable="true"
402      />
403      <tbl:columndef 
404        id="trusted"
405        property="trusted"
406        datatype="boolean"
407        title="Trusted"
408        sortable="true" 
409        filterable="true"
410        exportable="true"
411      />
412      <tbl:columndef 
413        id="owner"
414        property="owner.name"
415        datatype="string"
416        title="Owner"
417        sortable="true" 
418        filterable="true"
419        exportable="true"
420      />
421      <tbl:columndef 
422        id="description"
423        property="description"
424        datatype="string"
425        title="Description" 
426        sortable="true" 
427        filterable="true" 
428        exportable="true"
429      />
430      <tbl:columndef
431        id="loaded"
432        title="Loaded"
433      />
434      <tbl:columndef
435        id="permission"
436        title="Permission"
437      />
438      <tbl:toolbar
439        visible="<%=mode.hasToolbar()%>"
440        >
441        <tbl:button 
442          disabled="<%=createPermission ? false : true%>" 
443          image="<%=createPermission ? "new.gif" : "new_disabled.gif"%>" 
444          onclick="newItem()" 
445          title="New&hellip;" 
446          tooltip="<%=createPermission ? "Create new plugin" : "You do not have permission to create plugins"%>" 
447        />
448        <tbl:button 
449          image="delete.gif"
450          onclick="deleteItems()" 
451          title="Delete" 
452          tooltip="Delete the selected items" 
453        />
454        <tbl:button 
455          image="restore.gif"
456          onclick="restoreItems()" 
457          title="Restore" 
458          tooltip="Restore the selected (deleted) items"
459        />
460        <tbl:button 
461          image="share.gif"
462          onclick="shareItems()" 
463          title="Share&hellip;" 
464          tooltip="Share the selected items"
465        />
466        <tbl:button 
467          image="take_ownership.png"
468          onclick="takeOwnership()" 
469          title="Take ownership&hellip;"
470          tooltip="Take ownership of the selected items"
471        />
472        <tbl:button 
473          image="columns.gif" 
474          onclick="configureColumns()" 
475          title="Columns&hellip;" 
476          tooltip="Show, hide and re-order columns" 
477        />
478        <tbl:button 
479          image="import.gif" 
480          onclick="runPlugin('ImportItems')" 
481          title="Import&hellip;" 
482          tooltip="Import data" 
483          visible="<%=pluginCount.containsKey(Plugin.MainType.IMPORT)%>"
484        />
485        <tbl:button 
486          image="export.gif" 
487          onclick="runPlugin('ExportItems')" 
488          title="Export&hellip;" 
489          tooltip="Export data" 
490          visible="<%=pluginCount.containsKey(Plugin.MainType.EXPORT)%>"
491        />
492        <tbl:button 
493          image="runplugin.gif" 
494          onclick="runPlugin('RunListPlugin')" 
495          title="Run plugin&hellip;" 
496          tooltip="Run a plugin" 
497          visible="<%=pluginCount.containsKey(Plugin.MainType.OTHER)%>"
498        />
499        <tbl:button 
500          onclick="unloadItems()" 
501          title="Unload" 
502          tooltip="Unload plugins" 
503        />
504        </tbl:toolbar>
505      <tbl:navigator
506        page="<%=cc.getPage()%>" 
507        rowsperpage="<%=cc.getRowsPerPage()%>" 
508        totalrows="<%=plugins == null ? 0 : plugins.getTotalCount()%>" 
509        visible="<%=mode.hasNavigator()%>"
510      />
511      <tbl:data>
512        <tbl:columns>
513        <tbl:presetselector 
514          clazz="columnheader"
515          colspan="3"
516          onchange="presetOnChange()"
517        />
518        </tbl:columns>
519
520        <tr>
521          <tbl:header 
522            clazz="index"
523            >&nbsp;</tbl:header>
524          <tbl:header 
525            clazz="check" 
526            visible="<%=mode.hasCheck()%>"
527            ><base:icon 
528              image="check_uncheck.gif" 
529              tooltip="Check/uncheck all" 
530              onclick="Forms.checkUncheck(document.forms[formId])" style="align: left;"
531            /></tbl:header>
532          <tbl:header 
533            clazz="check" 
534            visible="<%=mode.hasRadio()%>"
535            >&nbsp;</tbl:header>
536          <tbl:header 
537            clazz="icons" 
538            visible="<%=mode.hasIcons()%>"
539            >&nbsp;</tbl:header>
540          <tbl:propertyfilter />
541        </tr>
542         
543          <tbl:rows>
544          <%
545          int index = cc.getPage()*cc.getRowsPerPage();
546          int selectedItemId = cc.getId();
547          Set<GuiContext> contexts = new TreeSet<GuiContext>(new ToStringComparator<GuiContext>(false));
548          if (plugins != null)
549          {
550            while (plugins.hasNext())
551            {
552              PluginDefinition item = plugins.next();
553              int itemId = item.getId();
554              String openSharePopup = "shareItem("+itemId+")";
555              boolean sharePermission = item.hasPermission(Permission.SET_PERMISSION);
556              String name = HTML.encodeTags(item.getName());
557              boolean usePermission = item.hasPermission(Permission.USE);
558              boolean writePermission = item.hasPermission(Permission.WRITE);
559              String tooltip = mode.isSelectionMode() ? 
560                  "Select this item" : "View this item" + (writePermission ? " (use CTRL, ALT or SHIFT to edit)" : "");
561              index++;
562              numListed++;
563              %>
564              <tbl:row>
565                <tbl:header 
566                  clazz="index"
567                  ><%=index%></tbl:header>
568                <tbl:header 
569                  clazz="check" 
570                  visible="<%=mode.hasCheck()%>"
571                  ><input 
572                    type="checkbox" 
573                    name="<%=itemId%>" 
574                    value="<%=itemId%>" 
575                    title="<%=name%>" 
576                    <%=cc.getSelected().contains(itemId) ? "checked" : ""%> 
577                  ></tbl:header>
578                <tbl:header 
579                  clazz="check" 
580                  visible="<%=mode.hasRadio()%>"
581                  ><input 
582                    type="radio" 
583                    name="item_id" 
584                    value="<%=itemId%>" 
585                    title="<%=name%>" 
586                    <%=selectedItemId == itemId ? "checked" : ""%>
587                  ></tbl:header>
588                <tbl:header 
589                  clazz="icons" 
590                  visible="<%=mode.hasIcons()%>"
591                  ><base:icon 
592                    image="deleted.gif" 
593                    tooltip="This item has been scheduled for deletion" 
594                    visible="<%=item.isRemoved()%>"
595                  /><base:icon 
596                    image="<%=sharePermission ? "shared.gif" : "shared_disabled.gif"%>" 
597                    onclick="<%=sharePermission ? openSharePopup : null%>"
598                    tooltip="This item is shared to other users, groups and/or projects" 
599                    visible="<%=item.isShared()%>"
600                  />&nbsp;</tbl:header>
601                <tbl:cell column="name"><div class="link" 
602                  onclick="itemOnClick(<%=writePermission ? "event" : null%>, <%=itemId%>)" 
603                  title="<%=tooltip%>"><%=name%></div></tbl:cell>
604                <tbl:cell column="pluginType"><%=item.getMainType()%></tbl:cell>
605                <tbl:cell column="className"><%=item.getClassName()%></tbl:cell>
606                <tbl:cell column="jarPath"><%=Values.getString(item.getJarPath(), "<i>-&nbsp;internal&nbsp;-</i>")%></tbl:cell>
607                <tbl:cell column="version"><%=HTML.encodeTags(item.getVersionString())%></tbl:cell>
608                <tbl:cell column="configurations">
609                  <%
610                  configQuery.setParameter("plugin", itemId, Type.INT);
611                  try
612                  {
613                    String separator = "";
614                    for (PluginConfiguration p : configQuery.list(dc))
615                    {
616                      out.write(separator);
617                      if (mode.hasPropertyLink())
618                      {
619                        out.write(Base.getLinkedName(ID, p, false, mode.hasEditLink()));
620                      }
621                      else
622                      {
623                        out.write(HTML.encodeTags(p.getName()));
624                      }
625                      separator = ", ";
626                    }
627                  }
628                  catch (Throwable t)
629                  {
630                    %>
631                    <div class="error"><%=t.getMessage()%></div>
632                    <%
633                  }
634                  %>
635                  <base:icon
636                    image="add.png" 
637                    onclick="<%="newConfiguration("+itemId+")"%>" 
638                    tooltip="Create new configuration" 
639                    visible="<%=mode.hasEditLink() && createConfigurationPermission && usePermission && item.supportsConfigurations() %>"
640                  />
641                </tbl:cell>
642                <tbl:cell column="contact"><%=HTML.encodeTags(item.getContact())%></tbl:cell>
643                <tbl:cell column="copyright"><%=HTML.encodeTags(item.getCopyright())%></tbl:cell>
644                <tbl:cell column="email"><%=HTML.encodeTags(item.getEmail())%></tbl:cell>
645                <tbl:cell column="url"><%=HTML.encodeTags(item.getUrl())%></tbl:cell>
646                <tbl:cell column="interactive"><%=item.isInteractive()%></tbl:cell>
647                <tbl:cell column="supportsConfigurations"><%=item.supportsConfigurations() ? "yes" : "no"%></tbl:cell>
648                <tbl:cell column="requiresConfiguration"><%=item.requiresConfiguration() ? "yes" : "no"%></tbl:cell>
649                <tbl:cell column="usePermissions"><%=item.getUsePermissions() ? "yes" : "no"%></tbl:cell>
650                <tbl:cell column="contexts">
651                  <%
652                  contexts.clear();
653                  contexts.addAll(item.getGuiContexts());
654                  %>
655                  <%=contexts.isEmpty() ? "<i>- none -</i>" : Values.getString(contexts, ", ", true)%>
656                </tbl:cell>
657                <tbl:cell column="loaded"><%=item.getJarPath() == null || JarClassLoader.exists(item.getJarPath()) ? "Yes" : "No"%></tbl:cell>
658                <tbl:cell column="maxMemory"><%=Values.formatBytes(item.getMaxMemory())%></tbl:cell>
659                <tbl:cell column="trusted"><%=item.isTrusted() ? "yes" : "no"%></tbl:cell>
660                <tbl:cell column="allowImmediateExecution"><%=item.getAllowImmediateExecution() ? "yes" : "no"%></tbl:cell>
661                <tbl:cell column="owner"
662                  ><base:propertyvalue 
663                    item="<%=item%>" 
664                    property="owner"
665                    enableEditLink="<%=mode.hasEditLink()%>" 
666                    enablePropertyLink="<%=mode.hasPropertyLink()%>"
667                  /></tbl:cell>
668                <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
669                <tbl:cell column="permission"><%=PermissionUtil.getShortPermissions(item)%></tbl:cell>
670              </tbl:row>
671              <%
672              }
673            }
674          %>
675          </tbl:rows>
676      </tbl:data>
677      <%
678      if (numListed == 0)
679      {
680        %>
681        <tbl:panel><%=plugins == null || plugins.getTotalCount() == 0 ? "No plugins were found" : "No plugins on this page. Please select another page!" %></tbl:panel>
682        <%
683      }
684      else
685      {
686        %>
687        <tbl:navigator
688          page="<%=cc.getPage()%>" 
689          rowsperpage="<%=cc.getRowsPerPage()%>" 
690          totalrows="<%=plugins == null ? 0 : plugins.getTotalCount()%>" 
691          visible="<%=mode.hasNavigator()%>"
692          locked="true"
693        />
694        <%
695      }
696      %>
697    </tbl:table>
698    <base:buttongroup align="center" clazz="fixedatbottom">
699      <base:button onclick="returnSelected();" title="Ok" visible="<%=mode.hasOkButton()%>" />
700      <base:button onclick="window.close();" title="Cancel" visible="<%=mode.hasCancelButton()%>" />
701      <base:button onclick="window.close();" title="Close" visible="<%=mode.hasCloseButton()%>" />
702    </base:buttongroup>
703    <br><br><br>
704  </base:body>
705  </base:page>
706  <%
707}
708finally
709{
710  if (plugins != null) plugins.close();
711  if (dc != null) dc.close();
712}
713%>
Note: See TracBrowser for help on using the repository browser.