From eec0cd2b46a2186b4df1b1a59962c81ae2a9bcb7 Mon Sep 17 00:00:00 2001 From: Bruno Sinou Date: Tue, 15 Sep 2015 13:31:13 +0000 Subject: [PATCH] Plug automatic refresh of the transaction edition commands. git-svn-id: https://svn.argeo.org/commons/trunk@8399 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- org.argeo.security.ui.admin/plugin.xml | 48 +++++--- .../ui/admin/commands/DeleteGroups.java | 1 + .../commands/UserTransactionHandler.java | 2 + .../security/ui/admin/editors/UserEditor.java | 1 + .../ui/admin/internal/PartStateChanged.java | 112 ++++++++++++++++++ .../ui/admin/internal/UiAdminUtils.java | 42 +++++-- .../internal/UserTransactionProvider.java | 79 ++++++++++++ 7 files changed, 257 insertions(+), 28 deletions(-) create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTransactionProvider.java diff --git a/org.argeo.security.ui.admin/plugin.xml b/org.argeo.security.ui.admin/plugin.xml index 86fca8c11..e22ef0787 100644 --- a/org.argeo.security.ui.admin/plugin.xml +++ b/org.argeo.security.ui.admin/plugin.xml @@ -97,30 +97,15 @@ - - - - - - + --> + + + + + + + + + + + @@ -201,6 +196,18 @@ --> + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java index 88700cdd9..8d72a5891 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java @@ -34,6 +34,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.UserAdmin; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/UserTransactionHandler.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/UserTransactionHandler.java index 158fae24d..0a94d1a7d 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/UserTransactionHandler.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/UserTransactionHandler.java @@ -20,6 +20,7 @@ import javax.transaction.UserTransaction; import org.argeo.ArgeoException; import org.argeo.security.ui.admin.SecurityAdminPlugin; +import org.argeo.security.ui.admin.internal.UiAdminUtils; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -57,6 +58,7 @@ public class UserTransactionHandler extends AbstractHandler { else userTransaction.rollback(); } + UiAdminUtils.notifyTransactionStateChange(userTransaction); } catch (ArgeoException e) { throw e; } catch (Exception e) { diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java index 76e6a6903..2f7aa41c7 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java @@ -132,6 +132,7 @@ public class UserEditor extends FormEditor implements UserAdminConstants { @Override public void doSave(IProgressMonitor monitor) { + UiAdminUtils.beginTransactionIfNeeded(userTransaction); commitPages(true); firePropertyChange(PROP_DIRTY); // FIXME transaction should be managed at a higher level diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java new file mode 100644 index 000000000..2d437540f --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java @@ -0,0 +1,112 @@ +package org.argeo.security.ui.admin.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.ArgeoException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.contexts.IContextActivation; + +/** Manage transaction and part refresh while updating the security model */ +public class PartStateChanged implements IPartListener, IStartup { + private final static Log log = LogFactory.getLog(PartStateChanged.class); + IContextActivation contextActivation; + + @Override + public void earlyStartup() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + try { + IWorkbenchPage iwp = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (iwp != null) + iwp.addPartListener(new PartStateChanged()); + } catch (Exception e) { + throw new ArgeoException( + "Error while registering the PartStateChangedListener", + e); + } + } + }); + } + + @Override + public void partActivated(IWorkbenchPart part) { + if (log.isTraceEnabled()) + log.trace("Part activated: " + part.getTitle() + " - " + + part.getClass()); + + // Try to avoid NPE when closing the application + IWorkbenchPartSite site = part.getSite(); + if (site == null) + return; + IWorkbenchWindow window = site.getWorkbenchWindow(); + if (window == null) + return; + + // // Retrieve the service to enable/disable checkout button + // ISourceProviderService sourceProviderService = + // (ISourceProviderService) window + // .getService(ISourceProviderService.class); + // EditionSourceProvider esp = (EditionSourceProvider) + // sourceProviderService + // .getSourceProvider(EditionSourceProvider.EDITING_STATE); + // if (part instanceof IVersionedItemEditor) { + // IStatusLineManager manager = ((IEditorPart) part).getEditorSite() + // .getActionBars().getStatusLineManager(); + // manager.setMessage(((IVersionedItemEditor) part) + // .getlastUpdateMessage()); + // + // } + // if (part instanceof CmsEditable) { + // CmsEditable editor = (CmsEditable) part; + // // Processing the ability to checkout is delegated to the editor + // esp.setCurrentItemEditingState(editor.isEditing()); + // } else {// force button to be disabled if another part has the focus. + // esp.setCurrentItemEditingState(true); + // } + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partClosed(IWorkbenchPart part) { + // Nothing to do + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + // Always remove checkOut button when the editor is left. + // if (part instanceof IVersionedItemEditor) { + // // Try to avoid NPE when closing the application + // IWorkbenchPartSite site = part.getSite(); + // if (site == null) + // return; + // IWorkbenchWindow window = site.getWorkbenchWindow(); + // if (window == null) + // return; + // + // // Retrieve the service to enable/disable checkout button + // ISourceProviderService sourceProviderService = + // (ISourceProviderService) window + // .getService(ISourceProviderService.class); + // EditionSourceProvider esp = (EditionSourceProvider) + // sourceProviderService + // .getSourceProvider(EditionSourceProvider.EDITING_STATE); + // esp.setCurrentItemEditingState(true); + // } + } + + @Override + public void partOpened(IWorkbenchPart part) { + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java index 5430b34d9..3872f8dfd 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java @@ -9,6 +9,9 @@ import javax.transaction.Status; import javax.transaction.UserTransaction; import org.argeo.ArgeoException; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.services.ISourceProviderService; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; @@ -41,16 +44,6 @@ public class UiAdminUtils { return (firstName.trim() + " " + lastName.trim() + " ").trim(); } - public final static void beginTransactionIfNeeded( - UserTransaction userTransaction) { - try { - if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) - userTransaction.begin(); - } catch (Exception e) { - throw new ArgeoException("Unable to begin transaction", e); - } - } - /* * INTERNAL METHODS: Below methods are meant to stay here and are not part * of a potential generic backend to manage the useradmin @@ -69,4 +62,33 @@ public class UiAdminUtils { return "".equals(string.trim()); } + /** Must be called from the UI Thread. */ + public final static void beginTransactionIfNeeded( + UserTransaction userTransaction) { + try { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) { + userTransaction.begin(); + notifyTransactionStateChange(userTransaction); + } + } catch (Exception e) { + throw new ArgeoException("Unable to begin transaction", e); + } + } + + /** Easily notify the ActiveWindow that the transaction had a state change */ + public final static void notifyTransactionStateChange( + UserTransaction userTransaction) { + try { + IWorkbenchWindow aww = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + ISourceProviderService sourceProviderService = (ISourceProviderService) aww + .getService(ISourceProviderService.class); + UserTransactionProvider esp = (UserTransactionProvider) sourceProviderService + .getSourceProvider(UserTransactionProvider.TRANSACTION_STATE); + esp.setUserTransaction(userTransaction); + esp.fireTransactionStateChange(); + } catch (Exception e) { + throw new ArgeoException("Unable to begin transaction", e); + } + } } \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTransactionProvider.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTransactionProvider.java new file mode 100644 index 000000000..3a57c59ad --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTransactionProvider.java @@ -0,0 +1,79 @@ +package org.argeo.security.ui.admin.internal; + +import java.util.HashMap; +import java.util.Map; + +import javax.transaction.Status; +import javax.transaction.UserTransaction; + +import org.argeo.ArgeoException; +import org.argeo.security.ui.admin.SecurityAdminPlugin; +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; + +/** Centralize interaction with the UserTransaction among the UI */ +public class UserTransactionProvider extends AbstractSourceProvider { + public final static String TRANSACTION_STATE = SecurityAdminPlugin.PLUGIN_ID + + ".userTransactionState"; + public final static String STATUS_ACTIVE = "status.active"; + public final static String STATUS_NO_TRANSACTION = "status.noTransaction"; + + private String transactionState = STATUS_NO_TRANSACTION; + + /* DEPENDENCY INJECTION */ + private UserTransaction userTransaction; + + @Override + public String[] getProvidedSourceNames() { + return new String[] { TRANSACTION_STATE }; + } + + @Override + public Map getCurrentState() { + Map currentState = new HashMap(1); + // TODO implement asking to the UserTransaction + // String transactionState = isActive ? STATUS_ACTIVE : + // STATUS_NO_TRANSACTION; + currentState.put(TRANSACTION_STATE, transactionState); + return currentState; + } + + @Override + public void dispose() { + } + + /** Publish the ability to change the state. */ + public void setUserTransactionState(String newState) { + transactionState = newState; + // fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, + // transactionState); + } + + private void refreshState() { + try { + if (userTransaction != null) { + if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) + transactionState = STATUS_NO_TRANSACTION; + else if (userTransaction.getStatus() == Status.STATUS_ACTIVE) + transactionState = STATUS_ACTIVE; + fireSourceChanged(ISources.WORKBENCH, TRANSACTION_STATE, + transactionState); + } + } catch (Exception e) { + throw new ArgeoException("Unable to begin transaction", e); + } + } + + /** Publish the ability to notify a state change */ + public void fireTransactionStateChange() { + refreshState(); + } + + /** FIXME: Rather inject the UserTransaction. */ + @Deprecated + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + // dirty init + refreshState(); + } +} \ No newline at end of file -- 2.30.2