| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * 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.ide.util.treeView; |
| |
| import com.intellij.openapi.fileTypes.FileTypeManager; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.Key; |
| import com.intellij.openapi.util.UserDataHolderEx; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.JavaDirectoryService; |
| import com.intellij.psi.PsiDirectory; |
| import com.intellij.psi.PsiManager; |
| import com.intellij.psi.PsiPackage; |
| import com.intellij.psi.impl.PsiManagerEx; |
| import com.intellij.util.containers.ConcurrentWeakHashMap; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.concurrent.ConcurrentMap; |
| |
| /** |
| * @author Eugene Zhuravlev |
| * Date: Oct 6, 2004 |
| */ |
| public class TreeViewUtil { |
| private static final int SUBPACKAGE_LIMIT = 2; |
| private static final Key<ConcurrentMap<PsiPackage,Boolean>> SHOULD_ABBREV_PACK_KEY = Key.create("PACK_ABBREV_CACHE"); |
| |
| private static boolean shouldAbbreviateName(PsiPackage aPackage) { |
| final Project project = aPackage.getProject(); |
| ConcurrentMap<PsiPackage, Boolean> map = project.getUserData(SHOULD_ABBREV_PACK_KEY); |
| if (map == null) { |
| final ConcurrentWeakHashMap<PsiPackage, Boolean> newMap = new ConcurrentWeakHashMap<PsiPackage, Boolean>(); |
| map = ((UserDataHolderEx)project).putUserDataIfAbsent(SHOULD_ABBREV_PACK_KEY, newMap); |
| if (map == newMap) { |
| ((PsiManagerEx)PsiManager.getInstance(project)).registerRunnableToRunOnChange(new Runnable() { |
| @Override |
| public void run() { |
| newMap.clear(); |
| } |
| }); |
| } |
| } |
| |
| Boolean ret = map.get(aPackage); |
| if (ret != null) return ret; |
| ret = scanPackages(aPackage, 1); |
| map.put(aPackage, ret); |
| return ret; |
| } |
| |
| private static boolean scanPackages(@NotNull PsiPackage p, int packageNameOccurrencesFound) { |
| final PsiPackage[] subPackages = p.getSubPackages(); |
| packageNameOccurrencesFound += subPackages.length; |
| if (packageNameOccurrencesFound > SUBPACKAGE_LIMIT) { |
| return true; |
| } |
| for (PsiPackage subPackage : subPackages) { |
| if (scanPackages(subPackage, packageNameOccurrencesFound)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @NotNull |
| public static String calcAbbreviatedPackageFQName(@NotNull PsiPackage aPackage) { |
| final StringBuilder name = new StringBuilder(aPackage.getName()); |
| for (PsiPackage parentPackage = aPackage.getParentPackage(); parentPackage != null; parentPackage = parentPackage.getParentPackage()) { |
| final String packageName = parentPackage.getName(); |
| if (packageName == null || packageName.isEmpty()) { |
| break; // reached default package |
| } |
| name.insert(0, "."); |
| if (packageName.length() > 2 && shouldAbbreviateName(parentPackage)) { |
| name.insert(0, packageName.substring(0, 1)); |
| } |
| else { |
| name.insert(0, packageName); |
| } |
| } |
| return name.toString(); |
| } |
| |
| /** |
| * a directory is considered "empty" if it has at least one child and all its children are only directories |
| * |
| * @param strictlyEmpty if true, the package is considered empty if it has only 1 child and this child is a directory |
| * otherwise the package is considered as empty if all direct children that it has are directories |
| */ |
| public static boolean isEmptyMiddlePackage(@NotNull PsiDirectory dir, boolean strictlyEmpty) { |
| final VirtualFile[] files = dir.getVirtualFile().getChildren(); |
| if (files.length == 0) { |
| return false; |
| } |
| PsiManager manager = dir.getManager(); |
| int subpackagesCount = 0; |
| int directoriesCount = 0; |
| for (VirtualFile file : files) { |
| if (FileTypeManager.getInstance().isFileIgnored(file)) continue; |
| if (!file.isDirectory()) return false; |
| PsiDirectory childDir = manager.findDirectory(file); |
| if (childDir != null) { |
| directoriesCount++; |
| if (strictlyEmpty && directoriesCount > 1) return false; |
| if (JavaDirectoryService.getInstance().getPackage(childDir) != null) { |
| subpackagesCount++; |
| } |
| } |
| } |
| if (strictlyEmpty) { |
| return directoriesCount == subpackagesCount && directoriesCount == 1; |
| } |
| return directoriesCount == subpackagesCount && directoriesCount > 0; |
| } |
| } |