| /* |
| * Copyright (c) 2013, 2015 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.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; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| 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; |
| |
| import org.eclipse.core.commands.ExecutionEvent; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorReference; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PartInitException; |
| 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 |
| * in the context of the currently selected {@link CDOSession}, with the help |
| * of an optional {@link ISecurityManagementContext} adapter. |
| * |
| * @author Christian W. Damus (CEA LIST) |
| */ |
| public class ManageSecurityHandler extends LongRunningHandler |
| { |
| private IWorkbenchPart part; |
| |
| private ISecurityManagementContext context; |
| |
| private CDOSession session; |
| |
| public ManageSecurityHandler() |
| { |
| } |
| |
| @Override |
| protected void extractEventDetails(ExecutionEvent event) |
| { |
| super.extractEventDetails(event); |
| |
| part = HandlerUtil.getActivePart(event); |
| context = getContext(event); |
| } |
| |
| @Override |
| protected void preRun() throws Exception |
| { |
| if (part == null) |
| { |
| // No workbench page available in which to open the editor |
| cancel(); |
| return; |
| } |
| |
| setSession(getSession()); |
| if (session != null && !session.isClosed()) |
| { |
| final IWorkbenchPage page = part.getSite().getPage(); |
| |
| IEditorPart existing = findEditor(page, session); |
| if (existing != null) |
| { |
| // Activate this editor and we're done |
| cancel(); |
| page.activate(existing); |
| } |
| } |
| } |
| |
| protected CDOSession getSession() |
| { |
| return UIUtil.adaptElement(getSelection(), CDOSession.class); |
| } |
| |
| protected void setSession(CDOSession session) |
| { |
| this.session = session; |
| } |
| |
| @Override |
| protected void doExecute(IProgressMonitor progressMonitor) throws Exception |
| { |
| // Open a new security editor |
| final CDOView[] view = new CDOView[] { context.connect(session) }; |
| if (view[0] == null || view[0].isClosed()) |
| { |
| showWarning(Messages.ManageSecurityHandler_0, Messages.ManageSecurityHandler_1); |
| return; |
| } |
| |
| try |
| { |
| final CDOResource resource = context.getSecurityResource(view[0]); |
| if (resource == null) |
| { |
| showWarning(Messages.ManageSecurityHandler_0, Messages.ManageSecurityHandler_2); |
| } |
| else |
| { |
| UIUtil.getDisplay().syncExec(new Runnable() |
| { |
| |
| public void run() |
| { |
| IEditorInput input = CDOEditorUtil.createCDOEditorInput(view[0], resource.getPath(), false); |
| |
| try |
| { |
| IEditorPart editor = part.getSite().getPage().openEditor(input, CDOSecurityFormEditor.ID); |
| if (editor != null) |
| { |
| hookCloseListener(editor, context, view[0]); |
| view[0] = null; // Don't disconnect it until later |
| } |
| } |
| catch (PartInitException e) |
| { |
| StatusManager.getManager().handle(e.getStatus(), StatusManager.SHOW); |
| } |
| } |
| }); |
| } |
| } |
| finally |
| { |
| if (view[0] != null) |
| { |
| context.disconnect(view[0]); |
| } |
| } |
| } |
| |
| protected void showWarning(final String title, final String message) |
| { |
| UIUtil.getDisplay().syncExec(new Runnable() |
| { |
| |
| public void run() |
| { |
| MessageDialog.openWarning(part.getSite().getShell(), title, message); |
| } |
| }); |
| } |
| |
| IEditorPart findEditor(IWorkbenchPage page, CDOSession session) |
| { |
| for (IEditorReference next : page.getEditorReferences()) |
| { |
| if (CDOSecurityFormEditor.ID.equals(next.getId())) |
| { |
| IEditorPart candidate = next.getEditor(false); |
| if (candidate != null) |
| { |
| IEditorInput input = candidate.getEditorInput(); |
| if (input instanceof CDOEditorInput) |
| { |
| CDOView view = ((CDOEditorInput)input).getView(); |
| if (view != null && !view.isClosed() && session.equals(view.getSession())) |
| { |
| return candidate; |
| } |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| ISecurityManagementContext getContext(ExecutionEvent event) |
| { |
| ISecurityManagementContext result = null; |
| |
| IWorkbenchPart part = HandlerUtil.getActivePart(event); |
| if (part != null) |
| { |
| result = part.getAdapter(ISecurityManagementContext.class); |
| } |
| |
| if (result == null) |
| { |
| result = ISecurityManagementContext.DEFAULT; |
| } |
| |
| return result; |
| } |
| |
| private void hookCloseListener(final IEditorPart editor, final ISecurityManagementContext context, final CDOView view) |
| { |
| final IWorkbenchPage page = editor.getSite().getPage(); |
| page.addPartListener(new IPartListener() |
| { |
| private final IEditorInput input = editor.getEditorInput(); |
| |
| private final Set<IEditorPart> openEditors = new java.util.HashSet<IEditorPart>(); |
| |
| { |
| openEditors.add(editor); |
| } |
| |
| public void partClosed(IWorkbenchPart part) |
| { |
| openEditors.remove(part); |
| if (openEditors.isEmpty()) |
| { |
| // No more editors using this view |
| context.disconnect(view); |
| page.removePartListener(this); |
| } |
| } |
| |
| public void partOpened(IWorkbenchPart part) |
| { |
| if (part instanceof IEditorPart) |
| { |
| IEditorPart editor = (IEditorPart)part; |
| if (input.equals(editor.getEditorInput())) |
| { |
| // The user opened the advanced-mode editor from the form editor |
| openEditors.add(editor); |
| } |
| } |
| } |
| |
| public void partDeactivated(IWorkbenchPart part) |
| { |
| // Pass |
| } |
| |
| public void partBroughtToTop(IWorkbenchPart part) |
| { |
| // Pass |
| } |
| |
| public void partActivated(IWorkbenchPart part) |
| { |
| // Pass |
| } |
| }); |
| } |
| |
| /** |
| * 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; |
| } |
| } |
| } |