2 * Copyright 2000-2011 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.psi.stubs;
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.application.ModalityState;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.editor.Document;
22 import com.intellij.openapi.fileEditor.FileDocumentManager;
23 import com.intellij.openapi.project.DumbService;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.vfs.VirtualFile;
26 import com.intellij.psi.search.GlobalSearchScopes;
27 import com.intellij.util.indexing.FileBasedIndex;
28 import com.intellij.util.indexing.FileContent;
29 import com.intellij.util.indexing.FileContentImpl;
30 import com.intellij.util.indexing.IndexingStamp;
31 import org.jetbrains.annotations.Nullable;
33 import java.io.IOException;
34 import java.util.List;
39 public class StubTreeLoaderImpl extends StubTreeLoader {
40 private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.StubTreeLoaderImpl");
43 public StubTree readOrBuild(Project project, final VirtualFile vFile) {
44 final StubTree fromIndices = readFromVFile(project, vFile);
45 if (fromIndices != null) {
49 if (!canHaveStub(vFile)) {
54 final FileContent fc = new FileContentImpl(vFile, vFile.contentsToByteArray());
55 fc.putUserData(FileBasedIndex.PROJECT, project);
56 final StubElement element = StubUpdatingIndex.buildStubTree(fc);
57 if (element instanceof PsiFileStub) {
58 return new StubTree((PsiFileStub)element);
61 catch (IOException e) {
62 throw new RuntimeException(e);
69 public StubTree readFromVFile(Project project, final VirtualFile vFile) {
70 if (DumbService.getInstance(project).isDumb()) {
74 final int id = Math.abs(FileBasedIndex.getFileId(vFile));
76 final List<SerializedStubTree> datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScopes
77 .fileScope(project, vFile));
78 final int size = datas.size();
81 StubElement stub = datas.get(0).getStub();
82 return new StubTree((PsiFileStub)stub);
85 LOG.error("Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id);
87 ApplicationManager.getApplication().invokeLater(new Runnable() {
89 final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile);
91 FileDocumentManager.getInstance().saveDocument(doc);
94 }, ModalityState.NON_MODAL);
96 FileBasedIndex.getInstance().requestReindex(vFile);
104 public void rebuildStubTree(VirtualFile virtualFile) {
105 FileBasedIndex.getInstance().requestReindex(virtualFile);
109 public long getStubTreeTimestamp(VirtualFile vFile) {
110 return IndexingStamp.getIndexStamp(vFile, StubUpdatingIndex.INDEX_ID);
114 public boolean canHaveStub(VirtualFile file) {
115 return StubUpdatingIndex.canHaveStub(file);