| /******************************************************************************* |
| * Copyright (c) 2012-2014 SAP SE. |
| * 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: |
| * SAP SE - initial API and implementation and/or initial documentation |
| * |
| *******************************************************************************/ |
| package org.eclipse.ogee.navigation.tree; |
| |
| import java.util.Arrays; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IResourceDeltaVisitor; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider; |
| import org.eclipse.emf.edit.provider.FeatureMapEntryWrapperItemProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.transaction.NotificationFilter; |
| import org.eclipse.emf.transaction.ResourceSetChangeEvent; |
| import org.eclipse.emf.transaction.ResourceSetListener; |
| import org.eclipse.emf.transaction.RollbackException; |
| import org.eclipse.emf.transaction.RunnableWithResult; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.emf.transaction.util.TransactionUtil; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.TreePath; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.ogee.model.api.IModelContext; |
| import org.eclipse.ogee.model.api.ModelAPIException; |
| import org.eclipse.ogee.model.odata.Association; |
| import org.eclipse.ogee.model.odata.AssociationSet; |
| import org.eclipse.ogee.model.odata.ComplexType; |
| import org.eclipse.ogee.model.odata.DataService; |
| import org.eclipse.ogee.model.odata.EDMX; |
| import org.eclipse.ogee.model.odata.EDMXSet; |
| import org.eclipse.ogee.model.odata.EntityContainer; |
| import org.eclipse.ogee.model.odata.EntitySet; |
| import org.eclipse.ogee.model.odata.EntityType; |
| import org.eclipse.ogee.model.odata.EnumType; |
| import org.eclipse.ogee.model.odata.FunctionImport; |
| import org.eclipse.ogee.model.odata.NavigationProperty; |
| import org.eclipse.ogee.model.odata.Parameter; |
| import org.eclipse.ogee.model.odata.Property; |
| import org.eclipse.ogee.model.odata.Schema; |
| import org.eclipse.ogee.model.odata.ValueTerm; |
| import org.eclipse.ogee.utils.logger.Logger; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.progress.UIJob; |
| |
| public class MNViewContentProvider extends AdapterFactoryContentProvider |
| implements ITreeContentProvider, IPartListener, |
| IResourceChangeListener, IResourceDeltaVisitor, ResourceSetListener { |
| |
| public MNViewContentProvider() { |
| super(MNComposedAdapterFactory.getAdapterFactory()); |
| ResourcesPlugin.getWorkspace().addResourceChangeListener(this, |
| IResourceChangeEvent.POST_CHANGE); |
| PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService() |
| .addPartListener(this); |
| |
| } |
| |
| @Override |
| public void dispose() { |
| super.dispose(); |
| } |
| |
| @Override |
| public Object[] getChildren(Object parentElement) { |
| final Object parent; |
| EObject eObject; |
| TransactionalEditingDomain editingDomain = null; |
| |
| // Retrieve the editing domain... |
| if (parentElement instanceof IFile) { |
| String path = ((IFile) parentElement).getFullPath().toString(); |
| URI uri = URI.createPlatformResourceURI(path, true); |
| try { |
| editingDomain = IModelContext.INSTANCE |
| .getTransaction((IFile) parentElement); |
| } catch (ModelAPIException e) { |
| Logger.getFrameworkLogger().log( |
| Messages.MNViewContentProvider_NoTransaction); |
| } |
| ResourceSet resourceSet = null; |
| if (editingDomain != null) { |
| resourceSet = editingDomain.getResourceSet(); |
| editingDomain.addResourceSetListener(this); |
| } else { |
| resourceSet = new ResourceSetImpl(); |
| } |
| |
| parent = resourceSet.getResource(uri, true); |
| } else if (parentElement instanceof FeatureMapEntryWrapperItemProvider) { |
| parent = parentElement; |
| eObject = (EObject) ((FeatureMapEntryWrapperItemProvider) parent) |
| .getOwner(); |
| try { |
| editingDomain = IModelContext.INSTANCE.getTransaction(eObject); |
| } catch (ModelAPIException e) { |
| editingDomain = null; |
| } |
| } else { |
| parent = parentElement; |
| eObject = (EObject) parent; |
| try { |
| editingDomain = IModelContext.INSTANCE.getTransaction(eObject); |
| } catch (ModelAPIException e) { |
| editingDomain = null; |
| } |
| } |
| |
| if (editingDomain == null) { |
| return getMyChildren(parent); |
| } |
| |
| return run(editingDomain, new RunnableWithResult.Impl<Object[]>() { |
| public void run() { |
| setResult(getMyChildren(parent)); |
| } |
| }); |
| |
| } |
| |
| private Object[] getMyChildren(Object parentElement) { |
| Object retObject; |
| Object[] ret; |
| List<Object> filteredChildList = new LinkedList<Object>(); |
| |
| if (parentElement instanceof ReferencedSchemasFolder) { |
| return ((ReferencedSchemasFolder) parentElement) |
| .getReferncedSchemas().toArray(); |
| } |
| |
| ret = super.getChildren(parentElement); |
| |
| for (int i = 0; i < ret.length; i++) { |
| retObject = ret[i]; |
| if ((retObject instanceof Association) |
| || (retObject instanceof AssociationSet) |
| || (retObject instanceof ComplexType) |
| || (retObject instanceof EntitySet) |
| || (retObject instanceof EntityType) |
| || (retObject instanceof FunctionImport) |
| || (retObject instanceof NavigationProperty) |
| || (retObject instanceof Parameter) |
| || (retObject instanceof Property) |
| || (retObject instanceof ValueTerm) |
| || (retObject instanceof EntityContainer) |
| || (retObject instanceof Schema)) { |
| filteredChildList.add(retObject); |
| } else if ((retObject instanceof EDMX) |
| || (retObject instanceof DataService) |
| || (retObject instanceof FeatureMapEntryWrapperItemProvider)) { |
| filteredChildList.addAll(Arrays.asList(getChildren(retObject))); |
| } else if (retObject instanceof DelegatingWrapperItemProvider) { |
| filteredChildList |
| .addAll(Arrays |
| .asList(getChildren(((DelegatingWrapperItemProvider) retObject) |
| .getValue()))); |
| } |
| |
| if (retObject instanceof EDMXSet) { |
| EDMXSet edmxSet = (EDMXSet) retObject; |
| EDMX edmx = edmxSet.getMainEDMX(); |
| filteredChildList.addAll(edmx.getDataService().getSchemata()); |
| } |
| |
| } |
| |
| ret = filteredChildList.toArray(); |
| |
| return ret; |
| } |
| |
| @Override |
| public Object[] getElements(Object object) { |
| return getChildren(object); |
| } |
| |
| @Override |
| public Object getParent(Object element) { |
| final Object myElement; |
| |
| TransactionalEditingDomain editingDomain = null; |
| |
| if (element instanceof IFile) |
| return ((IResource) element).getParent(); |
| if (element instanceof EObject) { |
| try { |
| editingDomain = IModelContext.INSTANCE |
| .getTransaction((EObject) element); |
| } catch (ModelAPIException e) { |
| Logger.getFrameworkLogger().log( |
| Messages.MNViewContentProvider_NoTransaction); |
| } |
| if (editingDomain == null) { |
| return getMyParent(element); |
| } |
| myElement = element; |
| return run(editingDomain, new RunnableWithResult.Impl<Object[]>() { |
| public void run() { |
| setResult(new Object[] { getMyParent(myElement) }); |
| } |
| }); |
| } else { |
| return super.getParent(element); |
| } |
| } |
| |
| private Object getMyParent(Object element) { |
| return super.getParent(element); |
| } |
| |
| @Override |
| public boolean hasChildren(Object element) { |
| if (element instanceof EntityType) |
| return ((EntityType) element).eAllContents().hasNext(); |
| ; |
| if (element instanceof ComplexType) |
| return ((ComplexType) element).eAllContents().hasNext(); |
| if (element instanceof EntityContainer) |
| return ((EntityContainer) element).eAllContents().hasNext(); |
| if (element instanceof Schema) |
| return ((Schema) element).eAllContents().hasNext(); |
| if (element instanceof ReferencedSchemasFolder) |
| return !((ReferencedSchemasFolder) element).getReferncedSchemas() |
| .isEmpty(); |
| if (element instanceof IFile) |
| return true; |
| if (element instanceof Property) |
| return false; |
| if (element instanceof EnumType) |
| return false; |
| if (element instanceof ValueTerm) |
| return false; |
| if (element instanceof NavigationProperty) |
| return false; |
| if (element instanceof Parameter) |
| return false; |
| if (element instanceof AssociationSet) |
| return false; |
| if (element instanceof Association) |
| return false; |
| return super.hasChildren(element); |
| } |
| |
| @Override |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| this.viewer = viewer; |
| } |
| |
| @Override |
| public void resourceChanged(IResourceChangeEvent event) { |
| try { |
| IResourceDelta delta = event.getDelta(); |
| delta.accept(this); |
| } catch (CoreException e) { |
| Logger.getFrameworkLogger() |
| .logError( |
| Messages.MNViewContentProvider_ResourceChanged_ErrorDeltaInformation, |
| e); |
| } |
| } |
| |
| @Override |
| public boolean visit(IResourceDelta delta) throws CoreException { |
| IResource changedResource = delta.getResource(); |
| |
| if (changedResource.getType() == IResource.FILE |
| && (changedResource.getFileExtension() != null) |
| && changedResource.getFileExtension().equals("odata")) { //$NON-NLS-1$ |
| UIJob job = new UIJob("Update Viewer") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| if (viewer != null && !viewer.getControl().isDisposed()) { |
| TreeViewer treeViewer = (TreeViewer) viewer; |
| TreePath[] treePaths = treeViewer |
| .getExpandedTreePaths(); |
| viewer.refresh(); |
| treeViewer.setExpandedTreePaths(treePaths); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.schedule(); |
| return false; |
| } |
| return true; |
| |
| } |
| |
| @Override |
| public NotificationFilter getFilter() { |
| return NotificationFilter.NOT_TOUCH; |
| } |
| |
| @Override |
| public Command transactionAboutToCommit(ResourceSetChangeEvent event) |
| throws RollbackException { |
| return null; |
| } |
| |
| @Override |
| public void resourceSetChanged(ResourceSetChangeEvent event) { |
| UIJob job = new UIJob("Update Viewer") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| if (viewer != null && !viewer.getControl().isDisposed()) { |
| TreeViewer treeViewer = (TreeViewer) viewer; |
| TreePath[] treePaths = treeViewer.getExpandedTreePaths(); |
| viewer.refresh(); |
| treeViewer.setExpandedTreePaths(treePaths); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.schedule(); |
| } |
| |
| @Override |
| public boolean isAggregatePrecommitListener() { |
| return false; |
| } |
| |
| @Override |
| public boolean isPrecommitOnly() { |
| return false; |
| } |
| |
| @Override |
| public boolean isPostcommitOnly() { |
| return true; |
| } |
| |
| @Override |
| public void partActivated(IWorkbenchPart part) { |
| |
| } |
| |
| @Override |
| public void partBroughtToTop(IWorkbenchPart part) { |
| |
| } |
| |
| @Override |
| public void partClosed(IWorkbenchPart part) { |
| if (part != null |
| && new String("org.eclipse.ogee.designer.ODataMultiPageEditor") //$NON-NLS-1$ |
| .equals(part.getClass().getCanonicalName())) { |
| UIJob job = new UIJob("Update Viewer") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| if (viewer != null && !viewer.getControl().isDisposed()) { |
| TreeViewer treeViewer = (TreeViewer) viewer; |
| TreePath[] treePaths = treeViewer |
| .getExpandedTreePaths(); |
| viewer.refresh(); |
| treeViewer.setExpandedTreePaths(treePaths); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.schedule(); |
| } |
| } |
| |
| @Override |
| public void partDeactivated(IWorkbenchPart part) { |
| |
| } |
| |
| @Override |
| public void partOpened(IWorkbenchPart part) { |
| |
| } |
| |
| protected <T> T run(TransactionalEditingDomain editingDomain, |
| RunnableWithResult<? extends T> run) { |
| try { |
| return TransactionUtil.runExclusive(editingDomain, run); |
| } catch (InterruptedException e) { |
| // Propagate interrupt status, because we are not throwing an |
| // exception... |
| Thread.currentThread().interrupt(); |
| return null; |
| } |
| } |
| |
| } |