001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.resolve.java;
018    
019    import com.google.common.collect.Lists;
020    import com.intellij.core.CoreJavaFileManager;
021    import com.intellij.openapi.progress.ProgressIndicatorProvider;
022    import com.intellij.openapi.project.Project;
023    import com.intellij.psi.PsiClass;
024    import com.intellij.psi.PsiElementFinder;
025    import com.intellij.psi.PsiPackage;
026    import com.intellij.psi.impl.JavaPsiFacadeImpl;
027    import com.intellij.psi.impl.file.impl.JavaFileManager;
028    import com.intellij.psi.search.GlobalSearchScope;
029    import org.jetbrains.annotations.NotNull;
030    import org.jetbrains.annotations.Nullable;
031    
032    import java.util.List;
033    
034    /**
035     * TODO Temporary class until {@link JavaPsiFacadeImpl} hacked.
036     *
037     * @see JavaPsiFacadeImpl
038     */
039    public class JavaPsiFacadeKotlinHacks {
040        public interface KotlinFinderMarker {}
041    
042        private final JavaFileManager javaFileManager;
043        private final List<PsiElementFinder> extensionPsiElementFinders;
044    
045        public JavaPsiFacadeKotlinHacks(@NotNull Project project) {
046            this.javaFileManager = findJavaFileManager(project);
047            this.extensionPsiElementFinders = Lists.newArrayList();
048            for (PsiElementFinder finder : project.getExtensions(PsiElementFinder.EP_NAME)) {
049                if (!(finder instanceof KotlinFinderMarker)) {
050                    this.extensionPsiElementFinders.add(finder);
051                }
052            }
053        }
054    
055        @NotNull
056        private JavaFileManager findJavaFileManager(@NotNull Project project) {
057            JavaFileManager javaFileManager = project.getComponent(JavaFileManager.class);
058            if (javaFileManager != null) {
059                return javaFileManager;
060            }
061            javaFileManager = project.getComponent(CoreJavaFileManager.class);
062            if (javaFileManager != null) {
063                // TODO: why it is not found by JavaFileManager?
064                return javaFileManager;
065            }
066            throw new IllegalStateException("JavaFileManager component is not found in project");
067        }
068    
069        @Nullable
070        public PsiPackage findPackage(@NotNull String qualifiedName) {
071            PsiPackage psiPackage = javaFileManager.findPackage(qualifiedName);
072            if (psiPackage != null) {
073                return psiPackage;
074            }
075    
076            for (PsiElementFinder finder : extensionPsiElementFinders) {
077                psiPackage = finder.findPackage(qualifiedName);
078                if (psiPackage != null) {
079                    return psiPackage;
080                }
081            }
082            return psiPackage;
083        }
084    
085        public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
086            ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
087    
088            PsiClass aClass = javaFileManager.findClass(qualifiedName, scope);
089            if (aClass != null) {
090                return aClass;
091            }
092    
093            for (PsiElementFinder finder : extensionPsiElementFinders) {
094                aClass = finder.findClass(qualifiedName, scope);
095                if (aClass != null) {
096                    return aClass;
097                }
098            }
099    
100            return null;
101        }
102    
103    }