Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2013-11-06 17:29:16 -0500
committerEike Stepper2013-11-12 07:56:20 -0500
commit452e6c6a3919d55c3074eb02aba46ec24081c487 (patch)
tree4dafb737595ef27e6c122931ef1d48b3e00be2a0
parentf4f414bc196a8359700c6e174f3af97f5dc79ba2 (diff)
downloadcdo-452e6c6a3919d55c3074eb02aba46ec24081c487.tar.gz
cdo-452e6c6a3919d55c3074eb02aba46ec24081c487.tar.xz
cdo-452e6c6a3919d55c3074eb02aba46ec24081c487.zip
[418454] [Admin] Client API and UI for managing repositories in a server
https://bugs.eclipse.org/bugs/show_bug.cgi?id=418454 Prompt the user to confirm deletion of a repository if any users are currently connected to it. This uses a new reusable confirmation signal API, including confirmation providers, after the fashion of the authentication signal and credentials providers. Also added the "Manage Security" action to repositories in the CDO Administration view. This uses an alternative handler targeting an admin-repository, which opens a new session if an open session doesn't already exist that is logged in as the administrator. Change-Id: Ib8d7e7d0237f9426158f5a9af57782b8515531cc Also-by: Eike Stepper <stepper@esc-net.de>
-rw-r--r--plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientImpl.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/protocol/CDOAdminClientProtocol.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/admin/CDOAdminProtocolConstants.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.security.ui/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.cdo.security.ui/plugin.xml30
-rw-r--r--plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/handlers/ManageSecurityHandler.java125
-rw-r--r--plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/util/OneToManyBlock.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServer.java97
-rw-r--r--plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/DefaultCDORepositoryConfigurationManager.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/protocol/CDOAdminServerProtocol.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.ocl/src/org/eclipse/emf/cdo/server/ocl/CDOAdditionalOperation.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.net4j.util.ui/plugin.xml6
-rw-r--r--plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/ConfirmationDialog.java92
-rw-r--r--plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/InteractiveConfirmationProvider.java85
-rw-r--r--plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/package-info.java18
-rw-r--r--plugins/org.eclipse.net4j.util/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.net4j.util/plugin.xml6
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/Confirmation.java25
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/IConfirmationProvider.java108
-rw-r--r--plugins/org.eclipse.net4j/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationIndication.java100
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationPrompt.java98
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationRequest.java63
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/package-info.java18
28 files changed, 932 insertions, 23 deletions
diff --git a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientImpl.java b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientImpl.java
index 404d783092..eb81b4f01b 100644
--- a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientImpl.java
+++ b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/CDOAdminClientImpl.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Christian W. Damus (CEA LIST) - bug 418454
*/
package org.eclipse.emf.cdo.internal.admin;
@@ -22,6 +23,7 @@ import org.eclipse.emf.cdo.spi.common.admin.AbstractCDOAdmin;
import org.eclipse.net4j.channel.IChannelMultiplexer;
import org.eclipse.net4j.connector.IConnector;
import org.eclipse.net4j.util.concurrent.ExecutorServiceFactory;
+import org.eclipse.net4j.util.confirmation.IConfirmationProvider;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
@@ -39,7 +41,7 @@ import java.util.concurrent.ExecutorService;
* @author Eike Stepper
*/
public class CDOAdminClientImpl extends AbstractCDOAdmin implements CDOAdminClient,
- IPasswordCredentialsProvider.Provider
+ IPasswordCredentialsProvider.Provider, IConfirmationProvider.Provider
{
private static final String URL_SEPARATOR = "://";
@@ -169,6 +171,19 @@ public class CDOAdminClientImpl extends AbstractCDOAdmin implements CDOAdminClie
}
}
+ public IConfirmationProvider getConfirmationProvider()
+ {
+ try
+ {
+ return (IConfirmationProvider)container.getElement(IConfirmationProvider.Factory.PRODUCT_GROUP,
+ IConfirmationProvider.Factory.INTERACTIVE_TYPE, null);
+ }
+ catch (Exception ex)
+ {
+ return null;
+ }
+ }
+
@Override
public int hashCode()
{
diff --git a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/protocol/CDOAdminClientProtocol.java b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/protocol/CDOAdminClientProtocol.java
index e6af8b9c32..d3867e8c62 100644
--- a/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/protocol/CDOAdminClientProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.admin/src/org/eclipse/emf/cdo/internal/admin/protocol/CDOAdminClientProtocol.java
@@ -18,8 +18,10 @@ import org.eclipse.emf.cdo.spi.common.admin.CDOAdminProtocolConstants;
import org.eclipse.net4j.signal.RequestWithConfirmation;
import org.eclipse.net4j.signal.SignalReactor;
+import org.eclipse.net4j.signal.confirmation.ConfirmationIndication;
import org.eclipse.net4j.signal.security.AuthenticatingSignalProtocol;
import org.eclipse.net4j.signal.security.AuthenticationIndication;
+import org.eclipse.net4j.util.confirmation.IConfirmationProvider;
import java.util.Map;
import java.util.Set;
@@ -27,7 +29,8 @@ import java.util.Set;
/**
* @author Eike Stepper
*/
-public class CDOAdminClientProtocol extends AuthenticatingSignalProtocol<CDOAdminClientImpl>
+public class CDOAdminClientProtocol extends AuthenticatingSignalProtocol<CDOAdminClientImpl> implements
+ IConfirmationProvider.Provider
{
public CDOAdminClientProtocol(CDOAdminClientImpl admin)
{
@@ -77,11 +80,19 @@ public class CDOAdminClientProtocol extends AuthenticatingSignalProtocol<CDOAdmi
case CDOAdminProtocolConstants.SIGNAL_AUTHENTICATION:
return new AuthenticationIndication(this, CDOAdminProtocolConstants.SIGNAL_AUTHENTICATION);
+ case CDOAdminProtocolConstants.SIGNAL_CONFIRMATION:
+ return new ConfirmationIndication<CDOAdminClientProtocol>(this, CDOAdminProtocolConstants.SIGNAL_CONFIRMATION);
+
default:
return super.createSignalReactor(signalID);
}
}
+ public IConfirmationProvider getConfirmationProvider()
+ {
+ return getInfraStructure().getConfirmationProvider();
+ }
+
private <RESULT> RESULT send(RequestWithConfirmation<RESULT> request)
{
return send(request, getTimeout());
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/admin/CDOAdminProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/admin/CDOAdminProtocolConstants.java
index 79be4d72b8..77a9dfad55 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/admin/CDOAdminProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/admin/CDOAdminProtocolConstants.java
@@ -46,4 +46,9 @@ public interface CDOAdminProtocolConstants
* @since 4.3
*/
public static final short SIGNAL_AUTHENTICATION = 9;
+
+ /**
+ * @since 4.3
+ */
+ public static final short SIGNAL_CONFIRMATION = 10;
}
diff --git a/plugins/org.eclipse.emf.cdo.security.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.security.ui/META-INF/MANIFEST.MF
index a78bcf3203..5a8a56f44b 100644
--- a/plugins/org.eclipse.emf.cdo.security.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.security.ui/META-INF/MANIFEST.MF
@@ -23,6 +23,7 @@ Require-Bundle: org.eclipse.emf.cdo.security;bundle-version="[4.3.0,5.0.0)",
org.eclipse.ui.forms;bundle-version="[3.6.100,4.0.0)",
org.eclipse.emf.databinding.edit;bundle-version="[1.3.0,2.0.0)",
org.eclipse.jface.databinding;bundle-version="[1.6.200,2.0.0)",
- org.eclipse.core.databinding.beans;bundle-version="[1.2.200,2.0.0)"
+ org.eclipse.core.databinding.beans;bundle-version="[1.2.200,2.0.0)",
+ org.eclipse.emf.cdo.admin;bundle-version="[4.1.200,5.0.0)"
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.emf.cdo.security.internal.ui.bundle.OM$Activator
diff --git a/plugins/org.eclipse.emf.cdo.security.ui/plugin.xml b/plugins/org.eclipse.emf.cdo.security.ui/plugin.xml
index a69db2a457..aa6a811670 100644
--- a/plugins/org.eclipse.emf.cdo.security.ui/plugin.xml
+++ b/plugins/org.eclipse.emf.cdo.security.ui/plugin.xml
@@ -63,10 +63,15 @@
value="1">
</count>
<iterate >
- <adapt
- type="org.eclipse.emf.cdo.session.CDOSession">
- <test property="org.eclipse.emf.cdo.session.userAuthenticated" />
- </adapt>
+ <or>
+ <adapt
+ type="org.eclipse.emf.cdo.session.CDOSession">
+ <test property="org.eclipse.emf.cdo.session.userAuthenticated" />
+ </adapt>
+ <adapt
+ type="org.eclipse.emf.cdo.admin.CDOAdminClientRepository">
+ </adapt>
+ </or>
</iterate>
</with>
</visibleWhen>
@@ -95,4 +100,21 @@
</command>
</extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ commandId="org.eclipse.emf.cdo.security.ui.openEditor"
+ class="org.eclipse.emf.cdo.security.internal.ui.handlers.ManageSecurityHandler$Sessionless">
+ <activeWhen>
+ <with
+ variable="activeMenuSelection">
+ <iterate >
+ <adapt
+ type="org.eclipse.emf.cdo.admin.CDOAdminClientRepository">
+ </adapt>
+ </iterate>
+ </with>
+ </activeWhen>
+ </handler>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/handlers/ManageSecurityHandler.java b/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/handlers/ManageSecurityHandler.java
index 6d9eb86ae9..232a8a1ad7 100644
--- a/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/handlers/ManageSecurityHandler.java
+++ b/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/handlers/ManageSecurityHandler.java
@@ -10,7 +10,12 @@
*/
package org.eclipse.emf.cdo.security.internal.ui.handlers;
+import org.eclipse.emf.cdo.admin.CDOAdminClientRepository;
+import org.eclipse.emf.cdo.common.model.CDOPackageRegistryPopulator;
import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.net4j.CDONet4jSession;
+import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration;
+import org.eclipse.emf.cdo.security.User;
import org.eclipse.emf.cdo.security.internal.ui.editor.CDOSecurityFormEditor;
import org.eclipse.emf.cdo.security.internal.ui.messages.Messages;
import org.eclipse.emf.cdo.security.ui.ISecurityManagementContext;
@@ -19,6 +24,15 @@ import org.eclipse.emf.cdo.ui.CDOEditorInput;
import org.eclipse.emf.cdo.ui.CDOEditorUtil;
import org.eclipse.emf.cdo.view.CDOView;
+import org.eclipse.emf.internal.cdo.session.CDOSessionFactory;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.security.CredentialsProviderFactory;
+import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
+import org.eclipse.net4j.util.security.NotAuthenticatedException;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.handlers.LongRunningHandler;
@@ -36,6 +50,7 @@ import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.statushandlers.StatusManager;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* "Manage Security" command handler, which opens the Security Manager editor
@@ -75,7 +90,7 @@ public class ManageSecurityHandler extends LongRunningHandler
return;
}
- session = getSession();
+ setSession(getSession());
if (session != null && !session.isClosed())
{
final IWorkbenchPage page = part.getSite().getPage();
@@ -95,6 +110,11 @@ public class ManageSecurityHandler extends LongRunningHandler
return UIUtil.adaptElement(getSelection(), CDOSession.class);
}
+ protected void setSession(CDOSession session)
+ {
+ this.session = session;
+ }
+
@Override
protected void doExecute(IProgressMonitor progressMonitor) throws Exception
{
@@ -256,4 +276,107 @@ public class ManageSecurityHandler extends LongRunningHandler
}
});
}
+
+ /**
+ * A specialized handler that gets or creates a session in the context of a repository in the
+ * CDO Administration view.
+ *
+ * @author Christian W. Damus (CEA LIST)
+ */
+ public static class Sessionless extends ManageSecurityHandler implements CDOAdminClientRepository.SessionConfigurator
+ {
+ private static final AtomicInteger NEXT_SESSION_NUMBER = new AtomicInteger();
+
+ public void prepare(CDONet4jSessionConfiguration configuration)
+ {
+ IPasswordCredentialsProvider credentialsProvider = getCredentialsProvider();
+ configuration.setCredentialsProvider(credentialsProvider);
+ }
+
+ @Override
+ protected CDOSession getSession()
+ {
+ return getExistingAdminSession(getRepository());
+ }
+
+ @Override
+ protected void doExecute(IProgressMonitor progressMonitor) throws Exception
+ {
+ CDOAdminClientRepository repository = getRepository();
+ CDOSession session = getExistingAdminSession(repository);
+ if (session == null)
+ {
+ session = openSession(getRepository());
+ setSession(session);
+ }
+
+ if (session != null)
+ {
+ super.doExecute(progressMonitor);
+ }
+ }
+
+ protected CDOAdminClientRepository getRepository()
+ {
+ return UIUtil.adaptElement(getSelection(), CDOAdminClientRepository.class);
+ }
+
+ protected CDOSession getExistingAdminSession(CDOAdminClientRepository repository)
+ {
+ for (Object element : IPluginContainer.INSTANCE.getElements(CDOSessionFactory.PRODUCT_GROUP))
+ {
+ CDONet4jSession session = ObjectUtil.tryCast(element, CDONet4jSession.class);
+
+ // If there's no user ID, then the repository doesn't require authentication,
+ // so we can use that session
+ if (session != null && !session.isClosed()
+ && (User.ADMINISTRATOR.equals(session.getUserID()) || StringUtil.isEmpty(session.getUserID()))
+ && ObjectUtil.equals(session.getRepositoryInfo().getUUID(), repository.getUUID()))
+ {
+ return session;
+ }
+ }
+
+ return null;
+ }
+
+ protected CDOSession openSession(CDOAdminClientRepository repository)
+ {
+ try
+ {
+ CDONet4jSession result = repository.openSession(this);
+ if (result != null)
+ {
+ CDOPackageRegistryPopulator.populate(result.getPackageRegistry());
+
+ // Add this session to the shared container so that it may appear in the CDO Sessions view
+ String description = "session" + NEXT_SESSION_NUMBER.incrementAndGet(); //$NON-NLS-1$
+ IPluginContainer.INSTANCE.putElement(CDOSessionFactory.PRODUCT_GROUP, "security", description, result); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+ catch (NotAuthenticatedException e)
+ {
+ // User cancelled authentication
+ return null;
+ }
+ }
+
+ protected IPasswordCredentialsProvider getCredentialsProvider()
+ {
+ IManagedContainer container = IPluginContainer.INSTANCE;
+ String productGroup = CredentialsProviderFactory.PRODUCT_GROUP;
+ String factoryType = "interactive"; //$NON-NLS-1$
+ IPasswordCredentialsProvider credentialsProvider = (IPasswordCredentialsProvider)container.getElement(
+ productGroup, factoryType, null);
+
+ if (credentialsProvider == null)
+ {
+ credentialsProvider = UIUtil.createInteractiveCredentialsProvider();
+ }
+
+ return credentialsProvider;
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/util/OneToManyBlock.java b/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/util/OneToManyBlock.java
index 85d340e081..7e33068e66 100644
--- a/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/util/OneToManyBlock.java
+++ b/plugins/org.eclipse.emf.cdo.security.ui/src/org/eclipse/emf/cdo/security/internal/ui/util/OneToManyBlock.java
@@ -80,6 +80,7 @@ import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -307,8 +308,7 @@ public class OneToManyBlock
if (directory != null)
{
// Get the available items not already in our input's reference list
- List<?> available = new java.util.ArrayList<Object>(EcoreUtil.getObjectsByType(directory.getItems(),
- itemType));
+ List<?> available = new ArrayList<Object>(EcoreUtil.getObjectsByType(directory.getItems(), itemType));
available.removeAll(value);
SecurityUIUtil.applySupportedElementFilter(available, itemType);
diff --git a/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF
index 8998c60d2a..e5c660271b 100644
--- a/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.server.admin/META-INF/MANIFEST.MF
@@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.core.runtime;resolution:=optional;bundle-version="[3
org.eclipse.emf.cdo.server;visibility:=reexport;bundle-version="[4.0.0,5.0.0)",
org.eclipse.net4j;visibility:=reexport;bundle-version="[4.0.0,5.0.0)",
org.eclipse.emf.cdo.server.security;bundle-version="[4.3.0,5.0.0)",
- org.eclipse.emf.cdo.security;bundle-version="[4.3.0,5.0.0)"
+ org.eclipse.emf.cdo.security;bundle-version="[4.3.0,5.0.0)",
+ org.eclipse.net4j.jvm;bundle-version="[4.1.100,5.0.0)";resolution:=optional
Export-Package: org.eclipse.emf.cdo.server.admin;version="4.2.0",
org.eclipse.emf.cdo.server.internal.admin;x-internal:=true;version="4.2.0",
org.eclipse.emf.cdo.server.internal.admin.bundle;x-internal:=true;version="4.2.0",
diff --git a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServer.java b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServer.java
index 3e3603c202..4db24e0b3d 100644
--- a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServer.java
+++ b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/CDOAdminServer.java
@@ -15,14 +15,21 @@ import org.eclipse.emf.cdo.common.CDOCommonRepository.State;
import org.eclipse.emf.cdo.common.CDOCommonRepository.Type;
import org.eclipse.emf.cdo.server.CDOServerUtil;
import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.ISession;
import org.eclipse.emf.cdo.server.internal.admin.bundle.OM;
import org.eclipse.emf.cdo.server.internal.admin.protocol.CDOAdminServerProtocol;
import org.eclipse.emf.cdo.server.spi.admin.CDOAdminHandler;
import org.eclipse.emf.cdo.server.spi.admin.CDOAdminHandler2;
import org.eclipse.emf.cdo.spi.common.admin.AbstractCDOAdmin;
+import org.eclipse.emf.cdo.spi.server.AuthenticationUtil;
+import org.eclipse.emf.cdo.spi.server.IAuthenticationProtocol;
+import org.eclipse.emf.cdo.spi.server.ISessionProtocol;
import org.eclipse.emf.cdo.spi.server.RepositoryFactory;
+import org.eclipse.net4j.channel.IChannel;
+import org.eclipse.net4j.jvm.IJVMChannel;
import org.eclipse.net4j.signal.ISignalProtocol;
+import org.eclipse.net4j.util.confirmation.Confirmation;
import org.eclipse.net4j.util.container.ContainerEventAdapter;
import org.eclipse.net4j.util.container.IContainer;
import org.eclipse.net4j.util.container.IManagedContainer;
@@ -32,6 +39,9 @@ import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.spi.net4j.Protocol;
+
+import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -41,6 +51,8 @@ import java.util.Set;
*/
public class CDOAdminServer extends AbstractCDOAdmin
{
+ private static Class<?> IJVMCHANNEL_CLASS;
+
private final IManagedContainer container;
private final IListener containerListener = new ContainerEventAdapter<Object>(true)
@@ -143,6 +155,12 @@ public class CDOAdminServer extends AbstractCDOAdmin
((CDOAdminHandler2)handler).authenticateAdministrator();
}
+ // Do we have any connected users? If so, prompt for confirmation
+ if (hasConnections(delegate) && !confirmDeletion(delegate))
+ {
+ return false;
+ }
+
LifecycleUtil.deactivate(delegate);
handler.deleteRepository(delegate);
return true;
@@ -153,6 +171,55 @@ public class CDOAdminServer extends AbstractCDOAdmin
return !(handler instanceof CDOAdminHandler2) || ((CDOAdminHandler2)handler).canDelete(repository);
}
+ protected boolean hasConnections(IRepository delegate)
+ {
+ ISession[] sessions = delegate.getSessionManager().getSessions();
+ if (sessions != null)
+ {
+ for (int i = 0; i < sessions.length; i++)
+ {
+ ISessionProtocol protocol = sessions[i].getProtocol();
+ if (protocol instanceof Protocol<?>)
+ {
+ // Connections from within this JVM do not count
+ IChannel channel = ((Protocol<?>)protocol).getChannel();
+ if (channel != null && !isJVMChannel(channel))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected boolean confirmDeletion(IRepository delegate)
+ {
+ IAuthenticationProtocol authProtocol = AuthenticationUtil.getAuthenticationProtocol();
+ if (authProtocol instanceof CDOAdminServerProtocol)
+ {
+ CDOAdminServerProtocol protocol = (CDOAdminServerProtocol)authProtocol;
+ String message = MessageFormat.format(
+ "The repository \"{0}\" has connected users. Proceed with deletion anyways?", delegate.getName());
+ try
+ {
+ if (protocol.sendConfirmationRequest("Repository In Use", message, Confirmation.NO, Confirmation.YES,
+ Confirmation.NO) != Confirmation.YES)
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
@Override
protected void doActivate() throws Exception
{
@@ -282,6 +349,36 @@ public class CDOAdminServer extends AbstractCDOAdmin
}
}
+ private static boolean isJVMChannel(IChannel channel)
+ {
+ return getIJVMChannelClass().isInstance(channel);
+ }
+
+ private static Class<?> getIJVMChannelClass()
+ {
+ if (IJVMCHANNEL_CLASS == null)
+ {
+ // Try to load the class, but the plug-in may not be installed
+ try
+ {
+ new Runnable()
+ {
+ public void run()
+ {
+ IJVMCHANNEL_CLASS = IJVMChannel.class;
+ }
+ }.run();
+ }
+ catch (LinkageError er)
+ {
+ // The class is not available, so no channel can be an IJVMChannel
+ IJVMCHANNEL_CLASS = Void.class;
+ }
+ }
+
+ return IJVMCHANNEL_CLASS;
+ }
+
/**
* @author Eike Stepper
*/
diff --git a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/DefaultCDORepositoryConfigurationManager.java b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/DefaultCDORepositoryConfigurationManager.java
index 0030135a91..301bccb459 100644
--- a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/DefaultCDORepositoryConfigurationManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/DefaultCDORepositoryConfigurationManager.java
@@ -69,6 +69,7 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -339,7 +340,7 @@ public class DefaultCDORepositoryConfigurationManager extends Lifecycle implemen
private void startExtensions(IRepository repository, RepositoryConfiguration configuration)
{
- final List<IAppExtension2> extensions = new java.util.ArrayList<IAppExtension2>(3);
+ final List<IAppExtension2> extensions = new ArrayList<IAppExtension2>(3);
IExtensionRegistry registry = Platform.getExtensionRegistry();
@SuppressWarnings("restriction")
diff --git a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/protocol/CDOAdminServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/protocol/CDOAdminServerProtocol.java
index 38a14e0563..ccd02827b6 100644
--- a/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/protocol/CDOAdminServerProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server.admin/src/org/eclipse/emf/cdo/server/internal/admin/protocol/CDOAdminServerProtocol.java
@@ -20,7 +20,10 @@ import org.eclipse.emf.cdo.spi.server.IAuthenticationProtocol;
import org.eclipse.net4j.signal.SignalProtocol;
import org.eclipse.net4j.signal.SignalReactor;
+import org.eclipse.net4j.signal.confirmation.ConfirmationPrompt;
+import org.eclipse.net4j.signal.confirmation.ConfirmationRequest;
import org.eclipse.net4j.signal.security.AuthenticationRequest;
+import org.eclipse.net4j.util.confirmation.Confirmation;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
@@ -116,6 +119,13 @@ public class CDOAdminServerProtocol extends SignalProtocol<CDOAdminServer> imple
throw new UnsupportedOperationException("sendCredentialsChallenge"); //$NON-NLS-1$
}
+ public Confirmation sendConfirmationRequest(String subject, String message, Confirmation suggestion,
+ Confirmation acceptable, Confirmation... more) throws Exception
+ {
+ return new ConfirmationRequest(this, CDOAdminProtocolConstants.SIGNAL_CONFIRMATION, new ConfirmationPrompt(subject,
+ message, suggestion, acceptable, more)).send(negotiationTimeout);
+ }
+
@Override
protected SignalReactor createSignalReactor(short signalID)
{
diff --git a/plugins/org.eclipse.emf.cdo.server.ocl/src/org/eclipse/emf/cdo/server/ocl/CDOAdditionalOperation.java b/plugins/org.eclipse.emf.cdo.server.ocl/src/org/eclipse/emf/cdo/server/ocl/CDOAdditionalOperation.java
index 88314786e6..64a4874e3b 100644
--- a/plugins/org.eclipse.emf.cdo.server.ocl/src/org/eclipse/emf/cdo/server/ocl/CDOAdditionalOperation.java
+++ b/plugins/org.eclipse.emf.cdo.server.ocl/src/org/eclipse/emf/cdo/server/ocl/CDOAdditionalOperation.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Christian W. Damus (CEA LIST) - initial API and implementation
*/
@@ -29,6 +29,7 @@ import org.eclipse.ocl.ecore.TypeType;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.utilities.TypedElement;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -39,7 +40,7 @@ import java.util.regex.Pattern;
/**
* Additional operations for use in OCL queries in the CDO context.
- *
+ *
* @author Christian W. Damus
* @since 4.2
*/
@@ -144,7 +145,7 @@ abstract class CDOAdditionalOperation extends AdapterImpl
* The <tt>cdoAllContents</tt> operation that collects all of the proper (non-cross-resource-contained)
* elements within a {@link CDOResource} or an {@link EObject}. An optional argument filters the result
* to instances of a particular model class.
- *
+ *
* @author Christian W. Damus
*/
private static class AllProperContents extends CDOAdditionalOperation
@@ -174,7 +175,7 @@ abstract class CDOAdditionalOperation extends AdapterImpl
@Override
protected Object evaluate(CDOEvaluationEnvironment evalEnv, Object source, Object[] arguments)
{
- Collection<EObject> result = new java.util.ArrayList<EObject>();
+ Collection<EObject> result = new ArrayList<EObject>();
// Only resources and EObjects have contents
Iterator<EObject> iter;
@@ -237,9 +238,9 @@ abstract class CDOAdditionalOperation extends AdapterImpl
}
/**
- * The <tt>cdoMatches</tt> operation queries whether a regular expression matches aany string-valued
+ * The <tt>cdoMatches</tt> operation queries whether a regular expression matches aany string-valued
* attribute of an {@link EObject}.
- *
+ *
* @author Christian W. Damus
*/
private static class MatchesAnyStringAttribute extends CDOAdditionalOperation
@@ -323,7 +324,6 @@ abstract class CDOAdditionalOperation extends AdapterImpl
}
Matcher result = matcherCache.get(regex);
-
if (result == null)
{
result = Pattern.compile(regex).matcher(""); //$NON-NLS-1$
@@ -341,7 +341,6 @@ abstract class CDOAdditionalOperation extends AdapterImpl
}
List<EAttribute> result = stringAttributes.get(eClass);
-
if (result == null)
{
for (EAttribute next : eClass.getEAllAttributes())
@@ -351,7 +350,7 @@ abstract class CDOAdditionalOperation extends AdapterImpl
{
if (result == null)
{
- result = new java.util.ArrayList<EAttribute>();
+ result = new ArrayList<EAttribute>();
}
result.add(next);
}
diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java
index b098a7d034..955c700e9f 100644
--- a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java
+++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java
@@ -34,6 +34,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -207,7 +208,7 @@ public abstract class AbstractCreateRepositoryWizardPage extends WizardPage
*/
public static final class Whiteboard
{
- private List<Object> subscribers = new java.util.ArrayList<Object>();
+ private List<Object> subscribers = new ArrayList<Object>();
/**
* Publish a topic to interested subscribers.
diff --git a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
index 0455f22c1e..169b456940 100644
--- a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
@@ -53,7 +53,8 @@ Export-Package: org.eclipse.emf.cdo;version="4.3.0",
org.eclipse.emf.cdo.defs,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.team,
- org.eclipse.emf.cdo.ui.admin",
+ org.eclipse.emf.cdo.ui.admin,
+ org.eclipse.emf.cdo.security.ui",
org.eclipse.emf.internal.cdo.session.remote;version="4.3.0";
x-friends:="org.eclipse.emf.cdo.net4j,
org.eclipse.emf.cdo.server,
diff --git a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF
index a1b438c344..8324c5ee8f 100644
--- a/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.net4j.util.ui/META-INF/MANIFEST.MF
@@ -22,6 +22,7 @@ Export-Package: org.eclipse.net4j.util.internal.ui;version="3.4.0";x-internal:=t
org.eclipse.net4j.util.internal.ui.views;version="3.4.0";x-internal:=true,
org.eclipse.net4j.util.ui;version="3.4.0",
org.eclipse.net4j.util.ui.actions;version="3.4.0",
+ org.eclipse.net4j.util.ui.confirmation;version="3.4.0",
org.eclipse.net4j.util.ui.container;version="3.4.0",
org.eclipse.net4j.util.ui.dnd;version="3.4.0",
org.eclipse.net4j.util.ui.handlers;version="3.4.0",
diff --git a/plugins/org.eclipse.net4j.util.ui/plugin.xml b/plugins/org.eclipse.net4j.util.ui/plugin.xml
index b0ef7c5e57..c8a0106d32 100644
--- a/plugins/org.eclipse.net4j.util.ui/plugin.xml
+++ b/plugins/org.eclipse.net4j.util.ui/plugin.xml
@@ -9,6 +9,7 @@
Contributors:
Eike Stepper - initial API and implementation
+ Christian W. Damus (CEA LIST) - bug 418454
-->
<plugin>
@@ -40,6 +41,11 @@
productGroup="org.eclipse.net4j.util.security.credentialsProviders"
type="interactive">
</factory>
+ <factory
+ class="org.eclipse.net4j.util.ui.confirmation.InteractiveConfirmationProvider$Factory"
+ productGroup="org.eclipse.net4j.util.confirmationProviders"
+ type="interactive">
+ </factory>
</extension>
</plugin>
diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/ConfirmationDialog.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/ConfirmationDialog.java
new file mode 100644
index 0000000000..ebdb6e45d1
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/ConfirmationDialog.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.util.ui.confirmation;
+
+import org.eclipse.net4j.util.confirmation.Confirmation;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 3.4
+ */
+public class ConfirmationDialog extends MessageDialog
+{
+ public ConfirmationDialog(Shell shell, String title, String message, Set<Confirmation> acceptableResponses,
+ Confirmation suggestedResponse)
+ {
+ this(shell, title, message, getButtonLabels(inOrder(acceptableResponses)), inOrder(acceptableResponses).indexOf(
+ suggestedResponse));
+ }
+
+ private ConfirmationDialog(Shell shell, String title, String message, String[] buttonLabels, int defaultIndex)
+ {
+ super(shell, title, null, message, MessageDialog.CONFIRM, buttonLabels, defaultIndex);
+ }
+
+ public static Confirmation openConfirm(Shell shell, String title, String message,
+ Set<Confirmation> acceptableResponses, Confirmation suggestedResponse)
+ {
+ List<Confirmation> inOrder = inOrder(acceptableResponses);
+ String[] buttonLabels = getButtonLabels(inOrder);
+ int defaultIndex = inOrder.indexOf(suggestedResponse);
+
+ ConfirmationDialog dialog = new ConfirmationDialog(shell, title, message, buttonLabels, defaultIndex);
+ int index = dialog.open();
+ return index == SWT.DEFAULT ? suggestedResponse : inOrder.get(index);
+ }
+
+ private static String[] getButtonLabels(List<Confirmation> acceptableResponses)
+ {
+ List<String> result = new ArrayList<String>(acceptableResponses.size());
+
+ for (Confirmation confirmation : acceptableResponses)
+ {
+ result.add(getLabel(confirmation));
+ }
+
+ return result.toArray(new String[result.size()]);
+ }
+
+ private static List<Confirmation> inOrder(Collection<Confirmation> confirmations)
+ {
+ List<Confirmation> result = new ArrayList<Confirmation>(confirmations);
+ Collections.sort(result);
+ return result;
+ }
+
+ private static String getLabel(Confirmation confirmation)
+ {
+ switch (confirmation)
+ {
+ case OK:
+ return IDialogConstants.OK_LABEL;
+ case CANCEL:
+ return IDialogConstants.CANCEL_LABEL;
+ case YES:
+ return IDialogConstants.YES_LABEL;
+ case NO:
+ return IDialogConstants.NO_LABEL;
+ }
+
+ throw new IllegalArgumentException(confirmation.name());
+ }
+}
diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/InteractiveConfirmationProvider.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/InteractiveConfirmationProvider.java
new file mode 100644
index 0000000000..f740ccc449
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/InteractiveConfirmationProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.util.ui.confirmation;
+
+import org.eclipse.net4j.util.confirmation.Confirmation;
+import org.eclipse.net4j.util.confirmation.IConfirmationProvider;
+import org.eclipse.net4j.util.factory.ProductCreationException;
+import org.eclipse.net4j.util.ui.UIUtil;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+
+import java.util.Set;
+
+/**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 3.4
+ */
+public class InteractiveConfirmationProvider implements IConfirmationProvider
+{
+ public InteractiveConfirmationProvider()
+ {
+ }
+
+ public boolean isInteractive()
+ {
+ return true;
+ }
+
+ public Confirmation confirm(final String subject, final String message, final Set<Confirmation> acceptable,
+ final Confirmation suggestion)
+ {
+ final Confirmation[] confirmation = new Confirmation[1];
+ final Display display = UIUtil.getDisplay();
+ display.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ Shell shell;
+
+ try
+ {
+ IWorkbenchWindow window = UIUtil.getActiveWorkbenchWindow();
+ shell = window.getShell();
+ }
+ catch (Exception ex)
+ {
+ shell = new Shell(display);
+ }
+
+ confirmation[0] = ConfirmationDialog.openConfirm(shell, subject, message, acceptable, suggestion);
+ }
+ });
+
+ return confirmation[0];
+ }
+
+ /**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 3.4
+ */
+ public static class Factory extends IConfirmationProvider.Factory
+ {
+ public Factory()
+ {
+ super(INTERACTIVE_TYPE);
+ }
+
+ public Object create(String description) throws ProductCreationException
+ {
+ return new InteractiveConfirmationProvider();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/package-info.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/package-info.java
new file mode 100644
index 0000000000..86119f8165
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/confirmation/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+
+/**
+ * Confirmation dialogs.
+ *
+ * @since 3.4
+ */
+package org.eclipse.net4j.util.ui.confirmation;
+
diff --git a/plugins/org.eclipse.net4j.util/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j.util/META-INF/MANIFEST.MF
index 4b2971ddf7..0ced9af530 100644
--- a/plugins/org.eclipse.net4j.util/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.net4j.util/META-INF/MANIFEST.MF
@@ -25,6 +25,7 @@ Export-Package: org.eclipse.net4j.internal.util.bundle;version="3.4.0";x-friends
org.eclipse.net4j.util.cache;version="3.4.0",
org.eclipse.net4j.util.collection;version="3.4.0",
org.eclipse.net4j.util.concurrent;version="3.4.0",
+ org.eclipse.net4j.util.confirmation;version="3.4.0",
org.eclipse.net4j.util.container;version="3.4.0",
org.eclipse.net4j.util.container.delegate;version="3.4.0",
org.eclipse.net4j.util.event;version="3.4.0",
diff --git a/plugins/org.eclipse.net4j.util/plugin.xml b/plugins/org.eclipse.net4j.util/plugin.xml
index 62eb37e2e2..dbe10e45c2 100644
--- a/plugins/org.eclipse.net4j.util/plugin.xml
+++ b/plugins/org.eclipse.net4j.util/plugin.xml
@@ -9,6 +9,7 @@
Contributors:
Eike Stepper - initial API and implementation
+ Christian W. Damus (CEA LIST) - bug 418454
-->
<plugin>
@@ -38,6 +39,11 @@
productGroup="org.eclipse.net4j.authenticators"
type="file"
class="org.eclipse.net4j.util.security.FileAuthenticatorFactory"/>
+ <factory
+ productGroup="org.eclipse.net4j.util.confirmationProviders"
+ type="default"
+ class="org.eclipse.net4j.util.confirmation.IConfirmationProvider.Factory.Default">
+ </factory>
</extension>
</plugin>
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/Confirmation.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/Confirmation.java
new file mode 100644
index 0000000000..b7a721e87e
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/Confirmation.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.util.confirmation;
+
+/**
+ * An enumeration of possible answers to a {@linkplain IConfirmationProvider request for confirmation}.
+ *
+ * @author Christian W. Damus (CEA LIST)
+ * @since 3.4
+ *
+ * @see IConfirmationProvider
+ */
+public enum Confirmation
+{
+ // Order negative answers after positive answers
+ OK, CANCEL, YES, NO;
+}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/IConfirmationProvider.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/IConfirmationProvider.java
new file mode 100644
index 0000000000..2f9cf5f2f2
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/confirmation/IConfirmationProvider.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.util.confirmation;
+
+import org.eclipse.net4j.util.factory.ProductCreationException;
+
+import java.util.Set;
+
+/**
+ * A provider of user confirmation of some action.
+ *
+ * @author Christian W. Damus (CEA LIST)
+ * @since 3.4
+ */
+public interface IConfirmationProvider
+{
+ /**
+ * Requests confirmation of some action/operation/consequence pertaining to a
+ * {@code subject} and described by a {@code message}. Any of the non-empty
+ * set of {@code acceptable} responses may be returned, and the requester
+ * may optionally provide a {@code suggestion} of a suitable/safe default
+ * answer.
+ */
+ public Confirmation confirm(String subject, String message, Set<Confirmation> acceptable, Confirmation suggestion);
+
+ public boolean isInteractive();
+
+ /**
+ * @author Christian W. Damus (CEA LIST)
+ * @since 3.4
+ */
+ public static abstract class Factory extends org.eclipse.net4j.util.factory.Factory
+ {
+ public static final String PRODUCT_GROUP = "org.eclipse.net4j.util.confirmationProviders"; //$NON-NLS-1$
+
+ public static final String DEFAULT_TYPE = "default"; //$NON-NLS-1$
+
+ public static final String INTERACTIVE_TYPE = "interactive"; //$NON-NLS-1$
+
+ public Factory(String type)
+ {
+ super(PRODUCT_GROUP, type);
+ }
+
+ /**
+ * @author Christian W. Damus (CEA LIST)
+ * @since 3.4
+ */
+ public static class Default extends Factory
+ {
+ public Default()
+ {
+ super(DEFAULT_TYPE);
+ }
+
+ public Object create(String description) throws ProductCreationException
+ {
+ return new ConfirmationProvider();
+ }
+
+ private static final class ConfirmationProvider implements IConfirmationProvider
+ {
+ public boolean isInteractive()
+ {
+ return false;
+ }
+
+ public Confirmation confirm(String subject, String message, Set<Confirmation> acceptable,
+ Confirmation suggestion)
+ {
+ // Just return the suggestion, or else the greatest of the acceptable set
+ return suggestion != null ? suggestion : max(acceptable);
+ }
+
+ private Confirmation max(Set<Confirmation> confirmations)
+ {
+ Confirmation[] all = Confirmation.values();
+ for (int i = all.length - 1; i >= 0; i--)
+ {
+ if (confirmations.contains(all[i]))
+ {
+ return all[i];
+ }
+ }
+
+ return null;
+ }
+ }
+ }
+ }
+
+ /**
+ * @author Christian W. Damus (CEA LIST)
+ * @since 3.4
+ */
+ public static interface Provider
+ {
+ public IConfirmationProvider getConfirmationProvider();
+ }
+}
diff --git a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
index bfa10c796a..03281b9408 100644
--- a/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.net4j/META-INF/MANIFEST.MF
@@ -37,6 +37,7 @@ Export-Package: org.eclipse.internal.net4j;version="4.3.0";
org.eclipse.net4j.connector;version="4.3.0",
org.eclipse.net4j.protocol;version="4.3.0",
org.eclipse.net4j.signal;version="4.3.0",
+ org.eclipse.net4j.signal.confirmation;version="4.3.0",
org.eclipse.net4j.signal.heartbeat;version="4.3.0",
org.eclipse.net4j.signal.security;version="4.3.0",
org.eclipse.net4j.signal.wrapping;version="4.3.0",
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationIndication.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationIndication.java
new file mode 100644
index 0000000000..d09ad552e6
--- /dev/null
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationIndication.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.signal.confirmation;
+
+import org.eclipse.net4j.signal.IndicationWithMonitoring;
+import org.eclipse.net4j.signal.SignalProtocol;
+import org.eclipse.net4j.util.confirmation.Confirmation;
+import org.eclipse.net4j.util.confirmation.IConfirmationProvider;
+import org.eclipse.net4j.util.io.ExtendedDataInputStream;
+import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+
+import org.eclipse.internal.net4j.bundle.OM;
+
+/**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 4.3
+ */
+public class ConfirmationIndication<PROTOCOL extends SignalProtocol<?> & IConfirmationProvider.Provider> extends
+ IndicationWithMonitoring
+{
+ private ConfirmationPrompt prompt;
+
+ public ConfirmationIndication(SignalProtocol<?> protocol, short id, String name)
+ {
+ super(protocol, id, name);
+ }
+
+ public ConfirmationIndication(SignalProtocol<?> protocol, short signalID)
+ {
+ super(protocol, signalID);
+ }
+
+ public ConfirmationIndication(SignalProtocol<?> protocol, Enum<?> literal)
+ {
+ super(protocol, literal);
+ }
+
+ @Override
+ protected void indicating(ExtendedDataInputStream in, OMMonitor monitor) throws Exception
+ {
+ prompt = ConfirmationPrompt.read(in);
+ }
+
+ protected final ConfirmationPrompt getPrompt()
+ {
+ return prompt;
+ }
+
+ @Override
+ protected void responding(ExtendedDataOutputStream out, OMMonitor monitor) throws Exception
+ {
+ monitor.begin();
+ Async async = monitor.forkAsync();
+
+ try
+ {
+ IConfirmationProvider confirmationProvider = getConfirmationProvider();
+ if (confirmationProvider == null)
+ {
+ throw new IllegalStateException("No confirmation provider configured"); //$NON-NLS-1$
+ }
+
+ Confirmation confirmation = confirmationProvider.confirm(prompt.getSubject(), prompt.getMessage(),
+ prompt.getAcceptableResponses(), prompt.getSuggestedResponse());
+ if (confirmation == null)
+ {
+ throw new IllegalStateException("No confirmation provided"); //$NON-NLS-1$
+ }
+
+ out.writeBoolean(true);
+ out.writeEnum(confirmation);
+ }
+ catch (Throwable ex)
+ {
+ out.writeBoolean(false);
+ OM.LOG.error(ex);
+ }
+ finally
+ {
+ async.stop();
+ monitor.done();
+ }
+ }
+
+ public IConfirmationProvider getConfirmationProvider()
+ {
+ return ((IConfirmationProvider.Provider)getProtocol()).getConfirmationProvider();
+ }
+}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationPrompt.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationPrompt.java
new file mode 100644
index 0000000000..0ae123d57e
--- /dev/null
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationPrompt.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.signal.confirmation;
+
+import org.eclipse.net4j.util.confirmation.Confirmation;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 4.3
+ */
+public class ConfirmationPrompt
+{
+ private final String subject;
+
+ private final String message;
+
+ private final Set<Confirmation> acceptableResponses;
+
+ private final Confirmation suggestedResponse;
+
+ public ConfirmationPrompt(String subject, String message, Confirmation suggestedResponse,
+ Confirmation acceptableResponse, Confirmation... more)
+ {
+ this(subject, message, suggestedResponse, EnumSet.of(acceptableResponse, more));
+ }
+
+ public ConfirmationPrompt(String subject, String message, Confirmation suggestedResponse,
+ Collection<Confirmation> acceptableResponses)
+ {
+ this.subject = subject;
+ this.message = message;
+ this.acceptableResponses = EnumSet.copyOf(acceptableResponses);
+ this.suggestedResponse = suggestedResponse;
+ }
+
+ public String getSubject()
+ {
+ return subject;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public Set<Confirmation> getAcceptableResponses()
+ {
+ return acceptableResponses;
+ }
+
+ public Confirmation getSuggestedResponse()
+ {
+ return suggestedResponse;
+ }
+
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ out.writeString(subject);
+ out.writeString(message);
+ out.writeEnum(suggestedResponse);
+ out.writeInt(acceptableResponses.size());
+ for (Confirmation acceptable : acceptableResponses)
+ {
+ out.writeEnum(acceptable);
+ }
+ }
+
+ public static ConfirmationPrompt read(ExtendedDataInput in) throws IOException
+ {
+ String subject = in.readString();
+ String message = in.readString();
+ Confirmation suggestion = in.readEnum(Confirmation.class);
+ EnumSet<Confirmation> acceptable = EnumSet.noneOf(Confirmation.class);
+ int count = in.readInt();
+ for (int i = 0; i < count; i++)
+ {
+ acceptable.add(in.readEnum(Confirmation.class));
+ }
+
+ return new ConfirmationPrompt(subject, message, suggestion, acceptable);
+ }
+}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationRequest.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationRequest.java
new file mode 100644
index 0000000000..44518bedfe
--- /dev/null
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/ConfirmationRequest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+package org.eclipse.net4j.signal.confirmation;
+
+import org.eclipse.net4j.signal.RequestWithMonitoring;
+import org.eclipse.net4j.signal.SignalProtocol;
+import org.eclipse.net4j.util.confirmation.Confirmation;
+import org.eclipse.net4j.util.io.ExtendedDataInputStream;
+import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+/**
+ * @author Christian W. Damus (CEA LIST)
+ *
+ * @since 4.3
+ */
+public class ConfirmationRequest extends RequestWithMonitoring<Confirmation>
+{
+ private final ConfirmationPrompt prompt;
+
+ public ConfirmationRequest(SignalProtocol<?> protocol, short signalID, String name, ConfirmationPrompt prompt)
+ {
+ super(protocol, signalID, name);
+ this.prompt = prompt;
+ }
+
+ public ConfirmationRequest(SignalProtocol<?> protocol, short signalID, ConfirmationPrompt prompt)
+ {
+ super(protocol, signalID);
+ this.prompt = prompt;
+ }
+
+ public ConfirmationRequest(SignalProtocol<?> protocol, Enum<?> literal, ConfirmationPrompt prompt)
+ {
+ super(protocol, literal);
+ this.prompt = prompt;
+ }
+
+ @Override
+ protected void requesting(ExtendedDataOutputStream out, OMMonitor monitor) throws Exception
+ {
+ prompt.write(out);
+ }
+
+ @Override
+ protected Confirmation confirming(ExtendedDataInputStream in, OMMonitor monitor) throws Exception
+ {
+ if (in.readBoolean())
+ {
+ return in.readEnum(Confirmation.class);
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/package-info.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/package-info.java
new file mode 100644
index 0000000000..a9d2bd92d4
--- /dev/null
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/confirmation/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus (CEA LIST) - initial API and implementation
+ */
+
+/**
+ * Reusable implementation of a server-to-client confirmation signal and related API.
+ *
+ * @since 4.3
+ */
+package org.eclipse.net4j.signal.confirmation;
+

Back to the top