From 9ce5c347cb19e90c6e4af4a4cdaa3279340fe56e Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 19 Jan 2018 15:45:53 +0100 Subject: [PATCH] IDEMPIERE-3545 Add plugin information in About window / implement start-stop --- .../oracle/201801191458_IDEMPIERE-3545.sql | 35 ++++ .../201801191458_IDEMPIERE-3545.sql | 32 +++ .../adempiere/webui/window/AboutWindow.java | 191 +++++++++++++++--- 3 files changed, 225 insertions(+), 33 deletions(-) create mode 100644 migration/i5.1z/oracle/201801191458_IDEMPIERE-3545.sql create mode 100644 migration/i5.1z/postgresql/201801191458_IDEMPIERE-3545.sql diff --git a/migration/i5.1z/oracle/201801191458_IDEMPIERE-3545.sql b/migration/i5.1z/oracle/201801191458_IDEMPIERE-3545.sql new file mode 100644 index 0000000000..7d066fb4e4 --- /dev/null +++ b/migration/i5.1z/oracle/201801191458_IDEMPIERE-3545.sql @@ -0,0 +1,35 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-3545 Add plugin information in About window +-- Jan 19, 2018 2:56:10 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Stop',0,0,'Y',TO_DATE('2018-01-19 14:56:09','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:56:09','YYYY-MM-DD HH24:MI:SS'),100,200443,'Stop','D','e250a904-9b0d-49a5-bfb3-d96702f035d1') +; + +-- Jan 19, 2018 2:56:44 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Uninstall',0,0,'Y',TO_DATE('2018-01-19 14:56:44','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:56:44','YYYY-MM-DD HH24:MI:SS'),100,200444,'Uninstall','D','0bbd28ab-67e4-4a61-95f9-10da8e2c875b') +; + +-- Jan 19, 2018 2:56:52 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Install',0,0,'Y',TO_DATE('2018-01-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,200445,'Install','D','f187b323-baa0-4207-9a98-8e931277f2ea') +; + +-- Jan 19, 2018 2:57:00 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Id',0,0,'Y',TO_DATE('2018-01-19 14:57:00','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:57:00','YYYY-MM-DD HH24:MI:SS'),100,200446,'Id','D','14fd776d-47a6-4b4f-a6e0-7f8aae564339') +; + +-- Jan 19, 2018 2:57:09 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','State',0,0,'Y',TO_DATE('2018-01-19 14:57:08','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:57:08','YYYY-MM-DD HH24:MI:SS'),100,200447,'State','D','1109bf43-b855-4846-9cca-abe90fbf1ba7') +; + +-- Jan 19, 2018 2:57:18 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Version',0,0,'Y',TO_DATE('2018-01-19 14:57:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:57:17','YYYY-MM-DD HH24:MI:SS'),100,200448,'Version','D','64e718bd-5195-4a0f-ae54-5d67af26f4e4') +; + +-- Jan 19, 2018 2:57:26 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Plugins',0,0,'Y',TO_DATE('2018-01-19 14:57:25','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-01-19 14:57:25','YYYY-MM-DD HH24:MI:SS'),100,200449,'Plugins','D','712ab4af-73c4-4998-b1c0-a0664f334945') +; + +SELECT register_migration_script('201801191458_IDEMPIERE-3545.sql') FROM dual +; + diff --git a/migration/i5.1z/postgresql/201801191458_IDEMPIERE-3545.sql b/migration/i5.1z/postgresql/201801191458_IDEMPIERE-3545.sql new file mode 100644 index 0000000000..2e1465359d --- /dev/null +++ b/migration/i5.1z/postgresql/201801191458_IDEMPIERE-3545.sql @@ -0,0 +1,32 @@ +-- IDEMPIERE-3545 Add plugin information in About window +-- Jan 19, 2018 2:56:10 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Stop',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:56:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:56:09','YYYY-MM-DD HH24:MI:SS'),100,200443,'Stop','D','e250a904-9b0d-49a5-bfb3-d96702f035d1') +; + +-- Jan 19, 2018 2:56:44 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Uninstall',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:56:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:56:44','YYYY-MM-DD HH24:MI:SS'),100,200444,'Uninstall','D','0bbd28ab-67e4-4a61-95f9-10da8e2c875b') +; + +-- Jan 19, 2018 2:56:52 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Install',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,200445,'Install','D','f187b323-baa0-4207-9a98-8e931277f2ea') +; + +-- Jan 19, 2018 2:57:00 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Id',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:57:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:57:00','YYYY-MM-DD HH24:MI:SS'),100,200446,'Id','D','14fd776d-47a6-4b4f-a6e0-7f8aae564339') +; + +-- Jan 19, 2018 2:57:09 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','State',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:57:08','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:57:08','YYYY-MM-DD HH24:MI:SS'),100,200447,'State','D','1109bf43-b855-4846-9cca-abe90fbf1ba7') +; + +-- Jan 19, 2018 2:57:18 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Version',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:57:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:57:17','YYYY-MM-DD HH24:MI:SS'),100,200448,'Version','D','64e718bd-5195-4a0f-ae54-5d67af26f4e4') +; + +-- Jan 19, 2018 2:57:26 PM CET +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Plugins',0,0,'Y',TO_TIMESTAMP('2018-01-19 14:57:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-01-19 14:57:25','YYYY-MM-DD HH24:MI:SS'),100,200449,'Plugins','D','712ab4af-73c4-4998-b1c0-a0664f334945') +; + +SELECT register_migration_script('201801191458_IDEMPIERE-3545.sql') FROM dual +; + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java index 2a576bc76c..d3ef8419dc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java @@ -15,9 +15,11 @@ package org.adempiere.webui.window; import java.io.File; import java.io.FileNotFoundException; +import java.util.Properties; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.WebUIActivator; import org.adempiere.webui.apps.AEnv; @@ -49,15 +51,18 @@ import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.FeedbackManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.Adempiere; +import org.compiere.minigrid.IDColumn; import org.compiere.model.MUser; import org.compiere.util.CLogErrorBuffer; import org.compiere.util.CLogMgt; import org.compiere.util.Env; import org.compiere.util.Ini; +import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; import org.compiere.util.Util; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; import org.zkoss.util.media.AMedia; import org.zkoss.zhtml.Pre; import org.zkoss.zhtml.Text; @@ -86,11 +91,10 @@ public class AboutWindow extends Window implements EventListener { /** * */ - private static final long serialVersionUID = -137266702660831515L; + private static final long serialVersionUID = 8527444729510721269L; private Checkbox bErrorsOnly; private Listbox logTable; - private WListbox pluginsTable; private Tabbox tabbox; protected Tabpanels tabPanels; protected Button btnDownload; @@ -103,6 +107,19 @@ public class AboutWindow extends Window implements EventListener { private Listbox levelListBox; + private WListbox pluginsTable; + private Listbox pluginActions; + private Button pluginProcess; + private Vector> pluginData; + private Vector pluginColumnNames; + + private static final int PLUGIN_ACTION_NONE = 0; + private static final int PLUGIN_ACTION_STOP = 1; + private static final int PLUGIN_ACTION_START = 2; + private static final int PLUGIN_ACTION_UPDATE = 3; + private static final int PLUGIN_ACTION_UNINSTALL = 4; + private static final int PLUGIN_ACTION_INSTALL = 5; + public AboutWindow() { super(); init(); @@ -329,48 +346,61 @@ public class AboutWindow extends Window implements EventListener { } protected Tabpanel createPlugins() { - MUser user = MUser.get(Env.getCtx()); + Properties ctx = Env.getCtx(); + MUser user = MUser.get(ctx); Tabpanel tabPanel = null; - if (Env.getAD_Client_ID(Env.getCtx()) == 0 && user.isAdministrator()) { + if (Env.getAD_Client_ID(ctx) == 0 && user.isAdministrator()) { tabPanel = new Tabpanel(); Vbox vbox = new Vbox(); - vbox.setParent(tabPanel); ZKUpdateUtil.setHflex(vbox, "1"); ZKUpdateUtil.setVflex(vbox, "1"); - Vector columnNames = new Vector(); - columnNames.add(Msg.getMsg(Env.getCtx(), "Id")); - columnNames.add(Msg.getMsg(Env.getCtx(), "State")); - columnNames.add(Msg.getCleanMsg(Env.getCtx(), "Name")); - columnNames.add(Msg.getMsg(Env.getCtx(), "Version")); + pluginColumnNames = new Vector(); + pluginColumnNames.add(""); + pluginColumnNames.add(Msg.getMsg(ctx, "Id")); + pluginColumnNames.add(Msg.getMsg(ctx, "State")); + pluginColumnNames.add(Msg.getCleanMsg(ctx, "Name")); + pluginColumnNames.add(Msg.getMsg(ctx, "Version")); pluginsTable = ListboxFactory.newDataTableAutoSize(); - - Vector> data = new Vector>(); - BundleContext ctx = WebUIActivator.getBundleContext(); - for (Bundle bundle : ctx.getBundles()) { - Vector line = new Vector(); - Integer bundl = new Long(bundle.getBundleId()).intValue(); // potential problem converting Long to Integer, but WListBox cannot order Long - line.add(bundl); - line.add(state(bundle.getState())); - line.add(bundle.getSymbolicName()); - line.add(bundle.getVersion()); - data.add(line); - } - - ListModelTable model = new ListModelTable(data); - pluginsTable.setData(model, columnNames); + pluginData = new Vector>(); int i = 0; - pluginsTable.setColumnClass(i++, Integer.class, true); // 0-bundleId - pluginsTable.setColumnClass(i++, String.class, true); // 1-State - pluginsTable.setColumnClass(i++, String.class, true); // 2-SymbolicName - pluginsTable.setColumnClass(i++, String.class, true); // 3-Version - pluginsTable.autoSize(); + pluginsTable.setColumnClass(i++, IDColumn.class, true); // 0-bundleId + pluginsTable.setColumnClass(i++, Integer.class, true); // 1-bundleId + pluginsTable.setColumnClass(i++, String.class, true); // 2-State + pluginsTable.setColumnClass(i++, String.class, true); // 3-SymbolicName + pluginsTable.setColumnClass(i++, String.class, true); // 4-Version vbox.appendChild(pluginsTable); ZKUpdateUtil.setVflex(pluginsTable, "1"); ZKUpdateUtil.setHflex(pluginsTable, "1"); + refreshPluginTable(); + pluginsTable.autoSize(); + pluginsTable.addEventListener(Events.ON_SELECT, this); - tabPlugins.setLabel(Msg.getMsg(Env.getCtx(), "Plugins") + " (" + data.size() + ")"); + pluginActions = new Listbox( + new KeyNamePair[] { + new KeyNamePair(PLUGIN_ACTION_NONE, ""), + new KeyNamePair(PLUGIN_ACTION_STOP, Msg.getMsg(ctx, "Stop")), + new KeyNamePair(PLUGIN_ACTION_START, Msg.getMsg(ctx, "Start")), + new KeyNamePair(PLUGIN_ACTION_UPDATE, Msg.getMsg(ctx, "Update")), + new KeyNamePair(PLUGIN_ACTION_UNINSTALL, Msg.getMsg(ctx, "Uninstall")), + new KeyNamePair(PLUGIN_ACTION_INSTALL, Msg.getMsg(ctx, "Install")) + }); + pluginActions.setId("pluginActions"); + pluginActions.setRows(0); + pluginActions.setMold("select"); + ZKUpdateUtil.setWidth(pluginActions, "200px"); + refreshActionList(); + pluginProcess = new Button(Msg.getMsg(ctx, "Process")); + pluginProcess.addEventListener(Events.ON_CLICK, this); + Div div = new Div(); + div.setStyle("text-align: right;"); + div.appendChild(pluginActions); + div.appendChild(pluginProcess); + vbox.appendChild(div); + vbox.setParent(tabPanel); + + tabPlugins.setLabel(Msg.getMsg(ctx, "Plugins") + " (" + pluginData.size() + ")"); } return tabPanel; @@ -395,6 +425,95 @@ public class AboutWindow extends Window implements EventListener { } } + private void refreshActionList() { + pluginActions.getItemAtIndex(PLUGIN_ACTION_UPDATE).setVisible(false); // not implemented yet + pluginActions.getItemAtIndex(PLUGIN_ACTION_UNINSTALL).setVisible(false); // not implemented yet + pluginActions.getItemAtIndex(PLUGIN_ACTION_INSTALL).setVisible(false); // not implemented yet + pluginActions.getItemAtIndex(PLUGIN_ACTION_STOP).setVisible(false); + pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(false); + pluginActions.setSelectedItem(null); + Bundle bundle = getSelectedBundle(); + if (bundle == null) + return; + int state = bundle.getState(); + if (bundle.getBundleId() == 0) { + // bundle 0 cannot be stopped + } else if (state == Bundle.ACTIVE) { + pluginActions.getItemAtIndex(PLUGIN_ACTION_STOP).setVisible(true); + } else if (state == Bundle.RESOLVED) { + pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(true); + } else if (state == Bundle.INSTALLED) { + // no options yet for installed + } else if (state == Bundle.STARTING) { + // no options yet for starting + } else if (state == Bundle.STOPPING) { + // no options yet for stopping + } else if (state == Bundle.UNINSTALLED) { + // no options yet for uninstalled + } + } + + private Bundle getSelectedBundle() { + Bundle retValue = null; + int idx = pluginsTable.getSelectedIndex(); + if (idx >= 0) { + Integer selectedPlugin = (Integer) pluginsTable.getModel().getDataAt(idx, 1); + Vector pluginVector = pluginData.get(selectedPlugin); + int pluginId = ((IDColumn)pluginVector.get(0)).getRecord_ID(); + BundleContext bundleCtx = WebUIActivator.getBundleContext(); + retValue = bundleCtx.getBundle(pluginId); + } + return retValue; + } + + private void processPlugin() { + Listitem actionItem = pluginActions.getSelectedItem(); + if (actionItem != null && actionItem.getValue() instanceof Integer) { + int action = (Integer)actionItem.getValue(); + Bundle bundle = getSelectedBundle(); + if (action == PLUGIN_ACTION_STOP && bundle != null) { + try { + bundle.stop(); + } catch (BundleException e) { + throw new AdempiereException(e); + } + } else if (action == PLUGIN_ACTION_START && bundle != null) { + try { + bundle.start(); + } catch (BundleException e) { + throw new AdempiereException(e); + } + } else if (action == PLUGIN_ACTION_UPDATE && bundle != null) { + // PLUGIN_ACTION_UPDATE not implemented yet + } else if (action == PLUGIN_ACTION_UNINSTALL && bundle != null) { + // PLUGIN_ACTION_UNINSTALL not implemented yet + } else if (action == PLUGIN_ACTION_INSTALL && bundle != null) { + // PLUGIN_ACTION_INSTALL not implemented yet + } + } + refreshPluginTable(); + refreshActionList(); + } + + private void refreshPluginTable() { + pluginsTable.getModel().removeAll(pluginData); + pluginData.removeAllElements(); + + BundleContext bundleCtx = WebUIActivator.getBundleContext(); + for (Bundle bundle : bundleCtx.getBundles()) { + Vector line = new Vector(); + Integer bundl = new Long(bundle.getBundleId()).intValue(); // potential problem converting Long to Integer, but WListBox cannot order Long + line.add(new IDColumn(bundl)); + line.add(bundl); + line.add(state(bundle.getState())); + line.add(bundle.getSymbolicName()); + line.add(bundle.getVersion()); + pluginData.add(line); + } + ListModelTable model = new ListModelTable(pluginData); + pluginsTable.setData(model, pluginColumnNames); + } + protected Tabpanel createInfo() { Tabpanel tabPanel = new Tabpanel(); Div div = new Div(); @@ -599,8 +718,14 @@ public class AboutWindow extends Window implements EventListener { downloadAdempiereLogFile(); else if (event.getTarget() == levelListBox) setTraceLevel(); - else if (Events.ON_CLICK.equals(event.getName())) - this.detach(); + else if (Events.ON_SELECT.equals(event.getName()) && event.getTarget() == pluginsTable) + refreshActionList(); + else if (Events.ON_CLICK.equals(event.getName())) { + if (event.getTarget() == pluginProcess) + processPlugin(); + else + this.detach(); + } } private void setTraceLevel() {