Plug automatic refresh of the transaction edition commands.
authorBruno Sinou <bsinou@argeo.org>
Tue, 15 Sep 2015 13:31:13 +0000 (13:31 +0000)
committerBruno Sinou <bsinou@argeo.org>
Tue, 15 Sep 2015 13:31:13 +0000 (13:31 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8399 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.security.ui.admin/plugin.xml
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteGroups.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/UserTransactionHandler.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/PartStateChanged.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UiAdminUtils.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserTransactionProvider.java [new file with mode: 0644]

index 86fca8c114a05db6b9b8495bdd3090ffed92097d..e22ef0787495b52d8bd31b5424e02c076f66bc45 100644 (file)
                <menuContribution
                        locationURI="toolbar:org.argeo.security.ui.rap.userToolbar?after=org.eclipse.ui.file.saveAll"> 
                        <!-- Transaction management --> 
-                       <command
+<!--                   <command
                                commandId="org.argeo.security.ui.admin.userTransactionHandler"
                                icon="icons/begin.gif"
                                label="Begin Transaction"
                                style="push"
                                tooltip="Begin a user transaction">
-<!--                           <visibleWhen>
-                                       <and>
-                                               <with variable="activePart">
-                                                       <instanceof value="org.argeo.cms.CmsEditable" />
-                                               </with>
-                                               <with variable="org.argeo.connect.people.rap.editingState">
-                                                       <equals value="notEditing" />
-                                               </with> -->
-                                               <!-- FIXME : never true, the role condition does not work -->
-                                               <!-- <with variable="roles">
-                                               <iterate ifEmpty="false" operator="or">
-                                                       <equals value="ROLE_BUSINESS_ADMIN" />
-                                               </iterate>
-                                       </with> -->
-<!--                           </and>
-                               </visibleWhen> -->
                                <parameter name="param.commandId" value="transaction.begin" />
-                       </command>
+                       </command>-->
+                       
                        <command
                                commandId="org.argeo.security.ui.admin.userTransactionHandler"
                                icon="icons/commit.gif"
                                style="push"
                                tooltip="Commit a user transaction">
                                <parameter name="param.commandId" value="transaction.commit" />
+                               <visibleWhen>
+                                       <with variable="org.argeo.security.ui.admin.userTransactionState">
+                                                       <equals value="status.active" />
+                                       </with>
+                               </visibleWhen>
                        </command>
                        <command
                                commandId="org.argeo.security.ui.admin.userTransactionHandler"
                                style="push"
                                tooltip="Abandon current changes and rollback to the latest commited version">
                                <parameter name="param.commandId" value="transaction.rollback" />
+                               <visibleWhen>
+                                       <with variable="org.argeo.security.ui.admin.userTransactionState">
+                                                       <equals value="status.active" />
+                                       </with>
+                               </visibleWhen>
                        </command>
                </menuContribution>
     
             </command>
         </menuContribution> -->
        </extension>
+
+       <!-- SERVICES -->
+       <extension
+       point="org.eclipse.ui.services">
+               <sourceProvider
+               provider="org.argeo.security.ui.admin.internal.UserTransactionProvider">
+               <variable
+                   name="org.argeo.security.ui.admin.userTransactionState"
+                   priorityLevel="workbench">
+               </variable>
+               </sourceProvider>
+       </extension>
   
        <!-- ACTIVITIES -->
        <extension
                        pattern="org.argeo.security.ui.admin/org.argeo.security.ui.admin.adminRolesView">
                </activityPatternBinding>
        </extension>
+       
+       <!-- STARTUP  --> 
+       <extension point="org.eclipse.ui.startup">
+               <startup class="org.argeo.security.ui.admin.internal.PartStateChanged"/>
+       </extension>
 </plugin>
\ No newline at end of file
index 88700cdd941080296a06a8e179b151edcefbcbab..8d72a5891ebcca82a422fa65a08aa6d15ca416cb 100644 (file)
@@ -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;
index 158fae24de987e46b6cd827ae4321f66aed4bfc9..0a94d1a7d0d8351fb452b3e2874cede0a2e852ab 100644 (file)
@@ -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) {
index 76e6a690367caa15a66fed5acacf30ea68c7289e..2f7aa41c7c2672a3562bb909c746eded2507ebbb 100644 (file)
@@ -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 (file)
index 0000000..2d43754
--- /dev/null
@@ -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
index 5430b34d90710432e4000511119e7a88e977ed32..3872f8dfd86f90aa5bcaba63ed66affe40fe8d08 100644 (file)
@@ -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 (file)
index 0000000..3a57c59
--- /dev/null
@@ -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<String, String> getCurrentState() {
+               Map<String, String> currentState = new HashMap<String, String>(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