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        @PostConstruct
057        public void initialize() {
058            javaSearchScope = new DelegatingGlobalSearchScope(baseScope) {
059                @Override
060                public boolean contains(@NotNull VirtualFile file) {
061                    return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
062                }
063    
064                //NOTE: expected by class finder to be not null
065                @NotNull
066                @Override
067                public Project getProject() {
068                    return project;
069                }
070            };
071            javaFacade = new JavaPsiFacadeKotlinHacks(project);
072        }
073    
074        @Nullable
075        @Override
076        public JavaClass findClass(@NotNull ClassId classId) {
077            FqNameUnsafe fqName = classId.asSingleFqName();
078    
079            PsiClass psiClass = javaFacade.findClass(fqName.asString(), javaSearchScope);
080            if (psiClass == null) return null;
081    
082            JavaClassImpl javaClass = new JavaClassImpl(psiClass);
083    
084            if (!fqName.equalsTo(javaClass.getFqName())) {
085                throw new IllegalStateException("Requested " + fqName + ", got " + javaClass.getFqName());
086            }
087    
088            if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
089                throw new IllegalStateException("Kotlin light classes should not be found by JavaPsiFacade, resolving: " + fqName);
090            }
091    
092            return javaClass;
093        }
094    
095        @Nullable
096        @Override
097        public JavaPackage findPackage(@NotNull FqName fqName) {
098            PsiPackage psiPackage = javaFacade.findPackage(fqName.asString());
099            return psiPackage == null ? null : new JavaPackageImpl(psiPackage);
100        }
101    }