// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.images.index;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.indexing.*;
+import com.intellij.util.gist.GistManager;
+import com.intellij.util.gist.VirtualFileGist;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import java.io.DataOutput;
import java.io.IOException;
-public final class ImageInfoIndex extends SingleEntryFileBasedIndexExtension<ImageInfo> {
- private static final long ourMaxImageSize = (long)(Registry.get("ide.index.image.max.size").asDouble() * 1024 * 1024);
- public static final ID<Integer, ImageInfo> INDEX_ID = ID.create("ImageFileInfoIndex");
+public class ImageInfoIndex {
+ @Nullable
+ public static ImageInfo getInfo(@NotNull VirtualFile file, @NotNull Project project) {
+ return ourGist.getFileData(project, file);
+ }
+
+ private static final long ourMaxImageSize = (long)(Registry.get("ide.index.image.max.size").asDouble() * 1024 * 1024);
- private final DataExternalizer<ImageInfo> myValueExternalizer = new DataExternalizer<ImageInfo>() {
+ private static final DataExternalizer<ImageInfo> ourValueExternalizer = new DataExternalizer<ImageInfo>() {
@Override
public void save(@NotNull final DataOutput out, final ImageInfo info) throws IOException {
DataInputOutputUtil.writeINT(out, info.width);
@Override
public ImageInfo read(@NotNull final DataInput in) throws IOException {
- return new ImageInfo(DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in));
+ return new ImageInfo(DataInputOutputUtil.readINT(in),
+ DataInputOutputUtil.readINT(in),
+ DataInputOutputUtil.readINT(in));
}
};
- private final SingleEntryIndexer<ImageInfo> myDataIndexer = new SingleEntryIndexer<ImageInfo>(false) {
- @Override
- protected ImageInfo computeValue(@NotNull FileContent inputData) {
- ImageInfoReader.Info info = ImageInfoReader.getInfo(inputData.getContent());
- return info != null ? new ImageInfo(info.width, info.height, info.bpp) : null;
- }
- };
-
- @Override
- @NotNull
- public ID<Integer, ImageInfo> getName() {
- return INDEX_ID;
- }
-
- @Override
- @NotNull
- public SingleEntryIndexer<ImageInfo> getIndexer() {
- return myDataIndexer;
- }
-
- @Nullable
- public static ImageInfo getInfo(@NotNull VirtualFile file, @NotNull Project project) {
- return ContainerUtil.getFirstItem(FileBasedIndex.getInstance().getFileData(INDEX_ID, file, project).values());
- }
-
- @NotNull
- @Override
- public DataExternalizer<ImageInfo> getValueExternalizer() {
- return myValueExternalizer;
- }
+ private static final VirtualFileGist<ImageInfo> ourGist =
+ GistManager.getInstance().newVirtualFileGist("ImageInfo", 1, ourValueExternalizer, (project, file) -> {
+ if (!file.isInLocalFileSystem() || file.getLength() > ourMaxImageSize) {
+ return null;
+ }
- @NotNull
- @Override
- public FileBasedIndex.InputFilter getInputFilter() {
- return new DefaultFileTypeSpecificInputFilter(ImageFileTypeManager.getInstance().getImageFileType(), SvgFileType.INSTANCE) {
- @Override
- public boolean acceptInput(@NotNull VirtualFile file) {
- return file.isInLocalFileSystem() && file.getLength() < ourMaxImageSize;
+ FileType fileType = file.getFileType();
+ if (fileType != SvgFileType.INSTANCE && fileType != ImageFileTypeManager.getInstance().getImageFileType()) {
+ return null;
}
- };
- }
- @Override
- public int getVersion() {
- return 8;
- }
+ byte[] content;
+ try {
+ content = file.contentsToByteArray();
+ }
+ catch (IOException e) {
+ Logger.getInstance(ImageInfoIndex.class).error(e);
+ return null;
+ }
+ ImageInfoReader.Info info = ImageInfoReader.getInfo(content);
+ return info == null ? null : new ImageInfo(info.width, info.height, info.bpp);
+ });
}
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
-import com.intellij.util.indexing.FileBasedIndex;
import org.intellij.images.util.ImageInfo;
import org.jetbrains.annotations.NotNull;
public class ImageInfoIndexTest extends BasePlatformTestCase {
public void testIndexModification() throws IOException {
VirtualFile file = myFixture.addFileToProject("image.svg", "<svg width='300' height='300' xmlns='http://www.w3.org/2000/svg'></svg>").getVirtualFile();
- long stamp = getIndexStamp();
ImageInfo value = getIndexValue(file);
VfsUtil.saveText(file, "<svg width='500' height='300' xmlns='http://www.w3.org/2000/svg'></svg>");
- assertNotEquals(stamp, getIndexStamp());
assertNotEquals(value, getIndexValue(file));
- stamp = getIndexStamp();
value = getIndexValue(file);
VfsUtil.saveText(file, "<svg width='500' height='300' xmlns='http://www.w3.org/2000/svg'><path d=\"M10 10\"/></svg>");
- assertEquals(stamp, getIndexStamp());
assertEquals(value, getIndexValue(file));
}
assertEquals(300, getIndexValue(file2).width);
}
- private long getIndexStamp() {
- return FileBasedIndex.getInstance().getIndexModificationStamp(ImageInfoIndex.INDEX_ID, myFixture.getProject());
- }
-
private ImageInfo getIndexValue(@NotNull VirtualFile file) {
return ImageInfoIndex.getInfo(file, myFixture.getProject());
}