| /******************************************************************************* |
| * Copyright (c) 2007, 2018 Borland Software Corporation and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * Borland Software Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.m2m.internal.qvt.oml.ui.wizards; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.m2m.internal.qvt.oml.project.QvtProjectUtil; |
| import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilderConfig; |
| import org.eclipse.m2m.internal.qvt.oml.project.model.IQvtElement; |
| import org.eclipse.m2m.internal.qvt.oml.project.model.IQvtNamespace; |
| import org.eclipse.m2m.internal.qvt.oml.project.model.IQvtProject; |
| import org.eclipse.m2m.internal.qvt.oml.project.model.QvtModelException; |
| import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin; |
| import org.eclipse.m2m.internal.qvt.oml.ui.QvtPluginImages; |
| import org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.QvtProjectLabelProvider; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; |
| import org.eclipse.ui.dialogs.ISelectionStatusValidator; |
| import org.eclipse.ui.model.IWorkbenchAdapter; |
| import org.eclipse.ui.model.WorkbenchContentProvider; |
| import org.eclipse.ui.model.WorkbenchLabelProvider; |
| import org.eclipse.ui.views.navigator.ResourceComparator; |
| |
| public class SourceDestinationChooser extends ElementTreeSelectionDialog { |
| |
| private IQvtNamespace selectedNamespace; |
| |
| |
| private SourceDestinationChooser(Shell parent, Object initialSelection) { |
| super(parent, createWorkbenchDelegatingProvider(), new ContentProviderImpl()); |
| |
| setComparator(new ResourceComparator(ResourceComparator.NAME)); |
| setInput(ResourcesPlugin.getWorkspace().getRoot()); |
| if(initialSelection != null) { |
| setInitialSelection(initialSelection); |
| } |
| |
| setAllowMultiple(false); |
| } |
| |
| @Override |
| protected TreeViewer createTreeViewer(Composite parent) { |
| TreeViewer viewer = super.createTreeViewer(parent); |
| viewer.addFilter(new ViewerFilter() { |
| @Override |
| public boolean select(Viewer viewer, Object parentElement, Object element) { |
| IProject project = adaptObject(element, IProject.class); |
| if(project != null) { |
| return QvtProjectUtil.isQvtProject(project); |
| } |
| |
| return true; |
| } |
| }); |
| |
| viewer.expandToLevel(2); |
| |
| return viewer; |
| } |
| |
| <T> T getSelectedElement(Class<T> type) { |
| ISelection selection = getTreeViewer().getSelection(); |
| if(!selection.isEmpty() && selection instanceof IStructuredSelection) { |
| IStructuredSelection structuredSelection = (IStructuredSelection) selection; |
| return adaptObject(structuredSelection.getFirstElement(), type); |
| } |
| return null; |
| } |
| |
| /** |
| * @param initialPath initial context path or null |
| */ |
| public static IContainer chooseSourceContainer(Shell shell, IContainer initialSourceContainer) { |
| Object initialSelection = initialSourceContainer != null && initialSourceContainer.getType() != IResource.PROJECT ? |
| new SourceContainer(initialSourceContainer) : initialSourceContainer; |
| |
| SourceDestinationChooser dialog = new SourceDestinationChooser(shell, initialSelection); |
| dialog.setTitle(Messages.SourceDestinationChooser_SourceContainerSelectionTitle); |
| dialog.setMessage(Messages.SourceDestinationChooser_ChooseSourceFolder); |
| |
| dialog.addFilter(new ViewerFilter() { |
| @Override |
| public boolean select(Viewer viewer, Object parentElement, Object element) { |
| IProject project = adaptObject(element, IProject.class); |
| return (project != null || element instanceof SourceContainer); |
| } |
| }); |
| |
| dialog.setValidator(dialog.createSourceContainerValidator()); |
| |
| if(dialog.open() == Window.OK) { |
| if(dialog.selectedNamespace != null) { |
| // deduce the source container from the chosen name-space |
| try { |
| IResource resource = dialog.selectedNamespace.getQvtProject().getDefaultNamespace().getUnderlyingResource(); |
| assert resource instanceof IContainer; |
| |
| return resource instanceof IContainer ? (IContainer) resource : null; |
| } catch (QvtModelException e) { |
| QVTUIPlugin.log(e); |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static IQvtNamespace chooseNamespaceFolder(Shell shell) { |
| final SourceDestinationChooser dialog = new SourceDestinationChooser(shell, null); |
| |
| dialog.setTitle(Messages.SourceDestinationChooser_NamespaceSelectionTitle); |
| dialog.setMessage(Messages.SourceDestinationChooser_ChooseCUNamespaceFolder); |
| |
| dialog.setValidator(dialog.createNamespaceValidator()); |
| |
| dialog.addFilter(new ViewerFilter() { |
| @Override |
| public boolean select(Viewer viewer, Object parentElement, Object element) { |
| // show project, source folders and name-spaces |
| if(element instanceof SourceContainer) { |
| return true; |
| } |
| IContainer container = adaptObject(element, IContainer.class); |
| if(container == null) { |
| return false; |
| } |
| return container.getType() == IResource.PROJECT || |
| (container.getType() == IResource.FOLDER && QvtProjectUtil.isNamespaceFolder((IFolder)container)); |
| } |
| }); |
| |
| if(dialog.open() == Window.OK) { |
| return dialog.selectedNamespace; |
| } |
| |
| return null; |
| } |
| |
| private ISelectionStatusValidator createNamespaceValidator() { |
| return new ISelectionStatusValidator() { |
| public IStatus validate(Object[] selection) { |
| if(selection == null || selection.length == 0) { |
| return QVTUIPlugin.createStatus(IStatus.ERROR, Messages.SourceDestinationChooser_NoNamespaceSelected, null); |
| } |
| |
| IQvtNamespace namespace = computeQvtNamespaceSelection(); |
| IStatus status = null; |
| |
| if(namespace == null) { |
| status = QVTUIPlugin.createStatus(IStatus.ERROR, "Not a namespace selection", null); //$NON-NLS-1$ |
| } |
| else if(IQvtNamespace.DEFAULT_NAMESPACE_NAME.equals(namespace.getName())) { |
| status = QVTUIPlugin.createStatus(IStatus.OK, "The default namespace will be applied", null); //$NON-NLS-1$ |
| } else { |
| status = QVTUIPlugin.createStatus(IStatus.OK, "", null); //$NON-NLS-1$ |
| } |
| |
| if(status.isOK()) { |
| selectedNamespace = namespace; |
| } |
| |
| return status; |
| } |
| }; |
| } |
| |
| private ISelectionStatusValidator createSourceContainerValidator() { |
| return new ISelectionStatusValidator() { |
| public IStatus validate(Object[] selection) { |
| if(selection == null || selection.length == 0) { |
| return QVTUIPlugin.createStatus(IStatus.ERROR, Messages.SourceDestinationChooser_NoSourceContainerSelected, null); |
| } |
| |
| IContainer container = getSelectedElement(IContainer.class); |
| IQvtNamespace namespace = computeQvtNamespaceSelection(); |
| IStatus status = null; |
| |
| // we expect the default name-space only here, as it corresponds to the source container |
| if(namespace == null || !IQvtNamespace.DEFAULT_NAMESPACE_NAME.equals(namespace.getName()) || |
| (container instanceof IProject && !container.getFullPath().equals(namespace.getFullPath())) ) { |
| |
| status = QVTUIPlugin.createStatus(IStatus.ERROR, "Not a source container selection", null); //$NON-NLS-1$ |
| } else if(container != null) { |
| if(!container.exists()) { |
| status = QVTUIPlugin.createStatus(IStatus.ERROR, "Source container does not exist", null); //$NON-NLS-1$ |
| } else { |
| status = QVTUIPlugin.createStatus(IStatus.OK, "", null); //$NON-NLS-1$ |
| } |
| } |
| |
| if(status.isOK()) { |
| selectedNamespace = namespace; |
| } else { |
| selectedNamespace = null; |
| } |
| |
| return status; |
| } |
| }; |
| } |
| |
| private IQvtNamespace computeQvtNamespaceSelection() { |
| IQvtProject project = null; |
| IContainer container = getSelectedElement(IContainer.class); |
| if(container != null) { |
| project = QvtProjectUtil.getQvtProject(container.getProject()); |
| } |
| |
| if(project != null) { |
| try { |
| IQvtElement qvtSelection = project.findElement(container, true); |
| if(qvtSelection != null) { |
| if(qvtSelection.getElementType() == IQvtElement.QVT_PROJECT) { |
| return ((IQvtProject) qvtSelection).getDefaultNamespace(); |
| } else if(qvtSelection.getElementType() == IQvtElement.QVT_NAMESPACE) { |
| return (IQvtNamespace) qvtSelection; |
| } |
| } |
| |
| } catch (QvtModelException e) { |
| QVTUIPlugin.log(e); |
| } |
| |
| } |
| |
| return null; |
| } |
| |
| private static ILabelProvider createWorkbenchDelegatingProvider() { |
| return new LabelProvideImpl(new QvtProjectLabelProvider()); |
| } |
| |
| private static class SourceContainer implements IAdaptable, IWorkbenchAdapter { |
| private final IContainer resource; |
| |
| SourceContainer(IContainer resource) { |
| this.resource = resource; |
| } |
| |
| public Object[] getChildren(Object o) { |
| try { |
| if(resource.exists()) { |
| return resource.members(); |
| } |
| } catch (CoreException e) { |
| QVTUIPlugin.log(e.getStatus()); |
| } |
| return new Object[0]; |
| } |
| |
| public ImageDescriptor getImageDescriptor(Object object) { |
| return QvtPluginImages.getInstance().getImageDescriptor(QvtPluginImages.SRC_CONTAINER); |
| } |
| |
| public String getLabel(Object o) { |
| return resource.getProjectRelativePath().toString(); |
| } |
| |
| public Object getParent(Object o) { |
| return resource.getProject(); |
| } |
| |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public Object getAdapter(Class adapter) { |
| return adaptObject(resource, adapter); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if(o instanceof SourceContainer) { |
| SourceContainer another = (SourceContainer) o; |
| return resource.equals(another.resource); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| return resource.getFullPath().hashCode(); |
| } |
| } |
| |
| private static class ContentProviderImpl extends WorkbenchContentProvider { |
| @Override |
| public Object[] getChildren(Object element) { |
| |
| Object[] regularChildren = super.getChildren(element); |
| IProject project = adaptObject(element, IProject.class); |
| if(project != null) { |
| // add top level source container if the project itself is not a container |
| QVTOBuilderConfig config = getBuilderConfig(project); |
| if (config != null) { |
| IContainer sourceContainer = config.getSourceContainer(); |
| if(sourceContainer.getType() != IResource.PROJECT) { |
| List<Object> children = new ArrayList<Object>(regularChildren.length + 1); |
| children.add(new SourceContainer(sourceContainer)); |
| return children.toArray(); |
| } |
| } |
| } |
| return super.getChildren(element); |
| } |
| |
| @Override |
| public Object getParent(Object element) { |
| SourceContainer container = adaptObject(element, SourceContainer.class); |
| if(container != null) { |
| // the top level container additional node -> make the project the parent |
| return container.resource.getProject(); |
| } |
| return super.getParent(element); |
| } |
| } |
| |
| private static class LabelProvideImpl extends LabelProvider { |
| |
| private ILabelProvider delegate; |
| private ILabelProvider provider; |
| |
| protected LabelProvideImpl(ILabelProvider delegate) { |
| this.provider = new WorkbenchLabelProvider(); |
| this.delegate = delegate; |
| |
| assert delegate != null; |
| assert provider != null; |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| Image image = delegate.getImage(element); |
| if(image != null) { |
| return image; |
| } |
| |
| return provider.getImage(element); |
| } |
| |
| @Override |
| public String getText(Object element) { |
| if(element instanceof IContainer) { |
| IContainer resource = (IContainer) element; |
| if(resource.getType() != IResource.PROJECT) { |
| QVTOBuilderConfig config = getBuilderConfig(resource); |
| if(config != null) { |
| IContainer sourceContainer = config.getSourceContainer(); |
| if(sourceContainer.getType() != IResource.PROJECT && resource.equals(sourceContainer)) { |
| return resource.getProjectRelativePath().toString(); |
| } |
| } |
| } |
| } |
| |
| String text = delegate.getText(element); |
| if(text != null) { |
| return text; |
| } |
| |
| return provider.getText(element); |
| } |
| } |
| |
| private static <T> T adaptObject(Object adaptee, Class<T> adapterType) { |
| if(adapterType.isInstance(adaptee)) { |
| return adapterType.cast(adaptee); |
| } else if (adaptee instanceof IAdaptable) { |
| IAdaptable adaptable = (IAdaptable) adaptee; |
| return adapterType.cast(adaptable.getAdapter(adapterType)); |
| } |
| |
| return null; |
| } |
| |
| |
| |
| private static QVTOBuilderConfig getBuilderConfig(Object element) { |
| try { |
| IResource resource = adaptObject(element, IResource.class); |
| if (resource != null) { |
| IProject project = resource.getProject(); |
| if(QvtProjectUtil.isQvtProject(project)) { |
| return QVTOBuilderConfig.getConfig(project); |
| } |
| } |
| } catch (CoreException e) { |
| return null; |
| } |
| |
| return null; |
| } |
| } |