package de.plushnikov.intellij.plugin.lombokconfig; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PathUtil; import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.DefaultFileTypeSpecificInputFilter; import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.FileBasedIndexExtension; import com.intellij.util.indexing.FileContent; import com.intellij.util.indexing.ID; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import de.plushnikov.intellij.plugin.language.LombokConfigFileType; import de.plushnikov.intellij.plugin.language.psi.LombokConfigCleaner; import de.plushnikov.intellij.plugin.language.psi.LombokConfigFile; import de.plushnikov.intellij.plugin.language.psi.LombokConfigProperty; import de.plushnikov.intellij.plugin.language.psi.LombokConfigPsiUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class LombokConfigIndex extends FileBasedIndexExtension<ConfigIndexKey, String> { @NonNls public static final ID<ConfigIndexKey, String> NAME = ID.create("LombokConfigIndex"); private static final int INDEX_FORMAT_VERSION = 5; @NotNull @Override public ID<ConfigIndexKey, String> getName() { return NAME; } @NotNull @Override public DataIndexer<ConfigIndexKey, String, FileContent> getIndexer() { return new DataIndexer<ConfigIndexKey, String, FileContent>() { @NotNull @Override public Map<ConfigIndexKey, String> map(@NotNull FileContent inputData) { Map<ConfigIndexKey, String> result = Collections.emptyMap(); final VirtualFile directoryFile = inputData.getFile().getParent(); if (null != directoryFile) { final String canonicalPath = PathUtil.toSystemIndependentName(directoryFile.getCanonicalPath()); if (null != canonicalPath) { final Map<String, String> configValues = extractValues((LombokConfigFile) inputData.getPsiFile()); result = new HashMap<ConfigIndexKey, String>(); for (Map.Entry<String, String> entry : configValues.entrySet()) { result.put(new ConfigIndexKey(canonicalPath, entry.getKey()), entry.getValue()); } } } return result; } private Map<String, String> extractValues(LombokConfigFile configFile) { Map<String, String> result = new HashMap<String, String>(); final LombokConfigCleaner[] configCleaners = LombokConfigUtil.getLombokConfigCleaners(configFile); for (LombokConfigCleaner configCleaner : configCleaners) { final String key = LombokConfigPsiUtil.getKey(configCleaner); final ConfigKey configKey = ConfigKey.fromConfigStringKey(key); if (null != configKey) { result.put(key, configKey.getConfigDefaultValue()); } } final LombokConfigProperty[] configProperties = LombokConfigUtil.getLombokConfigProperties(configFile); for (LombokConfigProperty configProperty : configProperties) { final String key = LombokConfigPsiUtil.getKey(configProperty); final String value = LombokConfigPsiUtil.getValue(configProperty); final String sign = LombokConfigPsiUtil.getSign(configProperty); if (null == sign) { result.put(key, value); } else { final String previousValue = StringUtil.defaultIfEmpty(result.get(key), ""); final String combinedValue = previousValue + sign + value + ";"; result.put(key, combinedValue); } } return result; } }; } @NotNull @Override public KeyDescriptor<ConfigIndexKey> getKeyDescriptor() { return new KeyDescriptor<ConfigIndexKey>() { @Override public int getHashCode(ConfigIndexKey configKey) { return configKey.hashCode(); } @Override public boolean isEqual(ConfigIndexKey val1, ConfigIndexKey val2) { return val1.equals(val2); } @Override public void save(@NotNull DataOutput out, ConfigIndexKey value) throws IOException { out.writeUTF(StringUtil.notNullize(value.getDirectoryName())); out.writeUTF(StringUtil.notNullize(value.getConfigKey())); } @Override public ConfigIndexKey read(@NotNull DataInput in) throws IOException { return new ConfigIndexKey(in.readUTF(), in.readUTF()); } }; } @NotNull @Override public DataExternalizer<String> getValueExternalizer() { return new EnumeratorStringDescriptor(); } @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { return new DefaultFileTypeSpecificInputFilter(LombokConfigFileType.INSTANCE); } @Override public boolean dependsOnFileContent() { return true; } @Override public int getVersion() { return INDEX_FORMAT_VERSION; } }