use FileContent in on-the-fly facet autodetection to avoid reloading file content

This commit is contained in:
nik
2010-10-22 09:56:26 +04:00
parent c5a4f03582
commit 3a5e4a4e7b
13 changed files with 147 additions and 57 deletions
@@ -25,6 +25,7 @@ import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.FacetInfoBackedByFacet;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.ide.caches.FileContent;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
@@ -392,7 +393,7 @@ public class DetectedFacetManager implements Disposable {
}
}
for (VirtualFile file : files) {
myAutodetectingManager.processFile(file);
myAutodetectingManager.processFile(new FileContent(file));
}
}
@@ -16,6 +16,7 @@
package com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetType;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressManager;
@@ -146,7 +147,7 @@ public class EnableAutodetectionWorker {
}
}
else {
myFacetAutodetectingManager.processFile(file);
myFacetAutodetectingManager.processFile(new FileContent(file));
}
}
@@ -25,6 +25,7 @@ import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ProjectComponent;
@@ -36,7 +37,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.*;
import com.intellij.util.SmartList;
import com.intellij.util.ui.update.MergingUpdateQueue;
@@ -153,23 +153,24 @@ public class FacetAutodetectingManagerImpl extends FacetAutodetectingManager imp
myDisabledAutodetectionInfo = state;
}
public void processFile(VirtualFile virtualFile) {
if (!virtualFile.isValid() || virtualFile.isDirectory() || myProject.isDisposed()
|| !virtualFile.exists() || !myFileIndex.getProjectFileIndex().isInContent(virtualFile)) return;
public void processFile(FileContent fileContent) {
final VirtualFile file = fileContent.getVirtualFile();
if (!file.isValid() || file.isDirectory() || myProject.isDisposed()
|| !file.exists() || !myFileIndex.getProjectFileIndex().isInContent(file)) return;
FileType fileType = virtualFile.getFileType();
FileType fileType = file.getFileType();
Collection<FacetDetectorWrapper> detectors = myDetectors.get(fileType);
if (detectors == null) return;
List<FacetInfo2<Module>> facets = null;
for (FacetDetectorWrapper<?,?,?,?> detector : detectors) {
facets = process(virtualFile, detector, facets);
facets = process(file, fileContent, detector, facets);
}
String url = virtualFile.getUrl();
String url = file.getUrl();
FacetDetectionIndexEntry indexEntry = myFileIndex.getIndexEntry(url);
if (indexEntry == null) {
indexEntry = new FacetDetectionIndexEntry(virtualFile.getTimeStamp());
indexEntry = new FacetDetectionIndexEntry(file.getTimeStamp());
}
Collection<Integer> removed = indexEntry.update(myFacetPointersManager, facets);
@@ -193,9 +194,11 @@ public class FacetAutodetectingManagerImpl extends FacetAutodetectingManager imp
return myDetectedFacetSet;
}
private List<FacetInfo2<Module>> process(final VirtualFile virtualFile, final FacetDetectorWrapper<?, ?, ?, ?> detector,
List<FacetInfo2<Module>> facets) {
if (!myDetectionInProgress && detector.getVirtualFileFilter().accept(virtualFile)) {
private List<FacetInfo2<Module>> process(final VirtualFile virtualFile,
FileContent fileContent,
final FacetDetectorWrapper<?, ?, ?, ?> detector,
List<FacetInfo2<Module>> facets) {
if (!myDetectionInProgress && detector.getFileContentFilter().accept(fileContent)) {
try {
myDetectionInProgress = true;
FacetInfo2<Module> facet = detector.detectFacet(virtualFile, myPsiManager);
@@ -255,7 +258,7 @@ public class FacetAutodetectingManagerImpl extends FacetAutodetectingManager imp
public void queueUpdate(final VirtualFile file) {
Update update = new Update("file:" + file.getUrl()) {
public void run() {
processFile(file);
processFile(new FileContent(file));
}
};
@@ -346,23 +349,23 @@ public class FacetAutodetectingManagerImpl extends FacetAutodetectingManager imp
myType = type;
}
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter,
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final FileContentFilter fileContentFilter,
@NotNull final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myHasDetectors = true;
myId2Detector.put(facetDetector.getId(), facetDetector);
myDetectors.put(fileType, new FacetByVirtualFileDetectorWrapper<C, F, U>(myDetectedFacetSet, myType,
FacetAutodetectingManagerImpl.this, virtualFileFilter,
FacetAutodetectingManagerImpl.this, fileContentFilter,
facetDetector, selector));
}
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter,
public <U extends FacetConfiguration> void register(@NotNull final FileType fileType, @NotNull final FileContentFilter fileContentFilter,
@NotNull final Condition<PsiFile> psiFileFilter, @NotNull final FacetDetector<PsiFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myHasDetectors = true;
myId2Detector.put(facetDetector.getId(), facetDetector);
myDetectors.put(fileType, new FacetByPsiFileDetectorWrapper<C, F, U>(myDetectedFacetSet, myType, FacetAutodetectingManagerImpl.this,
virtualFileFilter, facetDetector, psiFileFilter, selector));
fileContentFilter, facetDetector, psiFileFilter, selector));
}
public boolean hasDetectors() {
@@ -27,7 +27,6 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -38,10 +37,10 @@ public class FacetByPsiFileDetectorWrapper<C extends FacetConfiguration, F exten
private final Condition<PsiFile> myPsiFileFilter;
public FacetByPsiFileDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType,
final AutodetectionFilter autodetectionFilter, final VirtualFileFilter virtualFileFilter,
final AutodetectionFilter autodetectionFilter, final FileContentFilter fileContentFilter,
final FacetDetector<PsiFile, C> facetDetector,
Condition<PsiFile> psiFileFilter, final UnderlyingFacetSelector<VirtualFile, U> selector) {
super(projectFacetSet, facetType, autodetectionFilter, virtualFileFilter, facetDetector, selector);
super(projectFacetSet, facetType, autodetectionFilter, fileContentFilter, facetDetector, selector);
myPsiFileFilter = psiFileFilter;
}
@@ -26,7 +26,6 @@ import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.Nullable;
@@ -35,10 +34,10 @@ import org.jetbrains.annotations.Nullable;
*/
public class FacetByVirtualFileDetectorWrapper<C extends FacetConfiguration, F extends Facet<C>, U extends FacetConfiguration> extends FacetDetectorWrapper<VirtualFile, C, F, U> {
public FacetByVirtualFileDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType,
final AutodetectionFilter autodetectionFilter, final VirtualFileFilter virtualFileFilter,
final AutodetectionFilter autodetectionFilter, final FileContentFilter fileContentFilter,
final FacetDetector<VirtualFile, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
super(projectFacetSet, facetType, autodetectionFilter, virtualFileFilter, facetDetector, selector);
super(projectFacetSet, facetType, autodetectionFilter, fileContentFilter, facetDetector, selector);
}
@Nullable
@@ -22,6 +22,7 @@ import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.impl.autodetecting.model.DetectedFacetInfo;
import com.intellij.facet.pointers.FacetPointer;
import com.intellij.facet.pointers.FacetPointersManager;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
@@ -135,8 +136,8 @@ public class FacetDetectionIndex extends AbstractFileIndex<FacetDetectionIndexEn
myAutodetectingManager.queueUpdate(file);
}
protected void doUpdateIndexEntry(final VirtualFile file) {
myAutodetectingManager.processFile(file);
protected void doUpdateIndexEntry(final FileContent fileContent) {
myAutodetectingManager.processFile(fileContent);
}
@Nullable
@@ -16,28 +16,32 @@
package com.intellij.facet.impl.autodetecting;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetModel;
import com.intellij.facet.FacetType;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.FacetDetectorRegistry;
import com.intellij.facet.autodetecting.DetectedFacetPresentation;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.patterns.VirtualFilePattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.patterns.*;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.cache.impl.CacheUtil;
import com.intellij.util.text.CharSequenceReader;
import com.intellij.util.xml.NanoXmlUtil;
import com.intellij.util.xml.XmlFileHeader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import java.io.IOException;
import java.util.Collection;
/**
@@ -57,6 +61,37 @@ public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements Fa
myPresentation = presentation;
}
public void registerUniversalDetectorByRootTag(@NotNull final String rootTag, @NotNull final FacetDetector<VirtualFile, C> detector) {
registerUniversalDetector(StdFileTypes.XML, new VirtualFileFilter() {
@Override
public boolean accept(VirtualFile file) {
try {
return rootTag.equals(NanoXmlUtil.parseHeaderWithException(file).getRootTagLocalName());
}
catch (IOException e) {
return false;
}
}
}, new FileContentFilter() {
@Override
public boolean accept(FileContent fileContent) {
try {
return rootTag.equals(parseHeaderWithException(fileContent).getRootTagLocalName());
}
catch (IOException e) {
return false;
}
}
}, detector);
}
@NotNull
private static XmlFileHeader parseHeaderWithException(FileContent fileContent) throws IOException {
final CharSequence contentText = CacheUtil.getContentText(fileContent);
//noinspection IOResourceOpenedButNotSafelyClosed
return NanoXmlUtil.parseHeaderWithException(new CharSequenceReader(contentText));
}
public <U extends FacetConfiguration> void registerUniversalDetectorByFileNameAndRootTag(@NotNull @NonNls String fileName,
@NotNull @NonNls String rootTag,
@NotNull final FacetDetector<VirtualFile, C> detector,
@@ -101,7 +136,7 @@ public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements Fa
@NotNull final FacetDetector<PsiFile, C> facetDetector,
@Nullable UnderlyingFacetSelector<VirtualFile, U> selector) {
if (myOnTheFlyDelegate != null) {
myOnTheFlyDelegate.register(fileType, virtualFileFilter, psiFileFilter, facetDetector, selector);
myOnTheFlyDelegate.register(fileType, new MyFileContentFilter(virtualFileFilter), psiFileFilter, facetDetector, selector);
}
}
@@ -136,11 +171,16 @@ public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements Fa
}
public void registerUniversalDetector(@NotNull final FileType fileType, @NotNull final VirtualFileFilter virtualFileFilter, @NotNull final FacetDetector<VirtualFile, C> facetDetector) {
registerUniversalDetector(fileType, virtualFileFilter, new MyFileContentFilter(virtualFileFilter), facetDetector);
}
private void registerUniversalDetector(@NotNull final FileType fileType, @NotNull VirtualFileFilter virtualFileFilter, @NotNull final FileContentFilter fileContentFilter,
@NotNull final FacetDetector<VirtualFile, C> facetDetector) {
if (myForWizardDelegate != null) {
myForWizardDelegate.register(fileType, virtualFileFilter, facetDetector);
}
if (myOnTheFlyDelegate != null) {
myOnTheFlyDelegate.register(fileType, virtualFileFilter, facetDetector, null);
myOnTheFlyDelegate.register(fileType, fileContentFilter, facetDetector, null);
}
}
@@ -149,7 +189,7 @@ public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements Fa
final UnderlyingFacetSelector<VirtualFile, U> underlyingFacetSelector) {
registerSubFacetDetectorForWizard(fileType, virtualFilePattern, facetDetector, underlyingFacetSelector);
if (myOnTheFlyDelegate != null) {
myOnTheFlyDelegate.register(fileType, new MyPatternFilter(virtualFilePattern), facetDetector, underlyingFacetSelector);
myOnTheFlyDelegate.register(fileType, new MyFileContentFilter(new MyPatternFilter(virtualFilePattern)), facetDetector, underlyingFacetSelector);
}
}
@@ -189,4 +229,17 @@ public class FacetDetectorRegistryEx<C extends FacetConfiguration> implements Fa
DetectedFacetPresentation presentation = registry.myPresentation;
return presentation != null ? presentation : DefaultDetectedFacetPresentation.INSTANCE;
}
private static class MyFileContentFilter implements FileContentFilter {
private final VirtualFileFilter myVirtualFileFilter;
public MyFileContentFilter(VirtualFileFilter virtualFileFilter) {
myVirtualFileFilter = virtualFileFilter;
}
@Override
public boolean accept(FileContent fileContent) {
return myVirtualFileFilter.accept(fileContent.getVirtualFile());
}
}
}
@@ -16,19 +16,23 @@
package com.intellij.facet.impl.autodetecting;
import com.intellij.facet.*;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.model.*;
import com.intellij.facet.impl.autodetecting.model.FacetInfo2;
import com.intellij.facet.impl.autodetecting.model.ProjectFacetInfoSet;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Collections;
import java.util.Map;
/**
* @author nik
@@ -36,25 +40,25 @@ import java.util.*;
public abstract class FacetDetectorWrapper<S, C extends FacetConfiguration, F extends Facet<C>, U extends FacetConfiguration> {
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.autodetecting.FacetDetectorWrapper");
private final AutodetectionFilter myAutodetectionFilter;
private final VirtualFileFilter myVirtualFileFilter;
private final FileContentFilter myFileContentFilter;
private final FacetDetector<S,C> myFacetDetector;
private final UnderlyingFacetSelector<VirtualFile, U> myUnderlyingFacetSelector;
private final ProjectFacetInfoSet myDetectedFacetSet;
private final FacetType<F,C> myFacetType;
protected FacetDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType, final AutodetectionFilter autodetectionFilter, final VirtualFileFilter virtualFileFilter,
protected FacetDetectorWrapper(ProjectFacetInfoSet projectFacetSet, FacetType<F, C> facetType, final AutodetectionFilter autodetectionFilter, final FileContentFilter fileContentFilter,
final FacetDetector<S, C> facetDetector,
final UnderlyingFacetSelector<VirtualFile, U> selector) {
myDetectedFacetSet = projectFacetSet;
myFacetType = facetType;
myAutodetectionFilter = autodetectionFilter;
myVirtualFileFilter = virtualFileFilter;
myFileContentFilter = fileContentFilter;
myFacetDetector = facetDetector;
myUnderlyingFacetSelector = selector;
}
public VirtualFileFilter getVirtualFileFilter() {
return myVirtualFileFilter;
public FileContentFilter getFileContentFilter() {
return myFileContentFilter;
}
public FacetType<?, C> getFacetType() {
@@ -20,9 +20,8 @@ import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.autodetecting.FacetDetector;
import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -31,11 +30,11 @@ import org.jetbrains.annotations.NotNull;
*/
public interface FacetOnTheFlyDetectorRegistry<C extends FacetConfiguration> {
<U extends FacetConfiguration>
void register(@NotNull FileType fileType, @NotNull VirtualFileFilter virtualFileFilter,
void register(@NotNull FileType fileType, @NotNull FileContentFilter virtualFileFilter,
@NotNull FacetDetector<VirtualFile, C> detector, UnderlyingFacetSelector<VirtualFile, U> selector);
<U extends FacetConfiguration>
void register(@NotNull FileType fileType, @NotNull VirtualFileFilter virtualFileFilter,
void register(@NotNull FileType fileType, @NotNull FileContentFilter virtualFileFilter,
@NotNull Condition<PsiFile> psiFileFilter, @NotNull FacetDetector<PsiFile, C> detector,
UnderlyingFacetSelector<VirtualFile, U> selector);
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.facet.impl.autodetecting;
import com.intellij.ide.caches.FileContent;
/**
* @author nik
*/
public interface FileContentFilter {
boolean accept(FileContent fileContent);
}
@@ -131,6 +131,11 @@ public class NanoXmlUtil {
}
}
@NotNull
public static XmlFileHeader parseHeaderWithException(Reader reader) throws IOException {
return parseHeader(new MyXMLReader(reader));
}
@NotNull
public static XmlFileHeader parseHeaderWithException(final VirtualFile file) throws IOException {
return parseHeader(new MyXMLReader(file.getInputStream()));
@@ -76,7 +76,7 @@ public abstract class AbstractFileIndex<IndexEntry extends FileIndexEntry> imple
public abstract void queueEntryUpdate(final VirtualFile file);
protected abstract void doUpdateIndexEntry(final VirtualFile file);
protected abstract void doUpdateIndexEntry(final FileContent fileContent);
public ProjectFileIndex getProjectFileIndex() {
return myProjectFileIndex;
@@ -87,12 +87,12 @@ public abstract class AbstractFileIndex<IndexEntry extends FileIndexEntry> imple
return new File(PathManager.getSystemPath() + File.separator + dirName + File.separator + cacheFileName);
}
public final void updateIndexEntry(final VirtualFile file) {
if (!myStartupManager.startupActivityPassed() || myProjectFileIndex.isIgnored(file)) {
public final void updateIndexEntry(final FileContent fileContent) {
if (!myStartupManager.startupActivityPassed() || myProjectFileIndex.isIgnored(fileContent.getVirtualFile())) {
return;
}
doUpdateIndexEntry(file);
doUpdateIndexEntry(fileContent);
}
public final void removeIndexEntry(final VirtualFile file) {
@@ -341,7 +341,7 @@ public abstract class AbstractFileIndex<IndexEntry extends FileIndexEntry> imple
}
public void processFile(FileContent fileContent) {
updateIndexEntry(fileContent.getVirtualFile());
updateIndexEntry(fileContent);
}
public void updatingDone() {
@@ -60,7 +60,7 @@ public class FileIndexRefreshCacheUpdater extends VirtualFileAdapter implements
public void afterRefreshFinish(boolean asynchonous) {
if (!asynchonous) {
for (VirtualFile file : myChangedFiles) {
myFileIndex.updateIndexEntry(file);
myFileIndex.updateIndexEntry(new FileContent(file));
}
updatingDone();
}
@@ -75,7 +75,7 @@ public class FileIndexRefreshCacheUpdater extends VirtualFileAdapter implements
}
public void processFile(FileContent fileContent) {
myFileIndex.updateIndexEntry(fileContent.getVirtualFile());
myFileIndex.updateIndexEntry(fileContent);
}
public void updatingDone() {
@@ -129,7 +129,7 @@ public class FileIndexRefreshCacheUpdater extends VirtualFileAdapter implements
}
else {
if (create) {
myFileIndex.updateIndexEntry(file);
myFileIndex.updateIndexEntry(new FileContent(file));
}
else {
myFileIndex.removeIndexEntry(file);