package fr.adrienbrault.idea.symfony2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiFile; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpFileType; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.doctrine.DoctrineUtil; import fr.adrienbrault.idea.symfony2plugin.doctrine.dict.DoctrineModel; import fr.adrienbrault.idea.symfony2plugin.doctrine.dict.DoctrineModelSerializable; import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.ObjectStreamDataExternalizer; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.YAMLFileType; import java.util.Collection; import java.util.Map; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class DoctrineMetadataFileStubIndex extends FileBasedIndexExtension<String, DoctrineModelSerializable> { public static final ID<String, DoctrineModelSerializable> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.doctrine_metadata"); private final KeyDescriptor<String> myKeyDescriptor = new EnumeratorStringDescriptor(); private static ObjectStreamDataExternalizer<DoctrineModelSerializable> EXTERNALIZER = new ObjectStreamDataExternalizer<>(); private static int MAX_FILE_BYTE_SIZE = 1048576; private static class MyStringStringFileContentDataIndexer implements DataIndexer<String, DoctrineModelSerializable, FileContent> { @NotNull @Override public Map<String, DoctrineModelSerializable> map(@NotNull FileContent fileContent) { Map<String, DoctrineModelSerializable> map = new THashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); if(!Symfony2ProjectComponent.isEnabledForIndex(psiFile.getProject()) || !isValidForIndex(fileContent, psiFile)) { return map; } Collection<Pair<String, String>> classRepositoryPair = DoctrineUtil.getClassRepositoryPair(psiFile); if(classRepositoryPair == null || classRepositoryPair.size() == 0) { return map; } for (Pair<String, String> pair : classRepositoryPair) { String first = pair.getFirst(); if(first == null || first.length() == 0) { continue; } map.put(first, new DoctrineModel(first).setRepositoryClass(pair.getSecond())); } return map; } } @NotNull @Override public ID<String, DoctrineModelSerializable> getName() { return KEY; } @NotNull @Override public DataIndexer<String, DoctrineModelSerializable, FileContent> getIndexer() { return new MyStringStringFileContentDataIndexer(); } @NotNull @Override public KeyDescriptor<String> getKeyDescriptor() { return this.myKeyDescriptor; } @NotNull @Override public DataExternalizer<DoctrineModelSerializable> getValueExternalizer() { return EXTERNALIZER; } @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { return virtualFile -> { FileType fileType = virtualFile.getFileType(); return fileType == XmlFileType.INSTANCE || fileType == PhpFileType.INSTANCE || fileType == YAMLFileType.YML ; }; } @Override public boolean dependsOnFileContent() { return true; } @Override public int getVersion() { return 2; } public static boolean isValidForIndex(FileContent inputData, PsiFile psiFile) { String fileName = psiFile.getName(); if(fileName.startsWith(".") || fileName.endsWith("Test")) { return false; } // @TODO: filter .orm.xml? String extension = inputData.getFile().getExtension(); if(extension == null || !(extension.equalsIgnoreCase("xml") || extension.equalsIgnoreCase("yml")|| extension.equalsIgnoreCase("yaml") || extension.equalsIgnoreCase("php"))) { return false; } if(inputData.getFile().getLength() > MAX_FILE_BYTE_SIZE) { return false; } return true; } }