blob: ea969f32f2d27b938086b09e83bdd433dcb01840 [file] [log] [blame]
/*
* 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;
}
}