<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
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;
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;
else
userTransaction.rollback();
}
+ UiAdminUtils.notifyTransactionStateChange(userTransaction);
} catch (ArgeoException e) {
throw e;
} catch (Exception e) {
@Override
public void doSave(IProgressMonitor monitor) {
+ UiAdminUtils.beginTransactionIfNeeded(userTransaction);
commitPages(true);
firePropertyChange(PROP_DIRTY);
// FIXME transaction should be managed at a higher level
--- /dev/null
+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
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;
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
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
--- /dev/null
+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