/*******************************************************************************
* Copyright (c) 2007, 2014 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.common.ui.controls;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.m2m.internal.qvt.oml.common.MDAConstants;
import org.eclipse.m2m.internal.qvt.oml.common.project.DeployedTransformation;
import org.eclipse.m2m.internal.qvt.oml.common.project.TransformationRegistry;
import org.eclipse.m2m.internal.qvt.oml.common.ui.CommonPluginImages;
import org.eclipse.m2m.internal.qvt.oml.common.ui.controls.UniSelectTransformationControl.ISelectionListener.TreeAction;
import org.eclipse.m2m.internal.qvt.oml.common.ui.launch.Messages;
import org.eclipse.m2m.internal.qvt.oml.common.ui.launch.TransformationControls;
import org.eclipse.m2m.internal.qvt.oml.emf.util.EmfUtil;
import org.eclipse.m2m.internal.qvt.oml.emf.util.URIUtils;
import org.eclipse.m2m.internal.qvt.oml.emf.util.WorkspaceUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.progress.DeferredTreeContentManager;
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
import org.eclipse.ui.progress.PendingUpdateAdapter;
import org.eclipse.ui.progress.WorkbenchJob;
public class UniSelectTransformationControl extends Composite {
public static final IResourceFilter QVTO_FILE_FILTER = new IResourceFilter() {
public boolean accept(IResource resource) {
return resource instanceof IFile && MDAConstants.QVTO_FILE_EXTENSION.equalsIgnoreCase(resource.getFileExtension());
}
};
public static interface IResourceFilter {
boolean accept(IResource resource);
}
public static interface ISelectionListener {
enum TreeAction {
NONE,
EXPAND,
SELECT
}
boolean accept(URI uri);
TreeAction getTreeAction(URI uri);
IStatus selectionChanged(URI uri);
}
public static abstract class SelectionListenerAdapter implements ISelectionListener {
private final ISelectionListener delegate;
public SelectionListenerAdapter(ISelectionListener delegate) {
this.delegate = delegate;
}
public SelectionListenerAdapter() {
delegate = null;
}
public boolean accept(URI uri) {
if (delegate != null) {
return delegate.accept(uri);
}
return true;
}
public TreeAction getTreeAction(URI uri) {
if (delegate != null) {
return delegate.getTreeAction(uri);
}
return TreeAction.NONE;
}
}
public UniSelectTransformationControl(Composite parentComposite, IResourceFilter resourceFilter,
TransformationRegistry transfRegistry, TransformationRegistry.Filter transfFilter, ISelectionListener listener) {
super(parentComposite,SWT.NULL);
myResourceFilter = resourceFilter;
mySelectionListener = listener;
setLayout(new GridLayout());
setLayoutData(new GridData(GridData.FILL_BOTH));
List<ITreeContentProviderEx> contentProviders = new ArrayList<ITreeContentProviderEx>(2);
contentProviders.add(new WorkspaceContentProvider());
contentProviders.add(new DeployedTransformationContentProvider());
List<ILabelProviderEx> labelProviders = new ArrayList<ILabelProviderEx>(3);
labelProviders.add(new LabelProviderDelegate(new WorkbenchLabelProvider()) {
public boolean canHandle(Object element) {
return element instanceof IResource;
}
});
labelProviders.add(new LabelProviderDelegate(new QvtDeployedTransformationLabelProvider()) {
public boolean canHandle(Object element) {
return element instanceof DeployedTransformation
|| element instanceof DeployedTransformationRoot;
}
@Override
public String getText(Object element) {
if (element instanceof DeployedTransformationRoot) {
return Messages.UniSelectTransformationControl_DeployedTransformations;
}
return super.getText(element);
}
@Override
public Image getImage(Object element) {
if (element instanceof DeployedTransformationRoot) {
return CommonPluginImages.getInstance().getImage(CommonPluginImages.REGISTRY);
}
return super.getImage(element);
}
});
labelProviders.add(new ILabelProviderEx() {
public boolean canHandle(Object element) {
return element instanceof PendingUpdateAdapter;
}
public Image getImage(Object element) {
return CommonPluginImages.getInstance().getImage(CommonPluginImages.ACTIVITY);
}
public String getText(Object element) {
return Messages.UniSelectTransformationControl_fetchingTransformations;
}
public void addListener(ILabelProviderListener listener) {
}
public void dispose() {
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void removeListener(ILabelProviderListener listener) {
}
});
myViewer = new TreeViewer(this, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
myViewer.setContentProvider(new CompositeContentProvider(contentProviders));
myViewer.setLabelProvider(new CompositeLabelProvider(labelProviders));
myViewer.setAutoExpandLevel(DEFAUL_AUTO_EXPAND_LEVEL);
myViewer.addFilter(VIEWER_FILTER);
myViewer.setSorter(VIEWER_SORTER);
myViewer.addSelectionChangedListener(VIEWER_LISTENER);
GridData data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.verticalAlignment = GridData.FILL;
data.grabExcessVerticalSpace = true;
data.heightHint = 250;
data.widthHint = 350;
myViewer.getControl().setLayoutData(data);
myContentManager = new DeferredTreeContentManager(myViewer) {
protected void addChildren(final Object parent, final Object[] children, IProgressMonitor monitor) {
WorkbenchJob updateJob = new WorkbenchJob(Messages.UniSelectTransformationControl_addingTransformations) {
public IStatus runInUIThread(IProgressMonitor updateMonitor) {
// Cancel the job if the tree viewer got closed
if (myViewer.getControl().isDisposed() || updateMonitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
myViewer.add(parent, children);
return Status.OK_STATUS;
}
};
updateJob.setSystem(true);
updateJob.schedule();
try {
updateJob.join();
} catch (InterruptedException e) {
}
}
};
List<Object> inputs = new ArrayList<Object>(2);
inputs.add(ResourcesPlugin.getWorkspace().getRoot());
myDeployedTransformations = transfRegistry.getTransformations(transfFilter);
inputs.add(new DeployedTransformationRoot(myDeployedTransformations));
myViewer.setInput(inputs);
TransformationControls.createLabel(this, Messages.UniSelectTransformationControl_CurrentSelection, TransformationControls.GRID);
myFileNameText = new Text(this, SWT.BORDER);
myFileNameText.setEnabled(false);
myFileNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
}
public URI getSelectedUri() {
return myUri;
}
public void selectTransformationByUri(String uriString) {
URI uri = EmfUtil.makeUri(uriString);
if (uri == null) {
return;
}
if (uri.isPlatformPlugin()) {
for (DeployedTransformation deployedTransf : myDeployedTransformations) {
if (deployedTransf.getUri().equals(uri)) {
StructuredSelection sel = new StructuredSelection(new Object[] {deployedTransf});
myViewer.setSelection(sel);
return;
}
}
final String transfId = uri.toPlatformString(false).replace("/", ""); //$NON-NLS-1$ //$NON-NLS-2$
for (DeployedTransformation deployedTransf : myDeployedTransformations) {
if (deployedTransf.getId().equals(transfId)) {
StructuredSelection sel = new StructuredSelection(new Object[] {deployedTransf});
myViewer.setSelection(sel);
return;
}
}
}
else {
IFile ifile = WorkspaceUtils.getWorkspaceFile(uri);
if (ifile != null) {
StructuredSelection sel = new StructuredSelection(new Object[] {ifile});
myViewer.setSelection(sel);
}
}
}
private void fileSelectionChanged(URI selectedUri) {
if (mySelectionListener != null) {
try {
mySelectionListener.selectionChanged(selectedUri);
}
catch(Exception e) {
}
}
}
private final ViewerFilter VIEWER_FILTER = new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof IContainer) {
return hasMatchingChildrenRecursive((IContainer) element, myResourceFilter);
}
else if (element instanceof IResource) {
return resourceMatches(myResourceFilter, (IResource) element);
}
else {
return true;
}
}
private boolean hasMatchingChildrenRecursive(IContainer container, final IResourceFilter filter) {
try {
IResource[] members = container.members();
for (IResource member : members) {
if (resourceMatches(filter, member)) {
return true;
}
if(member instanceof IContainer) {
boolean has = hasMatchingChildrenRecursive((IContainer) member, filter);
if(has) {
return true;
}
}
}
}
catch (Exception e) {
}
return false;
}
private boolean resourceMatches(final IResourceFilter filter, IResource member) {
return filter == null || filter.accept(member);
}
};
private static final ViewerSorter VIEWER_SORTER = new ViewerSorter() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
boolean folderLeft = (e1 instanceof IContainer);
boolean folderRight = (e2 instanceof IContainer);
if (folderLeft == folderRight) {
return super.compare(viewer, e1, e2);
}
return folderLeft ? -1 : 1;
}
};
private final ISelectionChangedListener VIEWER_LISTENER = new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection)event.getSelection();
myFileNameText.setText(""); //$NON-NLS-1$
myUri = null;
if (selection != null && selection.getFirstElement() instanceof IFile){
IFile ifile = (IFile) selection.getFirstElement();
myUri = URI.createPlatformResourceURI(ifile.getFullPath().toOSString(), false);
myFileNameText.setText(myUri.toString());
}
else if (selection != null && selection.getFirstElement() instanceof DeployedTransformation){
DeployedTransformation transf = (DeployedTransformation) selection.getFirstElement();
myUri = transf.getUri();
myFileNameText.setText(myUri.toString());
}
fileSelectionChanged(myUri);
}
};
private final TreeViewer myViewer;
private Text myFileNameText;
private final IResourceFilter myResourceFilter;
private final ISelectionListener mySelectionListener;
private URI myUri;
private final List<DeployedTransformation> myDeployedTransformations;
private final DeferredTreeContentManager myContentManager;
private static final int DEFAUL_AUTO_EXPAND_LEVEL = 2;
private static interface ITreeContentProviderEx extends ITreeContentProvider {
boolean canHandle(Object element);
}
private static class CompositeContentProvider implements ITreeContentProvider {
CompositeContentProvider(List<ITreeContentProviderEx> providers) {
myProviders = providers;
}
public Object[] getChildren(Object parentElement) {
for (ITreeContentProviderEx provider : myProviders) {
if (provider.canHandle(parentElement)) {
return provider.getChildren(parentElement);
}
}
return null;
}
public Object getParent(Object element) {
for (ITreeContentProviderEx provider : myProviders) {
if (provider.canHandle(element)) {
return provider.getParent(element);
}
}
return null;
}
public boolean hasChildren(Object element) {
for (ITreeContentProviderEx provider : myProviders) {
if (provider.canHandle(element)) {
return provider.hasChildren(element);
}
}
return false;
}
public Object[] getElements(Object inputElement) {
if (inputElement instanceof List<?>) {
return ((List<?>)inputElement).toArray();
}
for (ITreeContentProviderEx provider : myProviders) {
if (provider.canHandle(inputElement)) {
return provider.getChildren(inputElement);
}
}
return null;
}
public void dispose() {
for (ITreeContentProviderEx provider : myProviders) {
provider.dispose();
}
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
for (ITreeContentProviderEx provider : myProviders) {
//if (provider.canHandle(oldInput) || provider.canHandle(newInput)) {
provider.inputChanged(viewer, oldInput, newInput);
//}
}
}
private final List<ITreeContentProviderEx> myProviders;
}
private static interface ILabelProviderEx extends ILabelProvider {
boolean canHandle(Object element);
}
private static class CompositeLabelProvider implements ILabelProvider {
CompositeLabelProvider(List<ILabelProviderEx> providers) {
myProviders = providers;
}
public Image getImage(Object element) {
for (ILabelProviderEx provider : myProviders) {
if (provider.canHandle(element)) {
return provider.getImage(element);
}
}
return null;
}
public String getText(Object element) {
for (ILabelProviderEx provider : myProviders) {
if (provider.canHandle(element)) {
return provider.getText(element);
}
}
return null;
}
public void addListener(ILabelProviderListener listener) {
for (ILabelProviderEx provider : myProviders) {
provider.addListener(listener);
}
}
public void dispose() {
for (ILabelProviderEx provider : myProviders) {
provider.dispose();
}
}
public boolean isLabelProperty(Object element, String property) {
for (ILabelProviderEx provider : myProviders) {
if (provider.canHandle(element)) {
return provider.isLabelProperty(element, property);
}
}
return false;
}
public void removeListener(ILabelProviderListener listener) {
for (ILabelProviderEx provider : myProviders) {
provider.removeListener(listener);
}
}
private final List<ILabelProviderEx> myProviders;
}
private class WorkspaceContentProvider implements ITreeContentProviderEx {
private AbstractDeferredAdapter workspaceContentAdapter;
private IAdapterFactory workspaceContentProviderFactory;
public Object[] getChildren(Object parentElement) {
return getElements(parentElement);
}
public Object getParent(Object element) {
return myProvider.getParent(element);
}
public boolean hasChildren(Object element) {
if (element instanceof IFile) {
return false;
}
return myContentManager.mayHaveChildren(element);
}
public Object[] getElements(Object inputElement) {
return myContentManager.getChildren(inputElement);
}
public void dispose() {
myProvider.dispose();
workspaceContentAdapter.cancel();
IAdapterManager adapterManager = Platform.getAdapterManager();
adapterManager.unregisterAdapters(workspaceContentProviderFactory);
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (workspaceContentAdapter == null) {
workspaceContentAdapter = new AbstractDeferredAdapter((TreeViewer) viewer) {
public String getLabel(Object o) {
return Messages.UniSelectTransformationControl_workspaceTransformations;
}
@Override
public Object[] getChildren(Object o) {
return myProvider.getElements(o);
}
@Override
public boolean isAccepted(Object object, IProgressMonitor monitor) {
if (myResourceFilter == null || !myResourceFilter.accept((IResource) object)) {
return true;
}
if (mySelectionListener == null) {
return true;
}
URI uri = URIUtils.getResourceURI((IResource) object);
return mySelectionListener.accept(uri);
}
@Override
public TreeAction getTreeAction(Object object, IProgressMonitor monitor) {
if (mySelectionListener == null) {
return TreeAction.NONE;
}
URI uri = URIUtils.getResourceURI((IResource) object);
return mySelectionListener.getTreeAction(uri);
}
};
workspaceContentProviderFactory = new IAdapterFactory() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public Object getAdapter(Object adaptableObject, Class adapterType) {
return workspaceContentAdapter;
}
public Class<?>[] getAdapterList() {
return new Class[] { IWorkbenchAdapter.class, IDeferredWorkbenchAdapter.class };
}
};
IAdapterManager adapterManager = Platform.getAdapterManager();
adapterManager.registerAdapters(workspaceContentProviderFactory, IResource.class);
}
myProvider.inputChanged(viewer, oldInput, newInput);
}
public boolean canHandle(Object element) {
return element instanceof IResource;
}
private final ITreeContentProvider myProvider = new WorkbenchContentProvider();
};
private static abstract class LabelProviderDelegate implements ILabelProviderEx {
LabelProviderDelegate(ILabelProvider provider) {
myDelegate = provider;
}
public Image getImage(Object element) {
return myDelegate.getImage(element);
}
public String getText(Object element) {
return myDelegate.getText(element);
}
public void addListener(ILabelProviderListener listener) {
myDelegate.addListener(listener);
}
public void dispose() {
myDelegate.dispose();
}
public boolean isLabelProperty(Object element, String property) {
return myDelegate.isLabelProperty(element, property);
}
public void removeListener(ILabelProviderListener listener) {
myDelegate.removeListener(listener);
}
private final ILabelProvider myDelegate;
};
private static class DeployedTransformationRoot {
DeployedTransformationRoot(List<DeployedTransformation> trasformations) {
myTrasformations = trasformations;
}
Object[] getChildren() {
return myTrasformations.toArray();
}
private final List<DeployedTransformation> myTrasformations;
}
private class DeployedTransformationContentProvider implements ITreeContentProviderEx {
private AbstractDeferredAdapter deployedTransformationAdapter;
private IAdapterFactory deployedTransformationProviderFactory;
public Object[] getChildren(Object parentElement) {
return getElements(parentElement);
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return myContentManager.mayHaveChildren(element);
}
public Object[] getElements(Object inputElement) {
return myContentManager.getChildren(inputElement);
}
public void dispose() {
deployedTransformationAdapter.cancel();
IAdapterManager adapterManager = Platform.getAdapterManager();
adapterManager.unregisterAdapters(deployedTransformationProviderFactory);
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (deployedTransformationAdapter == null) {
deployedTransformationAdapter = new AbstractDeferredAdapter(myViewer) {
public String getLabel(Object o) {
return Messages.UniSelectTransformationControl_platformTransformations;
}
@Override
public Object[] getChildren(Object o) {
return ((DeployedTransformationRoot) o).getChildren();
}
@Override
public boolean isAccepted(Object object, IProgressMonitor monitor) {
if (mySelectionListener == null) {
return true;
}
return mySelectionListener.accept(((DeployedTransformation) object).getUri());
}
@Override
public TreeAction getTreeAction(Object object, IProgressMonitor monitor) {
if (mySelectionListener == null) {
return TreeAction.NONE;
}
return mySelectionListener.getTreeAction(((DeployedTransformation) object).getUri());
}
};
deployedTransformationProviderFactory = new IAdapterFactory() {
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object getAdapter(Object adaptableObject, Class adapterType) {
return deployedTransformationAdapter;
}
public Class<?>[] getAdapterList() {
return new Class[] { IWorkbenchAdapter.class, IDeferredWorkbenchAdapter.class };
}
};
IAdapterManager adapterManager = Platform.getAdapterManager();
adapterManager.registerAdapters(deployedTransformationProviderFactory, DeployedTransformationRoot.class);
}
}
public boolean canHandle(Object element) {
return element instanceof DeployedTransformation
|| element instanceof DeployedTransformationRoot;
}
};
}