/* * Copyright 2010 The authors * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.struts2.facet.ui; import com.intellij.ide.presentation.VirtualFilePresentation; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.peer.PeerFactory; import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlFile; import com.intellij.ui.CheckboxTreeBase; import com.intellij.ui.CheckedTreeNode; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.tree.TreeUtil; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.util.*; /** * @author Yann Cébron */ public class StrutsFilesTree extends CheckboxTreeBase { private static final Comparator<PsiFile> FILE_COMPARATOR = new Comparator<PsiFile>() { public int compare(final PsiFile o1, final PsiFile o2) { return o1.getName().compareTo(o2.getName()); } }; public StrutsFilesTree() { super(new CheckboxTreeCellRendererBase() { public void customizeRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { if (!(value instanceof DefaultMutableTreeNode)) return; final ColoredTreeCellRenderer renderer = getTextRenderer(); final Object object = ((DefaultMutableTreeNode) value).getUserObject(); if (object instanceof Module) { final Module module = (Module) object; final Icon icon = ModuleType.get(module).getNodeIcon(expanded); renderer.setIcon(icon); final String moduleName = module.getName(); renderer.append(moduleName, SimpleTextAttributes.REGULAR_ATTRIBUTES); } else if (object instanceof PsiFile) { final PsiFile psiFile = (PsiFile) object; final Icon icon = psiFile.getIcon(0); renderer.setIcon(icon); final String fileName = psiFile.getName(); renderer.append(fileName, SimpleTextAttributes.REGULAR_ATTRIBUTES); final VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile != null) { String path = virtualFile.getPath(); final int i = path.indexOf(JarFileSystem.JAR_SEPARATOR); if (i >= 0) { path = path.substring(i + JarFileSystem.JAR_SEPARATOR.length()); } renderer.append(" (" + path + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); } } else if (object instanceof VirtualFile) { final VirtualFile file = (VirtualFile) object; renderer.setIcon(VirtualFilePresentation.getIcon(file)); renderer.append(file.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); String path = file.getPath(); final int i = path.indexOf(JarFileSystem.JAR_SEPARATOR); if (i >= 0) { path = path.substring(i + JarFileSystem.JAR_SEPARATOR.length()); } renderer.append(" (" + path + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); } } }, null); PeerFactory.getInstance().getUIHelper().installTreeSpeedSearch(this, new Convertor<TreePath, String>() { public String convert(final TreePath treePath) { final Object object = ((CheckedTreeNode) treePath.getLastPathComponent()).getUserObject(); if (object instanceof Module) { return ((Module) object).getName(); } else if (object instanceof PsiFile) { return ((PsiFile) object).getName(); } else if (object instanceof VirtualFile) { return ((VirtualFile) object).getName(); } else { return ""; } } }); } public Set<PsiFile> buildModuleNodes(final MultiMap<Module, PsiFile> files, final MultiMap<VirtualFile, PsiFile> jars, final StrutsFileSet fileSet) { final CheckedTreeNode root = (CheckedTreeNode) getModel().getRoot(); final HashSet<PsiFile> psiFiles = new HashSet<PsiFile>(); final List<Module> modules = new ArrayList<Module>(files.keySet()); Collections.sort(modules, new Comparator<Module>() { public int compare(final Module o1, final Module o2) { return o1.getName().compareTo(o2.getName()); } }); for (final Module module : modules) { final CheckedTreeNode moduleNode = new CheckedTreeNode(module); moduleNode.setChecked(false); root.add(moduleNode); if (files.containsKey(module)) { final List<PsiFile> moduleFiles = new ArrayList<PsiFile>(files.get(module)); Collections.sort(moduleFiles, FILE_COMPARATOR); for (final PsiFile file : moduleFiles) { final CheckedTreeNode fileNode = createFileNode(file, fileSet); moduleNode.add(fileNode); psiFiles.add(file); } } } for (final VirtualFile file : jars.keySet()) { final List<PsiFile> list = new ArrayList<PsiFile>(jars.get(file)); final PsiFile jar = list.get(0).getManager().findFile(file); if (jar != null) { final CheckedTreeNode jarNode = new CheckedTreeNode(jar); jarNode.setChecked(false); root.add(jarNode); Collections.sort(list, FILE_COMPARATOR); for (final PsiFile psiFile : list) { final CheckedTreeNode vfNode = createFileNode(psiFile, fileSet); jarNode.add(vfNode); psiFiles.add(psiFile); } } } return psiFiles; } public void updateFileSet(final StrutsFileSet fileSet) { final boolean[] result = new boolean[]{false}; final Set<VirtualFile> configured = new HashSet<VirtualFile>(); TreeUtil.traverse((TreeNode) getModel().getRoot(), new TreeUtil.Traverse() { public boolean accept(final Object node) { final CheckedTreeNode checkedTreeNode = (CheckedTreeNode) node; if (!checkedTreeNode.isChecked()) { return true; } final Object object = checkedTreeNode.getUserObject(); VirtualFile virtualFile = null; if (object instanceof XmlFile) { virtualFile = ((XmlFile) object).getVirtualFile(); } else if (object instanceof VirtualFile) { virtualFile = (VirtualFile) object; } if (virtualFile != null) { if (!fileSet.hasFile(virtualFile)) { result[0] = true; fileSet.addFile(virtualFile); } configured.add(virtualFile); } return true; } }); for (Iterator<VirtualFilePointer> i = fileSet.getFiles().iterator(); i.hasNext(); ) { final VirtualFilePointer pointer = i.next(); final VirtualFile file = pointer.getFile(); if (file == null || !configured.contains(file)) { result[0] = true; i.remove(); } } } private static CheckedTreeNode createFileNode(final PsiFile file, final StrutsFileSet fileSet) { final CheckedTreeNode fileNode = new CheckedTreeNode(file); fileNode.setChecked(fileSet.hasFile(file.getVirtualFile())); return fileNode; } public void addFile(final VirtualFile file) { final CheckedTreeNode root = (CheckedTreeNode) getModel().getRoot(); final CheckedTreeNode treeNode = new CheckedTreeNode(file); root.add(treeNode); final DefaultTreeModel model = (DefaultTreeModel) getModel(); model.nodeStructureChanged(root); } }