/******************************************************************************* * Copyright (c) 2012 Pivotal Software, Inc. * 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: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.explorer.providers; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; 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.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.packageview.ClassPathContainer; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.core.internal.GrailsNature; import org.grails.ide.eclipse.core.internal.GrailsResourceUtil; import org.grails.ide.eclipse.core.internal.plugins.GrailsProjectStructureManager; import org.grails.ide.eclipse.core.internal.plugins.GrailsProjectStructureTypes; import org.grails.ide.eclipse.explorer.GrailsExplorerPlugin; import org.grails.ide.eclipse.explorer.elements.GrailsClasspathContainersFolder; import org.grails.ide.eclipse.explorer.elements.GrailsFolderElementFactory; import org.grails.ide.eclipse.explorer.elements.ILogicalFolder; import org.grails.ide.eclipse.explorer.preferences.GrailsExplorerPreferences; import org.grails.ide.eclipse.explorer.preferences.OrderingConfig; /** * Providers Grails logical folders to the common navigator * * @author Nieraj Singh * @author Andy Clement * @author Christian Dupuis * @author Andrew Eisenberg */ public class GrailsNavigatorContentProvider implements ITreeContentProvider { private Viewer viewer; private GrailsExplorerPreferences.Listener preferencesListener; public GrailsNavigatorContentProvider() { } public Object[] getChildren(Object parentElement) { if (parentElement instanceof IProject && GrailsNature.isGrailsProject((IProject) parentElement)) { IProject project = (IProject) parentElement; Collection<GrailsProjectStructureTypes> types = GrailsProjectStructureManager .getInstance().getAllTopLevelLogicalFolders().values(); List<Object> topLevelFolders = new ArrayList<Object>(); GrailsFolderElementFactory factory = getFolderElementFactory(); for (GrailsProjectStructureTypes type : types) { ILogicalFolder element = factory .getElement(project, project.getFolder(new Path(type .getFolderName())), type); if (element != null) { topLevelFolders.add(element); } } //Add a logical folder that contains the classpath containers topLevelFolders.add(new GrailsClasspathContainersFolder(project)); // Now add the top level package fragment roots that are // non-dependency source folders IJavaProject javaProject = JavaCore.create(project); try { IPackageFragmentRoot[] roots = javaProject .getPackageFragmentRoots(); if (roots != null) { for (IPackageFragmentRoot root : roots) { if (root.getRawClasspathEntry().getEntryKind() == IClasspathEntry.CPE_SOURCE && !GrailsResourceUtil .isGrailsDependencyPackageFragmentRoot(root)) { topLevelFolders.add(root); } } } } catch (JavaModelException e) { GrailsCoreActivator.log(e); } // Add the file folders that are reimaged Set<GrailsProjectStructureTypes> fileFolders = GrailsProjectStructureManager .getInstance().getGrailsFileFolders(); if (fileFolders != null) { for (GrailsProjectStructureTypes type : fileFolders) { IFolder folder = project.getFolder(new Path(type .getFolderName())); if (folder != null && folder.exists()) { topLevelFolders.add(folder); } } } try { IResource[] children = project.members(); if (children != null) { for (IResource resource : children) { // Skip the linked folders that correspond to // Grails dependency package fragment roots if (!isLinkedDependencyPackageFragmentRoot(resource) && !isReimagedResource(resource)) { topLevelFolders.add(resource); } } } } catch (CoreException e) { GrailsCoreActivator.log(e); } return topLevelFolders.toArray(); } else if (parentElement instanceof ILogicalFolder) { ILogicalFolder element = (ILogicalFolder) parentElement; List<?> children = element.getChildren(); if (children != null) { return children.toArray(); } } else if (parentElement instanceof IPackageFragmentRoot) { IPackageFragmentRoot root = (IPackageFragmentRoot) parentElement; GrailsProjectStructureTypes type = GrailsResourceUtil .getGrailsContainerType(root); if (type == GrailsProjectStructureTypes.CONF) { try { IJavaElement[] children = root.getChildren(); if (children != null) { List<IJavaElement> elements = new ArrayList<IJavaElement>(); for (IJavaElement child : children) { IPackageFragment frag = (child instanceof IPackageFragment) ? (IPackageFragment) child : null; if (frag == null || !frag.isDefaultPackage()) { elements.add(child); } else { IJavaElement[] defaultChildren = frag .getChildren(); for (IJavaElement defaultChild : defaultChildren) { elements.add(defaultChild); } } } return elements.toArray(); } } catch (JavaModelException e) { GrailsCoreActivator.log(e); } } } return null; } protected boolean isReimagedResource(IResource resource) { if (!(resource instanceof IFolder)) { return false; } IFolder folder = (IFolder) resource; return GrailsResourceUtil.isReimagedGrailsProjectFileFolder(folder); } protected boolean isLinkedDependencyPackageFragmentRoot(IResource resource) { if (!(resource instanceof IFolder)) { return false; } IFolder folder = (IFolder) resource; if (!folder.isLinked()) { return false; } IJavaElement element = JavaCore.create(folder); if (element instanceof IPackageFragmentRoot && GrailsResourceUtil .isGrailsDependencyPackageFragmentRoot((IPackageFragmentRoot) element)) { return true; } return false; } protected GrailsFolderElementFactory getFolderElementFactory() { return new GrailsFolderElementFactory(); } public Object getParent(Object element) { if (element instanceof ILogicalFolder) { return ((ILogicalFolder) element).getParent(); } else if (element instanceof IResource && !(element instanceof IProject)) { return ((IResource) element).getParent(); } else if (element instanceof ClassPathContainer) { ClassPathContainer classPathContainer = (ClassPathContainer) element; return new GrailsClasspathContainersFolder(classPathContainer.getJavaProject().getProject()); } return null; } public boolean hasChildren(Object element) { try { if (element instanceof ILogicalFolder) { List<Object> children = ((ILogicalFolder) element).getChildren(); return children != null && children.size() > 0; } else if (element instanceof IContainer) { return ((IResource) element).isAccessible() && ((IContainer) element).members().length > 0; } else if (element instanceof IPackageFragmentRoot) { // not really working since there is a JDT content provider that thinks children exist IResource underlyingResource = ((IPackageFragmentRoot) element).getUnderlyingResource(); return underlyingResource instanceof IContainer && ((IContainer) underlyingResource).members().length > 0; } } catch (CoreException e) { GrailsCoreActivator.log(e); } return false; } public void dispose() { if (this.preferencesListener!=null) { GrailsExplorerPreferences prefs = GrailsExplorerPlugin.getDefault().getPreferences(); prefs.removeListener(preferencesListener); } } public Object[] getElements(Object inputElement) { return getChildren(inputElement); } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { this.viewer = viewer; ensurePreferencesListener(); } private void ensurePreferencesListener() { if (this.preferencesListener==null) { GrailsExplorerPreferences prefs = GrailsExplorerPlugin.getDefault().getPreferences(); if (prefs!=null) { preferencesListener = new GrailsExplorerPreferences.Listener() { public void orderingChanged(OrderingConfig newConfig) { if (viewer!=null) { viewer.refresh(); } } }; prefs.addListener(preferencesListener); } } } }