/** * CertWare Project * Copyright (c) 2010 National Aeronautics and Space Administration. All rights reserved. */ package net.certware.measurement.spm.view; import net.certware.core.ICertWareConstants; import net.certware.core.ui.log.CertWareLog; import net.certware.measurement.spm.ProjectCommit; import net.certware.measurement.spm.ProjectModel; 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.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.progress.UIJob; /** * Provides project metrics as navigator content. * @author mrb * @since 1.1 */ public class ContentProvider implements ITreeContentProvider, IResourceChangeListener, IResourceDeltaVisitor, ICertWareConstants { /** no children tree */ private static final Object[] NO_CHILDREN = new Object[0]; /** selected resource file, if any */ private IFile selectedFile = null; /** tree viewer to update */ private StructuredViewer viewer; /** * Constructor adds resource change listener for post change events. */ public ContentProvider() { ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); } /** * Disposes of content provider, clears map, and removes resource change listener. * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } /** * Responds to content input change for the provider. * @param aViewer structured content viewer * @param oldInput previous input model * @param newInput new input model * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object) */ @Override public void inputChanged(Viewer aViewer, Object oldInput, Object newInput) { if (null != oldInput && !oldInput.equals(newInput)) { // clear any cache... } viewer = (StructuredViewer) aViewer; } /** * Visitor for resource change deltas. * @param delta resource change delta * @return false for file type resource processing, true otherwise * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(IResourceDelta) */ @Override public boolean visit(IResourceDelta delta) { final IResource source = delta.getResource(); switch (source.getType()) { case IResource.ROOT: case IResource.PROJECT: case IResource.FOLDER: return true; case IResource.FILE: final IFile file = (IFile) source; if ( ICertWareConstants.SPM_EXTENSION.equals(file.getFileExtension()) ) { updateModel(file); new UIJob(Messages.Job) { public IStatus runInUIThread(IProgressMonitor monitor) { if (null != viewer ) { viewer.refresh(file); } selectedFile = file; return Status.OK_STATUS; } }.schedule(); } return false; default: break; } return false; } /** * Method resourceChanged. * @param event IResourceChangeEvent * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(IResourceChangeEvent) */ @Override public void resourceChanged(IResourceChangeEvent event) { final IResourceDelta delta = event.getDelta(); try { delta.accept(this); } catch (CoreException e) { CertWareLog.logError(Messages.ResourceChanged,e); } } /** * Gets the input model children as elements. * @param inputElement input model whose children are returned * @return Object[] children * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(Object) */ @Override public Object[] getElements(Object inputElement) { return getChildren(inputElement); } /** * Returns all of the tree items in a project model as an object list. * @param pm project model * @return list of project commits */ public Object[] getChildrenForModel(ProjectModel pm) { return pm.getCommits().toArray(); /* List<EObject> items = new ArrayList<EObject>(); TreeIterator ti = pm.eAllContents(); while( ti.hasNext() ) { items.add( (EObject)ti.next() ); } return items.toArray(); */ } /** * Gets the children of the given parent element. * @param parentElement parent element * @return Object[] of NO_CHILDREN or project commits * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(Object) */ @Override public Object[] getChildren(Object parentElement) { Object[] children = null; // project model selection has project commits as children // project commits may or may not have the metrics as immediate children if ( parentElement instanceof ProjectModel ) { children = getChildrenForModel((ProjectModel)parentElement); } else if (parentElement instanceof IFile) { final IFile modelFile = (IFile)parentElement; if ( ICertWareConstants.SPM_EXTENSION.equals( modelFile.getFileExtension() ) ) { ProjectModel pm = updateModel(modelFile); children = getChildrenForModel(pm); } } return (null != children) ? children : NO_CHILDREN; } /** * Gets the parent object if project model or commit. * @param element element to find parent * @return project model from commit, file from project model, or null * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(Object) */ @Override public Object getParent(Object element) { if ( element instanceof ProjectModel ) { return selectedFile; // may not match model element selection from editor } if ( element instanceof ProjectCommit ) { ProjectCommit pc = (ProjectCommit)element; return (ProjectModel)pc.eContainer(); } return null; } /** * Whether the tree element has children. * @param element tree element * @return true if project model element or file with matching extension, false otherwise * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(Object) */ @Override public boolean hasChildren(Object element) { if ( element instanceof ProjectModel ) { return true; } else if ( element instanceof IFile ) { return ICertWareConstants.SPM_EXTENSION.equals(((IFile)element).getFileExtension()); } return false; } /** * Updates the content model from the project statistics in the resource model file. * @param modelFile input file * @return model resource processed from file */ private synchronized ProjectModel updateModel(IFile modelFile) { if ( ICertWareConstants.SPM_EXTENSION.equals(modelFile.getFileExtension())) { if (modelFile.exists()) { final ResourceSet resourceSet = new ResourceSetImpl(); final Resource resource = resourceSet.getResource( URI.createPlatformResourceURI(modelFile.getFullPath().toString(), true), true); if ( null != resource ) { ProjectModel pm = (ProjectModel)resource.getContents().get(0); return pm; } // resource not null } // model exists } // file extension matches System.err.println("returning null"); return null; } // method }