package com.intellij.lang.javascript.flex.projectStructure.ui; import com.intellij.ide.projectView.TreeStructureProvider; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.nodes.ExternalLibrariesNode; import com.intellij.ide.projectView.impl.nodes.NamedLibraryElement; import com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.lang.javascript.flex.projectStructure.FlexCompositeSdk; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class FlexCompositeSdkProjectViewStructureProvider implements TreeStructureProvider, DumbAware { @NotNull @Override public Collection<AbstractTreeNode> modify(@NotNull final AbstractTreeNode parent, @NotNull final Collection<AbstractTreeNode> children, final ViewSettings settings) { if (!(parent instanceof ExternalLibrariesNode)) { return children; } Set<Sdk> processedSdks = new HashSet<>(); Collection<AbstractTreeNode> result = new ArrayList<>(); for (AbstractTreeNode child : children) { Object value = child.getValue(); if (!(value instanceof NamedLibraryElement)) { result.add(child); continue; } NamedLibraryElement libraryElement = (NamedLibraryElement)value; OrderEntry orderEntry = libraryElement.getOrderEntry(); if (!(orderEntry instanceof JdkOrderEntry)) { result.add(child); continue; } Sdk sdk = ((JdkOrderEntry)orderEntry).getJdk(); if (!(sdk instanceof FlexCompositeSdk)) { result.add(child); continue; } Sdk[] sdks = ((FlexCompositeSdk)sdk).getSdks(); for (Sdk individualSdk : sdks) { if (processedSdks.add(individualSdk)) { IndividualSdkOrderEntry entry = new IndividualSdkOrderEntry(individualSdk, orderEntry.getOwnerModule()); result.add(new NamedLibraryElementNode(parent.getProject(), new NamedLibraryElement(null, entry), ((ExternalLibrariesNode)parent).getSettings())); } } } return result; } private static class IndividualSdkOrderEntry implements ModuleJdkOrderEntry { @NotNull private final Sdk mySdk; @NotNull private final Module myModule; private IndividualSdkOrderEntry(final Sdk sdk, final Module module) { mySdk = sdk; myModule = module; } @Override public Sdk getJdk() { return mySdk; } @Override public String getJdkName() { return mySdk.getName(); } @NotNull @Override public VirtualFile[] getRootFiles(@NotNull final OrderRootType type) { List<VirtualFile> directories = ContainerUtil.filter(mySdk.getRootProvider().getFiles(type), virtualFile -> virtualFile.isDirectory()); return VfsUtil.toVirtualFileArray(directories); } @NotNull @Override public String[] getRootUrls(@NotNull final OrderRootType type) { return mySdk.getRootProvider().getUrls(type); } @NotNull @Override public VirtualFile[] getFiles(final OrderRootType type) { return mySdk.getRootProvider().getFiles(type); } @NotNull @Override public String[] getUrls(final OrderRootType rootType) { return getRootUrls(rootType); } @NotNull @Override public String getPresentableName() { return "<" + getJdkName() + ">"; } @Override public boolean isValid() { return true; } @NotNull @Override public Module getOwnerModule() { return myModule; } @Override public <R> R accept(final RootPolicy<R> policy, @Nullable final R initialValue) { return policy.visitModuleJdkOrderEntry(this, initialValue); } @Override public int compareTo(final OrderEntry o) { return 0; } @Override public boolean isSynthetic() { return true; } } }