update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / ide / util / JavaUtil.java
blobe71d32f0448fdf3ba042d3686ec9eb9d5a19f561
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.ide.util;
18 import com.intellij.lexer.JavaLexer;
19 import com.intellij.lexer.Lexer;
20 import com.intellij.openapi.fileTypes.FileType;
21 import com.intellij.openapi.fileTypes.FileTypeManager;
22 import com.intellij.openapi.fileTypes.StdFileTypes;
23 import com.intellij.openapi.progress.ProgressIndicator;
24 import com.intellij.openapi.progress.ProgressManager;
25 import com.intellij.openapi.util.Pair;
26 import com.intellij.openapi.util.SystemInfo;
27 import com.intellij.openapi.util.io.FileUtil;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.pom.java.LanguageLevel;
30 import com.intellij.psi.JavaTokenType;
31 import com.intellij.util.text.CharArrayCharSequence;
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
39 public class JavaUtil {
41 public static List<Pair<File,String>> suggestRoots(File dir) {
42 ArrayList<Pair<File,String>> foundDirectories = new ArrayList<Pair<File, String>>();
43 try{
44 suggestRootsImpl(dir, dir, foundDirectories);
46 catch(PathFound found){
48 return foundDirectories;
51 private static class PathFound extends Exception {
52 public File myDirectory;
54 public PathFound(File directory) {
55 myDirectory = directory;
59 private static void suggestRootsImpl(File base, File dir, ArrayList<? super Pair<File, String>> foundDirectories) throws PathFound {
60 if (!dir.isDirectory()) {
61 return;
63 FileTypeManager typeManager = FileTypeManager.getInstance();
64 if (typeManager.isFileIgnored(dir.getName())) {
65 return;
67 final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
68 if (progressIndicator != null) {
69 if (progressIndicator.isCanceled()) {
70 return;
72 progressIndicator.setText2(dir.getPath());
75 File[] list = dir.listFiles();
76 if (list == null || list.length == 0) {
77 return;
79 for (File child : list) {
80 if (child.isFile()) {
81 FileType type = typeManager.getFileTypeByFileName(child.getName());
82 if (StdFileTypes.JAVA == type) {
83 if (progressIndicator != null && progressIndicator.isCanceled()) {
84 return;
86 Pair<File, String> root = suggestRootForJavaFile(child);
87 if (root != null) {
88 String packagePrefix = getPackagePrefix(base, root);
89 if (packagePrefix == null) {
90 foundDirectories.add(root);
92 else {
93 foundDirectories.add(Pair.create(base, packagePrefix));
95 throw new PathFound(root.getFirst());
97 else {
98 return;
104 for (File child : list) {
105 if (child.isDirectory()) {
106 try {
107 suggestRootsImpl(base, child, foundDirectories);
109 catch (PathFound found) {
110 if (!found.myDirectory.equals(child)) {
111 throw found;
118 private static String getPackagePrefix(File base, Pair<File,String> root) {
119 String result = "";
120 for (File parent = base; parent != null; parent = parent.getParentFile()) {
121 if (parent.equals(root.getFirst())) {
122 return root.getSecond() + (root.getSecond().length() > 0 && result.length() > 0 ? "." : "") + result;
124 result = parent.getName() + (result.length() > 0 ? "." : "") + result;
126 return null;
130 private static Pair<File,String> suggestRootForJavaFile(File javaFile) {
131 if (!javaFile.isFile()) {
132 return null;
135 try {
136 final CharSequence chars = new CharArrayCharSequence(FileUtil.loadFileText(javaFile));
138 String packageName = getPackageStatement(chars);
139 if (packageName != null) {
140 File root = javaFile.getParentFile();
141 int index = packageName.length();
142 while (index > 0) {
143 int index1 = packageName.lastIndexOf('.', index - 1);
144 String token = packageName.substring(index1 + 1, index);
145 String dirName = root.getName();
146 final boolean equalsToToken = SystemInfo.isFileSystemCaseSensitive ? dirName.equals(token) : dirName.equalsIgnoreCase(token);
147 if (!equalsToToken) {
148 return Pair.create(root, packageName.substring(0, index));
150 String parent = root.getParent();
151 if (parent == null) {
152 return null;
154 root = new File(parent);
155 index = index1;
157 return Pair.create(root, "");
160 catch(IOException e){
161 return null;
164 return null;
167 private static String getPackageStatement(CharSequence text){
168 Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3);
169 lexer.start(text);
170 skipWhiteSpaceAndComments(lexer);
171 if (lexer.getTokenType() != JavaTokenType.PACKAGE_KEYWORD) return "";
172 lexer.advance();
173 skipWhiteSpaceAndComments(lexer);
174 StringBuilder buffer = new StringBuilder();
175 while(true){
176 if (lexer.getTokenType() != JavaTokenType.IDENTIFIER) break;
177 buffer.append(text, lexer.getTokenStart(), lexer.getTokenEnd());
178 lexer.advance();
179 skipWhiteSpaceAndComments(lexer);
180 if (lexer.getTokenType() != JavaTokenType.DOT) break;
181 buffer.append('.');
182 lexer.advance();
183 skipWhiteSpaceAndComments(lexer);
185 String packageName = buffer.toString();
186 if (packageName.length() == 0 || StringUtil.endsWithChar(packageName, '.')) return null;
187 return packageName;
190 private static void skipWhiteSpaceAndComments(Lexer lexer){
191 while(JavaTokenType.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(lexer.getTokenType())) {
192 lexer.advance();