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.intellij.openapi.project.Project;
020    import com.intellij.openapi.vfs.VirtualFile;
021    import com.intellij.psi.PsiClass;
022    import com.intellij.psi.PsiPackage;
023    import com.intellij.psi.search.DelegatingGlobalSearchScope;
024    import com.intellij.psi.search.GlobalSearchScope;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
028    import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
029    import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl;
030    import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPackageImpl;
031    import org.jetbrains.jet.lang.resolve.name.ClassId;
032    import org.jetbrains.jet.lang.resolve.name.FqName;
033    import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
034    import org.jetbrains.jet.plugin.JetFileType;
035    
036    import javax.annotation.PostConstruct;
037    import javax.inject.Inject;
038    
039    public class JavaClassFinderImpl implements JavaClassFinder {
040        private Project project;
041        private GlobalSearchScope baseScope;
042    
043        private GlobalSearchScope javaSearchScope;
044        private JavaPsiFacadeKotlinHacks javaFacade;
045    
046        @Inject
047        public void setProject(@NotNull Project project) {
048            this.project = project;
049        }
050    
051        @Inject
052        public void setScope(@NotNull GlobalSearchScope scope) {
053            this.baseScope = scope;
054        }
055    
056        @Inject
057        public void setComponentPostConstruct(@NotNull JavaClassFinderPostConstruct finderPostConstruct) {
058            // Only activate post create
059        }
060    
061        @PostConstruct
062        public void initialize() {
063            javaSearchScope = new DelegatingGlobalSearchScope(baseScope) {
064                @Override
065                public boolean contains(@NotNull VirtualFile file) {
066                    return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
067                }
068    
069                //NOTE: expected by class finder to be not null
070                @NotNull
071                @Override
072                public Project getProject() {
073                    return project;
074                }
075            };
076            javaFacade = new JavaPsiFacadeKotlinHacks(project);
077        }
078    
079        @Nullable
080        @Override
081        public JavaClass findClass(@NotNull ClassId classId) {
082            FqNameUnsafe fqName = classId.asSingleFqName();
083    
084            PsiClass psiClass = javaFacade.findClass(fqName.asString(), javaSearchScope);
085            if (psiClass == null) return null;
086    
087            JavaClassImpl javaClass = new JavaClassImpl(psiClass);
088    
089            if (!fqName.equalsTo(javaClass.getFqName())) {
090                throw new IllegalStateException("Requested " + fqName + ", got " + javaClass.getFqName());
091            }
092    
093            if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
094                throw new IllegalStateException("Kotlin light classes should not be found by JavaPsiFacade, resolving: " + fqName);
095            }
096    
097            return javaClass;
098        }
099    
100        @Nullable
101        @Override
102        public JavaPackage findPackage(@NotNull FqName fqName) {
103            PsiPackage psiPackage = javaFacade.findPackage(fqName.asString());
104            return psiPackage == null ? null : new JavaPackageImpl(psiPackage, javaSearchScope);
105        }
106    }