Package mmrnmhrm.ui.navigator

Source Code of mmrnmhrm.ui.navigator.DubNavigatorContentProvider$DubContentElementsSwitcher

package mmrnmhrm.ui.navigator;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertUnreachable;

import java.util.ArrayList;

import melnorme.lang.ide.core.utils.EclipseUtils;
import melnorme.utilbox.misc.CollectionUtil;
import mmrnmhrm.core.DeeCore;
import mmrnmhrm.core.workspace.IWorkspaceModel.DubModelUpdateEvent;
import mmrnmhrm.core.workspace.IWorkspaceModel.IWorkspaceModelListener;
import mmrnmhrm.core.workspace.ProjectInfo;
import mmrnmhrm.core.workspace.WorkspaceModel;
import mmrnmhrm.core.workspace.viewmodel.DubDepSourceFolderElement;
import mmrnmhrm.core.workspace.viewmodel.DubDependenciesContainer;
import mmrnmhrm.core.workspace.viewmodel.DubDependencyElement;
import mmrnmhrm.core.workspace.viewmodel.DubErrorElement;
import mmrnmhrm.core.workspace.viewmodel.DubRawDependencyElement;
import mmrnmhrm.core.workspace.viewmodel.IDubElement;
import mmrnmhrm.core.workspace.viewmodel.StdLibContainer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IParent;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;

import dtool.dub.BundlePath;
import dtool.dub.DubBundleDescription;

public class DubNavigatorContentProvider extends AbstractNavigatorContentProvider {
 
  public static WorkspaceModel getWorkspaceModel() {
    return DeeCore.getWorkspaceModel();
  }
 
  protected IWorkspaceModelListener listener;
 
  @Override
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    super.inputChanged(viewer, oldInput, newInput);
   
    // Remove previous listener, even though I think inputChange is only called once.
    getWorkspaceModel().removeListener(listener);
   
    listener = new IWorkspaceModelListener() {
      @Override
      public void notifyUpdateEvent(DubModelUpdateEvent updateEvent) {
        // we use throttle Job as a workaround to to ensure label is updated, due to bug:
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=430005
        viewerRefreshThrottleJob.scheduleRefreshJob();
      }
    };
    getWorkspaceModel().addListener(listener);
  }
 
  @Override
  public void dispose() {
    getWorkspaceModel().removeListener(listener);
  }
 
  protected final ThrottleCodeJob viewerRefreshThrottleJob = new ThrottleCodeJob(1200) {
    @Override
    protected void runThrottledCode() {
      postRefreshEventToUI(this);
    };
  };
 
  protected void postRefreshEventToUI(final ThrottleCodeJob throttleCodeJob) {
    final ArrayList<IProject> dubProjects = new ArrayList<>();
    for (String projectName : getWorkspaceModel().getDubProjects()) {
      IProject project = EclipseUtils.getWorkspaceRoot().getProject(projectName);
      dubProjects.add(project);
    }
   
    Display.getDefault().asyncExec(new Runnable() {
      @Override
      public void run() {
        throttleCodeJob.markRequestFinished();
        for (IProject dubProject : dubProjects) {
          getViewer().refresh(dubProject);
        }
      }
    });
  }
 
  public static abstract class DubContentElementsSwitcher<RET> {
   
    public RET switchElement(Object element) {
      if(element instanceof IDubElement) {
        return visitDubElement((IDubElement) element);
      } else if(element instanceof IProject) {
        return visitProject((IProject) element);
      } if(element instanceof IModelElement && element instanceof IParent) {
        return visitModelElement((IModelElement) element, (IParent) element);
      } else {
        return visitOther(element);
      }
    }
   
    public abstract RET visitDubElement(IDubElement dubElement);
   
    public abstract RET visitProject(IProject project);
   
    public abstract RET visitModelElement(IModelElement element, IParent elementAsParent);
   
    public abstract RET visitOther(Object element);
   
  }
 
 
  @Override
  public boolean hasChildren(Object element) {
    return new DubContentElementsSwitcher<Boolean>() {
      @Override
      public Boolean visitProject(IProject project) {
        return project.isAccessible() && getWorkspaceModel().getBundleInfo(project) != null;
      }
      @Override
      public Boolean visitDubElement(IDubElement dubElement) {
        return dubElement.hasChildren();
      }
      @Override
      public Boolean visitModelElement(IModelElement element, IParent elementAsParent) {
        try {
          return elementAsParent.hasChildren();
        } catch (ModelException e) {
          return false;
        }
      }
      @Override
      public Boolean visitOther(Object element) {
        return false;
      }
    }.switchElement(element);
  }
 
  @Override
  public Object[] getChildren(Object parent) {
    return new DubContentElementsSwitcher<Object[]>() {
      @Override
      public Object[] visitProject(IProject project) {
        return getProjectChildren(project);
      }
      @Override
      public Object[] visitDubElement(IDubElement dubElement) {
        return dubElement.getChildren();
      }
      @Override
      public Object[] visitModelElement(IModelElement element, IParent elementAsParent) {
        try {
          return elementAsParent.getChildren();
        } catch (ModelException e) {
          return IDubElement.NO_CHILDREN;
        }
      }
      @Override
      public Object[] visitOther(Object element) {
        return null;
      }
    }.switchElement(parent);
  }
 
  protected Object[] getProjectChildren(IProject project) {
    ArrayList<Object> arrayList = new ArrayList<>();
    if(project.isAccessible()) {
      ProjectInfo projectInfo = getWorkspaceModel().getProjectInfo(project);
      if(projectInfo != null) {
        DubDependenciesContainer dubContainer = projectInfo.getDubContainer(project);
        arrayList.add(dubContainer);
        arrayList.add(new StdLibContainer(projectInfo.getCompilerInstall(), project));
      }
     
      // Add project children ourselves: this is so that children will be sorted by our own sorter.
      // (otherwise only Platform Navigator sorter will be used)
      // Navigator ResourceExtension will also add this, but they will not appear duplicated because they
      // are equal elements.
      try {
        arrayList.addAll(CollectionUtil.createArrayList(project.members()));
      } catch (CoreException e) {
        // ignore, leave empty
      }
    }
    return arrayList.toArray();
  }
 
  @Override
  public Object getParent(Object element) {
    return new DubContentElementsSwitcher<Object>() {
      @Override
      public Object visitProject(IProject project) {
        return project.getParent();
      }
      @Override
      public Object visitDubElement(IDubElement dubElement) {
        return dubElement.getParent();
      }
      @Override
      public Object visitModelElement(IModelElement element, IParent elementAsParent) {
        IModelElement parent = element.getParent();
        if(parent instanceof IProjectFragment) {
          // TODO: need to map to DepSourceContainer
          return null;
        }
        return parent;
      }
      @Override
      public Object visitOther(Object element) {
        return null;
      }
    }.switchElement(element);
  }
 
  /* ----------------- specific switcher ----------------- */
 
  public static abstract class DubAllContentElementsSwitcher<RET> extends DubContentElementsSwitcher<RET> {
   
    @Override
    public RET visitProject(IProject project) {
      return null;
    }
   
    @Override
    public RET visitDubElement(IDubElement element) {
      switch (element.getElementType()) {
      case DUB_DEP_CONTAINER: return visitDepContainer((DubDependenciesContainer) element);
      case DUB_STD_LIB: return visitStdLibContainer((StdLibContainer) element);
      case DUB_RAW_DEP: return visitRawDepElement((DubRawDependencyElement) element);
      case DUB_ERROR_ELEMENT: return visitErrorElement((DubErrorElement) element);
      case DUB_RESOLVED_DEP: return visitDepElement((DubDependencyElement) element);
      case DUB_DEP_SRC_FOLDER: return visitDepSourceFolderElement((DubDepSourceFolderElement) element);
      }
      throw assertUnreachable();
    }
   
    public abstract RET visitDepContainer(DubDependenciesContainer element);
    public abstract RET visitStdLibContainer(StdLibContainer element);
    public abstract RET visitRawDepElement(DubRawDependencyElement element);
    public abstract RET visitErrorElement(DubErrorElement element);
    public abstract RET visitDepElement(DubDependencyElement element);
    public abstract RET visitDepSourceFolderElement(DubDepSourceFolderElement element);
   
    @Override
    public abstract RET visitModelElement(IModelElement element, IParent elementAsParent);
   
    @Override
    public RET visitOther(Object element) {
      if(isDubManifestFile(element)) {
        return visitDubManifestFile((IFile) element);
      }
      if(isDubCacheFolder(element)) {
        return visitDubCacheFolder((IFolder) element);
      }
      if(isDubSourceFolder(element)) {
        return visitDubSourceFolder((IFolder) element);
      }
      return null;
    }
   
    public abstract RET visitDubManifestFile(IFile element);
   
    public abstract RET visitDubCacheFolder(IFolder element);
   
    public abstract RET visitDubSourceFolder(IFolder element);
   
  }
 
  public static boolean isDubManifestFile(Object element) {
    if(element instanceof IFile) {
      IFile file = (IFile) element;
      if(file.getProjectRelativePath().equals(new Path(BundlePath.DUB_MANIFEST_FILENAME))) {
        return true;
      }
    }
    return false;
  }
 
  public static boolean isDubCacheFolder(Object element) {
    if(!(element instanceof IFolder)) {
      return false;
    }
    IFolder folder = (IFolder) element;
    if(folder.getProjectRelativePath().equals(new Path(".dub"))) {
      return true;
    }
    return false;
  }
 
  public static boolean isDubSourceFolder(Object element) {
    if(!(element instanceof IFolder)) {
      return false;
    }
    IFolder folder = (IFolder) element;
    IProject project = folder.getProject();
    DubBundleDescription bundleInfo = getWorkspaceModel().getBundleInfo(project);
    if(bundleInfo == null) {
      return false;
    }
   
    java.nio.file.Path[] sourceFolders = bundleInfo.getMainBundle().getEffectiveSourceFolders();
    for (java.nio.file.Path srcFolderPath : sourceFolders) {
      if(folder.getProjectRelativePath().toFile().toPath().equals(srcFolderPath)) {
        return true;
      }
    }
    return false;
  }
 
}
TOP

Related Classes of mmrnmhrm.ui.navigator.DubNavigatorContentProvider$DubContentElementsSwitcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.