/***************************************************************************** * Copyright (c) 2011 Atos Origin Integration. * * 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: * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.infra.onefile.providers; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.security.auth.kerberos.KerberosKey; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.papyrus.infra.core.Activator; import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor; import org.eclipse.papyrus.infra.core.resource.ModelMultiException; import org.eclipse.papyrus.infra.core.resource.ModelSet; import org.eclipse.papyrus.infra.core.resource.uml.UmlModel; import org.eclipse.papyrus.infra.core.resource.uml.UmlUtils; import org.eclipse.papyrus.infra.core.services.ExtensionServicesRegistry; import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.onefile.matcher.OnlyDiFilter; import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile; import org.eclipse.papyrus.infra.onefile.model.PapyrusModelHelper; import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.navigator.CommonViewer; /** * Content provider able to retrieve Papyrus children from an {@link IContainer} * * @author Tristan FAURE * */ public class PapyrusContentProvider extends WorkbenchContentProvider { private CommonViewer common; public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { super.inputChanged(viewer, oldInput, newInput); if(viewer instanceof CommonViewer) { common = (CommonViewer)viewer; } } /** * Determine if the current navigator is filtered or not * * @return true if the viewer is filtered */ public boolean isFiltered() { return common != null && common.getNavigatorContentService() != null && common.getNavigatorContentService().getFilterService() != null && common.getNavigatorContentService().getFilterService().isActive(OnlyDiFilter.FILTER_ID); } @Override public void dispose() { super.dispose(); } public Object[] getElements(Object inputElement) { if(inputElement instanceof IWorkspaceRoot) { return null; } List<Object> result = new LinkedList<Object>(); try { if(isFiltered()) { if(inputElement instanceof IPapyrusFile) { IPapyrusFile file = (IPapyrusFile)inputElement; for(IResource r : file.getAssociatedResources()) { result.add(PapyrusModelHelper.getPapyrusModelFactory().createISubResourceFile(file, (IFile)r)); } } else { IResource[] members = null; if(inputElement instanceof IContainer) { members = ((IContainer)inputElement).members(); } if(members != null) { for(IResource r : members) { if(r instanceof IContainer && !(r instanceof IProject)) { IContainer cont = (IContainer)r; result.add(cont); } else if(r instanceof IFile) { if(OneFileUtils.isDi(r)) { IPapyrusFile createIPapyrusFile = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile((IFile)r); result.add(createIPapyrusFile); } else { if(!OneFileUtils.diExists(r.getName(), r.getParent())) { result.add(r); } } } else { result.add(r); } } } } } } catch (CoreException e) { } return result.isEmpty() ? null : result.toArray(); } public Object[] getChildren(Object inputElement) { return getElements(inputElement); } public Object getParent(Object element) { if(element instanceof IPapyrusFile) { IPapyrusFile papyFile = (IPapyrusFile)element; return papyFile.getParent(); } return null; } public boolean hasChildren(Object element) { return OneFileUtils.hasChildren(element); } @Override protected void processDelta(IResourceDelta delta) { super.processDelta(delta); if(!isFiltered()) { return; } Control ctrl = common.getControl(); if(ctrl == null || ctrl.isDisposed()) { return; } final Collection<Runnable> runnables = new ArrayList<Runnable>(); processPapyrusDelta(delta, runnables); if(runnables.isEmpty()) { return; } //Are we in the UIThread? If so spin it until we are done ctrl.getDisplay().asyncExec(new Runnable() { /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { //Abort if this happens after disposes Control ctrl = common.getControl(); if(ctrl == null || ctrl.isDisposed()) { return; } runUpdates(runnables); } }); } private void runUpdates(Collection<?> runnables) { Iterator<?> runnableIterator = runnables.iterator(); while(runnableIterator.hasNext()) { ((Runnable)runnableIterator.next()).run(); } } protected void processPapyrusDelta(IResourceDelta delta, Collection<Runnable> runnables) { IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED); // Handle changed children . for(int i = 0; i < affectedChildren.length; i++) { processPapyrusDelta(affectedChildren[i], runnables); } IResourceDelta[] addedChildren = delta.getAffectedChildren(IResourceDelta.ADDED); final Object[] addedObjects; // Process additions before removals as to not cause selection // preservation prior to new objects being added // Handle added children. Issue one update for all insertions. if(addedChildren.length > 0) { addedObjects = new Object[addedChildren.length]; for(int i = 0; i < addedChildren.length; i++) { addedObjects[i] = addedChildren[i].getResource(); } } else { addedObjects = new Object[0]; } // Handle removed children. Issue one update for all removals. // heuristic test for items moving within same folder (i.e. renames) Runnable addAndRemove = new Runnable() { public void run() { if(common instanceof AbstractTreeViewer) { AbstractTreeViewer treeViewer = (AbstractTreeViewer)common; // Disable redraw until the operation is finished so we don't // get a flash of both the new and old item (in the case of // rename) // Only do this if we're both adding and removing files (the // rename case) try { // need to handle resource addition if(addedObjects.length > 0) { ArrayList<IPapyrusFile> elements = new ArrayList<IPapyrusFile>(addedObjects.length); ArrayList<IPapyrusFile> toAdd = new ArrayList<IPapyrusFile>(addedObjects.length); for(Object r : addedObjects) { if(r instanceof IResource) { IResource current = (IResource)r; if(OneFileUtils.diExists(current.getName(), current.getParent())) { elements.add(PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(OneFileUtils.getDi(current.getName(), current.getParent()))); } if(OneFileUtils.isDi(current)) { toAdd.add(PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile((IFile)current)); } } } for(Object o : elements) { common.refresh(o); } for(IPapyrusFile o : toAdd) { common.add(o.getParent(), o); } } } finally { } } } }; runnables.add(addAndRemove); } // @Override // protected ITreeContentProvider getDelegateContentProvider() { // if(provider == null) { // provider = new WorkbenchContentProvider(); // } // return provider; // } // // @Override // protected String getModelProviderId() { // return OneFileModelProvider.MODEL_PROVIDER_ID; // } // // @Override // protected Object getModelRoot() { // return null; // } // @Override // protected ResourceTraversal[] getTraversals(ISynchronizationContext context, Object object) { // return null; // } }