package com.googlecode.goclipse.ui.navigator; import static melnorme.utilbox.core.CoreUtil.areEqual; import java.nio.file.Path; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.swt.widgets.Display; import com.googlecode.goclipse.core.GoProjectEnvironment; import com.googlecode.goclipse.tooling.env.GoEnvironment; import com.googlecode.goclipse.tooling.env.GoPath; import com.googlecode.goclipse.tooling.env.GoRoot; import com.googlecode.goclipse.tooling.env.GoWorkspaceLocation; import com.googlecode.goclipse.ui.GoUIPlugin; import com.googlecode.goclipse.ui.navigator.elements.GoPathElement; import com.googlecode.goclipse.ui.navigator.elements.GoPathEntryElement; import com.googlecode.goclipse.ui.navigator.elements.GoRootElement; import melnorme.lang.ide.core.INavigatorElement_Actual; import melnorme.lang.ide.core.project_model.view.BundleErrorElement; import melnorme.lang.ide.core.utils.ResourceUtils; import melnorme.lang.ide.ui.navigator.AbstractNavigatorContentProvider; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.misc.Location; import melnorme.utilbox.misc.MiscUtil; // TODO: this content provider is hard-coded to show files from GOROOT; we'll probably want this // to have better knowledge of the GOROOT / GOPATH directories that are in use by the project. /** * A CNF content provider that decorates the the standard resource content provider with a GOROOT * node. This shows the IFileStore files in the GOROOT/src directory. * * @author devoncarew */ public class GoNavigatorContentProvider extends AbstractNavigatorContentProvider { protected final Object[] NO_CHILDREN = new Object[0]; public GoNavigatorContentProvider() { // TODO: we really want to listen for changes to the root directories referenced by the project. GoUIPlugin.getCorePrefStore().addPropertyChangeListener(propListener); } @Override public void dispose() { GoUIPlugin.getCorePrefStore().removePropertyChangeListener(propListener); super.dispose(); } protected final IPropertyChangeListener propListener = (pce) -> { updateViewer(); }; protected void updateViewer() { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if(viewer != null) { viewer.refresh(); } } }); } /* ----------------- ----------------- */ @Override protected LangNavigatorSwitcher_HasChildren hasChildren_switcher() { return new LangNavigatorSwitcher_HasChildren() { @Override public Boolean visitGoPathElement(GoPathElement goPathElement) { return true; } @Override public Boolean visitFileStoreElement(IFileStore fileStore) { return getChildren(fileStore).length > 0; } }; } @Override protected LangNavigatorSwitcher_GetChildren getChildren_switcher() { return new LangNavigatorSwitcher_GetChildren() { @Override public void addFirstProjectChildren(IProject project, ArrayList2<Object> projectChildren) { projectChildren.addElements(getProjectGoPathChildren(project)); } @Override public Object[] visitGoPathElement(GoPathElement goPathElement) { try { IFileStore fileStore = EFS.getStore(goPathElement.getDirectory().toURI()); return fileStore.childStores(EFS.NONE, null); } catch (CoreException exception) { return NO_CHILDREN; } } @Override public Object[] visitFileStoreElement(IFileStore fileStore) { try { return fileStore.childStores(EFS.NONE, null); } catch (CoreException e) { return NO_CHILDREN; } } }; } @Override protected void addBuildTargetsContainer(IProject project, ArrayList2<Object> projectChildren) { super.addBuildTargetsContainer(project, projectChildren); } @Override protected LangNavigatorSwitcher_GetParent getParent_switcher() { return new LangNavigatorSwitcher_GetParent() { @Override public Object visitGoPathElement(GoPathElement goPathElement) { return null; // TODO: project parent } @Override public Object visitFileStoreElement(IFileStore fileStore) { // TODO: trim this at the GOROOT directory return fileStore.getParent(); } }; } protected Object[] getProjectGoPathChildren(IProject project) { GoEnvironment goEnvironment = GoProjectEnvironment.getGoEnvironment(project); GoRoot goRoot = goEnvironment.getGoRoot(); Location goRootSource; Location projectLocation; try { goRootSource = goRoot.getSourceRootLocation(); projectLocation = ResourceUtils.getLocation(project); } catch (CommonException e) { return NO_CHILDREN; } ArrayList2<INavigatorElement_Actual> buildpathChildren = new ArrayList2<>(); buildpathChildren.add(new GoRootElement(goRootSource.toFile())); GoPath goPath = goEnvironment.getGoPath(); for (String goPathEntry : goPath.getGoPathEntries()) { Path goPathEntryPath; try { goPathEntryPath = MiscUtil.createPath(goPathEntry); } catch (CommonException e) { continue; // TODO: create error element } if(areEqual(goPathEntryPath, project.getLocation().toFile().toPath())) { continue; // Don't add this entry. } boolean projectInsideThisGoPathEntry = false; // Not used ATM buildpathChildren.add(new GoPathEntryElement(goPathEntryPath, project, projectInsideThisGoPathEntry)); } GoWorkspaceLocation goWorkspaceRoot = goPath.findGoPathEntry(projectLocation); if(goWorkspaceRoot == null) { buildpathChildren.add(new BundleErrorElement(project, "Project is not contained in any GOPATH entry.")); } return buildpathChildren.toArray(); } }