refactored symbol cache to enable reuse for various types of cache items and separated symbol cache from beans index cache
This commit is contained in:
@@ -170,37 +170,44 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex {
|
||||
public void addSymbols(IJavaProject project, EnhancedSymbolInformation[] enhancedSymbols,
|
||||
Bean[] beanDefinitions) {
|
||||
|
||||
// organize symbols by doc URI
|
||||
Map<String, List<EnhancedSymbolInformation>> symbolsPerDoc = new HashMap<>();
|
||||
for (EnhancedSymbolInformation symbol : enhancedSymbols) {
|
||||
Either<Location, WorkspaceSymbolLocation> location = symbol.getSymbol().getLocation();
|
||||
String docURI = location.isLeft() ? location.getLeft().getUri() : location.getRight().getUri();
|
||||
|
||||
symbolsPerDoc.computeIfAbsent(docURI, k -> new ArrayList<>()).add(symbol);
|
||||
}
|
||||
if (enhancedSymbols != null) {
|
||||
|
||||
// add symbols per doc
|
||||
for (Map.Entry<String, List<EnhancedSymbolInformation>> entry : symbolsPerDoc.entrySet()) {
|
||||
String docURI = entry.getKey();
|
||||
List<EnhancedSymbolInformation> symbols = entry.getValue();
|
||||
|
||||
SpringSymbolIndex.this.addSymbolsByDoc(project, docURI, (EnhancedSymbolInformation[]) symbols.toArray(new EnhancedSymbolInformation[symbols.size()]));
|
||||
// organize symbols by doc URI
|
||||
Map<String, List<EnhancedSymbolInformation>> symbolsPerDoc = new HashMap<>();
|
||||
for (EnhancedSymbolInformation symbol : enhancedSymbols) {
|
||||
Either<Location, WorkspaceSymbolLocation> location = symbol.getSymbol().getLocation();
|
||||
String docURI = location.isLeft() ? location.getLeft().getUri() : location.getRight().getUri();
|
||||
|
||||
symbolsPerDoc.computeIfAbsent(docURI, k -> new ArrayList<>()).add(symbol);
|
||||
}
|
||||
|
||||
// add symbols per doc
|
||||
for (Map.Entry<String, List<EnhancedSymbolInformation>> entry : symbolsPerDoc.entrySet()) {
|
||||
String docURI = entry.getKey();
|
||||
List<EnhancedSymbolInformation> symbols = entry.getValue();
|
||||
|
||||
SpringSymbolIndex.this.addSymbolsByDoc(project, docURI, (EnhancedSymbolInformation[]) symbols.toArray(new EnhancedSymbolInformation[symbols.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
// organize beans per doc URI
|
||||
Map<String, List<Bean>> beansPerDoc = new HashMap<>();
|
||||
for (Bean bean : beanDefinitions) {
|
||||
String docURI = bean.getLocation().getUri();
|
||||
beansPerDoc.computeIfAbsent(docURI, k -> new ArrayList<>()).add(bean);
|
||||
if (beanDefinitions != null) {
|
||||
|
||||
// organize beans per doc URI
|
||||
Map<String, List<Bean>> beansPerDoc = new HashMap<>();
|
||||
for (Bean bean : beanDefinitions) {
|
||||
String docURI = bean.getLocation().getUri();
|
||||
beansPerDoc.computeIfAbsent(docURI, k -> new ArrayList<>()).add(bean);
|
||||
}
|
||||
|
||||
// add beans per doc URI
|
||||
for (Map.Entry<String, List<Bean>> entry : beansPerDoc.entrySet()) {
|
||||
String docURI = entry.getKey();
|
||||
List<Bean> beans = entry.getValue();
|
||||
|
||||
springIndex.updateBeans(project.getElementName(), docURI, (Bean[]) beans.toArray(new Bean[beans.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
// add beans per doc URI
|
||||
for (Map.Entry<String, List<Bean>> entry : beansPerDoc.entrySet()) {
|
||||
String docURI = entry.getKey();
|
||||
List<Bean> beans = entry.getValue();
|
||||
|
||||
springIndex.updateBeans(project.getElementName(), docURI, (Bean[]) beans.toArray(new Bean[beans.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.index.cache;
|
||||
|
||||
public abstract class AbstractIndexCacheable implements IndexCacheable {
|
||||
|
||||
private final String docURI;
|
||||
|
||||
public AbstractIndexCacheable(String docURI) {
|
||||
this.docURI = docURI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocURI() {
|
||||
return this.docURI;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
@@ -23,17 +22,17 @@ import com.google.common.collect.Multimap;
|
||||
*/
|
||||
public interface IndexCache {
|
||||
|
||||
void store(IndexCacheKey cacheKey, String[] files, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files);
|
||||
<T extends IndexCacheable> void store(IndexCacheKey cacheKey, String[] files, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type);
|
||||
<T extends IndexCacheable> Pair<T[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files, Class<T> type);
|
||||
|
||||
void update(IndexCacheKey cacheKey, String file, long lastModified, List<CachedSymbol> generatedSymbols, Set<String> dependencies);
|
||||
void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies);
|
||||
<T extends IndexCacheable> void update(IndexCacheKey cacheKey, String file, long lastModified, List<T> generatedSymbols, Set<String> dependencies, Class<T> type);
|
||||
<T extends IndexCacheable> void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type);
|
||||
|
||||
void remove(IndexCacheKey cacheKey);
|
||||
void removeFile(IndexCacheKey symbolCacheKey, String file);
|
||||
<T extends IndexCacheable> void removeFile(IndexCacheKey symbolCacheKey, String file, Class<T> type);
|
||||
|
||||
default CachedSymbol[] retrieveSymbols(IndexCacheKey cacheKey, String[] files) {
|
||||
Pair<CachedSymbol[], Multimap<String, String>> r = retrieve(cacheKey, files);
|
||||
default <T extends IndexCacheable> T[] retrieveSymbols(IndexCacheKey cacheKey, String[] files, Class<T> type) {
|
||||
Pair<T[], Multimap<String, String>> r = retrieve(cacheKey, files, type);
|
||||
return r!=null ? r.getLeft() : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 2021 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -14,6 +14,7 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
@@ -34,7 +35,6 @@ import org.eclipse.lsp4j.Location;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
@@ -53,6 +53,7 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
/**
|
||||
@@ -61,7 +62,7 @@ import com.google.gson.stream.JsonReader;
|
||||
public class IndexCacheOnDisc implements IndexCache {
|
||||
|
||||
private final File cacheDirectory;
|
||||
private final Map<IndexCacheKey, CacheStore> stores;
|
||||
private final Map<IndexCacheKey, IndexCacheStore<? extends IndexCacheable>> stores;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(IndexCacheOnDisc.class);
|
||||
|
||||
@@ -79,10 +80,11 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(IndexCacheKey cacheKey, String[] files, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies) {
|
||||
if (dependencies==null) {
|
||||
public <T extends IndexCacheable> void store(IndexCacheKey cacheKey, String[] files, List<T> elements, Multimap<String, String> dependencies, Class<T> type) {
|
||||
if (dependencies == null) {
|
||||
dependencies = ImmutableMultimap.of();
|
||||
}
|
||||
|
||||
SortedMap<String, Long> timestampedFiles = new TreeMap<>();
|
||||
|
||||
timestampedFiles = Arrays.stream(files)
|
||||
@@ -95,18 +97,19 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
}
|
||||
}, (v1,v2) -> { throw new RuntimeException(String.format("Duplicate key for values %s and %s", v1, v2));}, TreeMap::new));
|
||||
|
||||
save(cacheKey, generatedSymbols, timestampedFiles, dependencies.asMap());
|
||||
save(cacheKey, elements, timestampedFiles, dependencies.asMap(), type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Pair<CachedSymbol[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files) {
|
||||
public <T extends IndexCacheable> Pair<T[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files, Class<T> type) {
|
||||
File cacheStore = new File(cacheDirectory, cacheKey.toString() + ".json");
|
||||
if (cacheStore.exists()) {
|
||||
|
||||
Gson gson = createGson();
|
||||
|
||||
try (JsonReader reader = new JsonReader(new FileReader(cacheStore))) {
|
||||
CacheStore store = gson.fromJson(reader, CacheStore.class);
|
||||
IndexCacheStore<T> store = gson.fromJson(reader, IndexCacheStore.class);
|
||||
|
||||
SortedMap<String, Long> timestampedFiles = Arrays.stream(files)
|
||||
.filter(file -> new File(file).exists())
|
||||
@@ -121,16 +124,19 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
if (isFileMatch(timestampedFiles, store.getTimestampedFiles())) {
|
||||
this.stores.put(cacheKey, store);
|
||||
|
||||
List<CachedSymbol> symbols = store.getSymbols();
|
||||
List<T> symbols = store.getSymbols();
|
||||
|
||||
Map<String, Collection<String>> storedDependencies = store.getDependencies();
|
||||
Multimap<String, String> dependencies = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
|
||||
if (storedDependencies!=null && !storedDependencies.isEmpty()) {
|
||||
for (Entry<String, Collection<String>> entry : storedDependencies.entrySet()) {
|
||||
dependencies.replaceValues(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return Pair.of(
|
||||
(CachedSymbol[]) symbols.toArray(new CachedSymbol[symbols.size()]),
|
||||
(T[]) symbols.toArray((T[]) Array.newInstance(type, symbols.size())),
|
||||
MultimapBuilder.hashKeys().hashSetValues().build(dependencies)
|
||||
);
|
||||
}
|
||||
@@ -143,20 +149,22 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFile(IndexCacheKey cacheKey, String file) {
|
||||
CacheStore cacheStore = this.stores.get(cacheKey);
|
||||
public <T extends IndexCacheable> void removeFile(IndexCacheKey cacheKey, String file, Class<T> type) {
|
||||
@SuppressWarnings("unchecked")
|
||||
IndexCacheStore<T> cacheStore = (IndexCacheStore<T>) this.stores.get(cacheKey);
|
||||
|
||||
if (cacheStore != null) {
|
||||
String docURI = UriUtil.toUri(new File(file)).toASCIIString();
|
||||
|
||||
SortedMap<String, Long> timestampedFiles = new TreeMap<>(cacheStore.getTimestampedFiles());
|
||||
timestampedFiles.remove(file);
|
||||
|
||||
List<CachedSymbol> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
List<T> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
.filter(cachedSymbol -> !cachedSymbol.getDocURI().equals(docURI))
|
||||
.collect(Collectors.toList());
|
||||
Map<String, Collection<String>> changedDeps = new HashMap<>(cacheStore.getDependencies());
|
||||
changedDeps.remove(file);
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDeps);
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDeps, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,12 +178,14 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String file, long lastModified, List<CachedSymbol> generatedSymbols, Set<String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String file, long lastModified,
|
||||
List<T> generatedSymbols, Set<String> dependencies, Class<T> type) {
|
||||
if (dependencies == null) {
|
||||
dependencies = ImmutableSet.of();
|
||||
}
|
||||
|
||||
CacheStore cacheStore = this.stores.get(cacheKey);
|
||||
@SuppressWarnings("unchecked")
|
||||
IndexCacheStore<T> cacheStore = (IndexCacheStore<T>) this.stores.get(cacheKey);
|
||||
|
||||
if (cacheStore != null) {
|
||||
String docURI = UriUtil.toUri(new File(file)).toASCIIString();
|
||||
@@ -183,7 +193,7 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
SortedMap<String, Long> timestampedFiles = new TreeMap<>(cacheStore.getTimestampedFiles());
|
||||
timestampedFiles.put(file, lastModified);
|
||||
|
||||
List<CachedSymbol> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
List<T> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
.filter(cachedSymbol -> !cachedSymbol.getDocURI().equals(docURI))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -195,17 +205,20 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
} else {
|
||||
changedDependencies.put(file, ImmutableSet.copyOf(dependencies));
|
||||
}
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDependencies);
|
||||
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDependencies, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String[] files, long[] lastModified,
|
||||
List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type) {
|
||||
if (dependencies == null) {
|
||||
dependencies = ImmutableMultimap.of();
|
||||
}
|
||||
|
||||
CacheStore cacheStore = this.stores.get(cacheKey);
|
||||
@SuppressWarnings("unchecked")
|
||||
IndexCacheStore<T> cacheStore = (IndexCacheStore<T>) this.stores.get(cacheKey);
|
||||
|
||||
if (cacheStore != null) {
|
||||
SortedMap<String, Long> timestampedFiles = new TreeMap<>(cacheStore.getTimestampedFiles());
|
||||
@@ -231,19 +244,19 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
}
|
||||
|
||||
// update cache internal list of cached symbols (by removing old ones and adding all new ones)
|
||||
List<CachedSymbol> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
List<T> cachedSymbols = cacheStore.getSymbols().stream()
|
||||
.filter(cachedSymbol -> !allDocURIs.contains(cachedSymbol.getDocURI()))
|
||||
.collect(Collectors.toList());
|
||||
cachedSymbols.addAll(generatedSymbols);
|
||||
|
||||
// store the complete cache content of this project to disc
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDependencies);
|
||||
save(cacheKey, cachedSymbols, timestampedFiles, changedDependencies, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getModificationTimestamp(IndexCacheKey cacheKey, String file) {
|
||||
CacheStore cacheStore = this.stores.get(cacheKey);
|
||||
IndexCacheStore<? extends IndexCacheable> cacheStore = this.stores.get(cacheKey);
|
||||
|
||||
if (cacheStore != null) {
|
||||
Long result = cacheStore.getTimestampedFiles().get(file);
|
||||
@@ -255,9 +268,9 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void save(IndexCacheKey cacheKey, List<CachedSymbol> generatedSymbols,
|
||||
SortedMap<String, Long> timestampedFiles, Map<String, Collection<String>> dependencies) {
|
||||
CacheStore store = new CacheStore(timestampedFiles, generatedSymbols, dependencies);
|
||||
private <T extends IndexCacheable> void save(IndexCacheKey cacheKey, List<T> elements, SortedMap<String, Long> timestampedFiles,
|
||||
Map<String, Collection<String>> dependencies, Class<T> type) {
|
||||
IndexCacheStore<T> store = new IndexCacheStore<T>(timestampedFiles, elements, dependencies, type);
|
||||
this.stores.put(cacheKey, store);
|
||||
|
||||
try (FileWriter writer = new FileWriter(new File(cacheDirectory, cacheKey.toString() + ".json")))
|
||||
@@ -301,6 +314,7 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
return new GsonBuilder()
|
||||
.registerTypeAdapter(SymbolAddOnInformation.class, new SymbolAddOnInformationAdapter())
|
||||
.registerTypeAdapter(Bean.class, new BeanJsonAdapter())
|
||||
.registerTypeAdapter(IndexCacheStore.class, new IndexCacheStoreAdapter())
|
||||
.create();
|
||||
}
|
||||
|
||||
@@ -308,31 +322,68 @@ public class IndexCacheOnDisc implements IndexCache {
|
||||
/**
|
||||
* internal storage structure
|
||||
*/
|
||||
private static class CacheStore {
|
||||
private static class IndexCacheStore<T extends IndexCacheable> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String elementType;
|
||||
|
||||
private final SortedMap<String, Long> timestampedFiles;
|
||||
private final List<CachedSymbol> symbols;
|
||||
private final List<T> elements;
|
||||
private final Map<String, Collection<String>> dependencies;
|
||||
|
||||
public CacheStore(SortedMap<String, Long> timestampedFiles, List<CachedSymbol> symbols, Map<String, Collection<String>> dependencies) {
|
||||
super();
|
||||
public IndexCacheStore(SortedMap<String, Long> timestampedFiles, List<T> elements, Map<String, Collection<String>> dependencies, Class<T> elementType) {
|
||||
this.timestampedFiles = timestampedFiles;
|
||||
this.symbols = symbols;
|
||||
this.elements = elements;
|
||||
this.dependencies = dependencies;
|
||||
this.elementType = elementType.getName();
|
||||
}
|
||||
|
||||
public Map<String, Collection<String>> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public List<CachedSymbol> getSymbols() {
|
||||
return symbols;
|
||||
public List<T> getSymbols() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public SortedMap<String, Long> getTimestampedFiles() {
|
||||
return timestampedFiles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class IndexCacheStoreAdapter implements JsonDeserializer<IndexCacheStore<?>> {
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public IndexCacheStore<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
JsonObject parsedObject = json.getAsJsonObject();
|
||||
|
||||
String className = parsedObject.get("elementType").getAsString();
|
||||
|
||||
try {
|
||||
Class<?> elementType = Class.forName(className);
|
||||
|
||||
JsonElement elementsObject = parsedObject.get("elements");
|
||||
Type elementListType = TypeToken.getParameterized(List.class, elementType).getType();
|
||||
List elements = context.deserialize(elementsObject, elementListType);
|
||||
|
||||
JsonElement timestampedFilesObject = parsedObject.get("timestampedFiles");
|
||||
Type timestampsMapType = TypeToken.getParameterized(SortedMap.class, String.class, Long.class).getType();
|
||||
SortedMap timestampedFiles = context.deserialize(timestampedFilesObject, timestampsMapType);
|
||||
|
||||
JsonElement dependenciesObject = parsedObject.get("dependencies");
|
||||
Map dependencies = context.deserialize(dependenciesObject, HashMap.class);
|
||||
|
||||
return new IndexCacheStore(timestampedFiles, elements, dependencies, elementType);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new JsonParseException("cannot parse data from index cache with element type: " + className, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -14,7 +14,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
@@ -24,20 +23,20 @@ import com.google.common.collect.Multimap;
|
||||
public class IndexCacheVoid implements IndexCache {
|
||||
|
||||
@Override
|
||||
public void store(IndexCacheKey cacheKey, String[] files, List<CachedSymbol> generatedSymbols, Multimap<String,String> dependencies) {
|
||||
public <T extends IndexCacheable> void store(IndexCacheKey cacheKey, String[] files, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<CachedSymbol[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files) {
|
||||
public <T extends IndexCacheable> Pair<T[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files, Class<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String file, long lastModified, List<CachedSymbol> generatedSymbols, Set<String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String file, long lastModified, List<T> generatedSymbols, Set<String> dependencies, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String[] file, long[] lastModified, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,7 +44,7 @@ public class IndexCacheVoid implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFile(IndexCacheKey symbolCacheKey, String file) {
|
||||
public <T extends IndexCacheable> void removeFile(IndexCacheKey symbolCacheKey, String file, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.index.cache;
|
||||
|
||||
public interface IndexCacheable {
|
||||
|
||||
String getDocURI();
|
||||
}
|
||||
@@ -101,7 +101,8 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), annotations);
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
@@ -121,7 +122,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
Either.forLeft(new Location(doc.getUri(), doc.toRange(functionBean.getT3()))));
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(),
|
||||
new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(functionBean.getT1(), functionBean.getT2().getQualifiedName())}), null));
|
||||
new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(functionBean.getT1(), functionBean.getT2().getQualifiedName())})));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.beans;
|
||||
|
||||
import org.springframework.ide.vscode.boot.index.cache.AbstractIndexCacheable;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
|
||||
public class CachedBean extends AbstractIndexCacheable {
|
||||
|
||||
private final Bean bean;
|
||||
|
||||
public CachedBean(String docURI, Bean bean) {
|
||||
super(docURI);
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public Bean getBean() {
|
||||
return this.bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2022 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -28,7 +28,6 @@ import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
@@ -56,7 +55,8 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
EnhancedSymbolInformation enhancedSymbol = result.getFirst();
|
||||
Bean beanDefinition = result.getSecond();
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -23,6 +23,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
@@ -74,7 +75,8 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider {
|
||||
String concreteRepoType = concreteBeanTypeBindung.getQualifiedName();
|
||||
Bean beanDefinition = new Bean(beanName, concreteRepoType, location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), new String[0]);
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("error creating data repository symbol for a specific range", e);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers;
|
||||
|
||||
import org.springframework.ide.vscode.boot.index.cache.AbstractIndexCacheable;
|
||||
|
||||
public class CachedDiagnostics extends AbstractIndexCacheable {
|
||||
|
||||
public CachedDiagnostics(String docURI) {
|
||||
super(docURI);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
return resultPath.startsWith("/") ? resultPath : "/" + resultPath;
|
||||
}))
|
||||
.map(p -> RouteUtils.createRouteSymbol(location, p, methods, contentTypes, acceptTypes, null))
|
||||
.forEach((enhancedSymbol) -> context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null)));
|
||||
.forEach((enhancedSymbol) -> context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
EnhancedSymbolInformation enhancedSymbol = RouteUtils.createRouteSymbol(location, path, getElementStrings(httpMethods),
|
||||
getElementStrings(contentTypes), getElementStrings(acceptTypes), addon);
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -10,43 +10,31 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.utils;
|
||||
|
||||
import org.springframework.ide.vscode.boot.index.cache.AbstractIndexCacheable;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
|
||||
public class CachedSymbol {
|
||||
public class CachedSymbol extends AbstractIndexCacheable {
|
||||
|
||||
private final String docURI;
|
||||
private final long lastModified;
|
||||
private final EnhancedSymbolInformation enhancedSymbol;
|
||||
private final Bean bean;
|
||||
|
||||
public CachedSymbol(String docURI, long lastModified, EnhancedSymbolInformation enhancedSymbol, Bean bean) {
|
||||
this.docURI = docURI;
|
||||
public CachedSymbol(String docURI, long lastModified, EnhancedSymbolInformation enhancedSymbol) {
|
||||
super(docURI);
|
||||
this.lastModified = lastModified;
|
||||
this.enhancedSymbol = enhancedSymbol;
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public EnhancedSymbolInformation getEnhancedSymbol() {
|
||||
return enhancedSymbol;
|
||||
}
|
||||
|
||||
public Bean getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public String getDocURI() {
|
||||
return docURI;
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CachedSymbol [docURI=" + docURI + ", enhancedSymbol=" + enhancedSymbol + "]";
|
||||
return "CachedSymbol [docURI=" + getDocURI() + ", enhancedSymbol=" + enhancedSymbol + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class RestrictedDefaultSymbolProvider extends AbstractSymbolProvider {
|
||||
if (!isCombinedWithAnnotation(node, Annotations.BEAN)) {
|
||||
try {
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(DefaultSymbolProvider.provideDefaultSymbol(node, doc), null);
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
} catch (Exception e) {
|
||||
log.warn(e.getMessage());
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
|
||||
CachedSymbol[] symbols = this.cache.retrieveSymbols(cacheKey, filesStr);
|
||||
CachedSymbol[] symbols = this.cache.retrieveSymbols(cacheKey, filesStr, CachedSymbol.class);
|
||||
if (symbols == null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
|
||||
@@ -178,7 +178,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
generatedSymbols.addAll(scanFile(file));
|
||||
}
|
||||
|
||||
this.cache.store(cacheKey, filesStr, generatedSymbols, null);
|
||||
this.cache.store(cacheKey, filesStr, generatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
symbols = (CachedSymbol[]) generatedSymbols.toArray(new CachedSymbol[generatedSymbols.size()]);
|
||||
}
|
||||
@@ -188,8 +188,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
|
||||
if (symbols != null) {
|
||||
EnhancedSymbolInformation[] enhancedSymbols = Arrays.stream(symbols).map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = Arrays.stream(symbols).filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, beans);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, null);
|
||||
}
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
@@ -205,7 +204,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
long lastModified = Files.getLastModifiedTime(file).toMillis();
|
||||
String docUri = file.toUri().toASCIIString();
|
||||
for (EnhancedSymbolInformation s : computeSymbols(docUri, content)) {
|
||||
builder.add(new CachedSymbol(docUri, lastModified, s, null));
|
||||
builder.add(new CachedSymbol(docUri, lastModified, s));
|
||||
}
|
||||
return builder.build();
|
||||
} catch (IOException e) {
|
||||
@@ -256,11 +255,10 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
String file = new File(new URI(docURI)).getAbsolutePath();
|
||||
this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null);
|
||||
this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedSymbols.stream().filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans);
|
||||
symbolHandler.addSymbols(project, docURI, symbols, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +273,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
updateFile(project, d, Files.readString(path));
|
||||
} else {
|
||||
String file = new File(new URI(d.getDocURI())).getAbsolutePath();
|
||||
cache.removeFile(key, file);
|
||||
cache.removeFile(key, file, CachedSymbol.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,7 +284,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
IndexCacheKey key = getCacheKey(project);
|
||||
for (String docUri : docURIs) {
|
||||
String file = new File(new URI(docUri)).getAbsolutePath();
|
||||
cache.removeFile(key, file);
|
||||
cache.removeFile(key, file, CachedSymbol.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2022 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -52,6 +52,7 @@ import org.springframework.ide.vscode.boot.index.cache.IndexCache;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheKey;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
@@ -80,6 +81,9 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
// we need to change the generation - this will result in a re-indexing due to no up-to-date cache data being found
|
||||
private static final String GENERATION = "GEN-3";
|
||||
|
||||
private static final String SYMBOL_KEY = "symbols";
|
||||
private static final String BEANS_KEY = "beans";
|
||||
|
||||
private final SymbolHandler symbolHandler;
|
||||
private final AnnotationHierarchyAwareLookup<SymbolProvider> symbolProviders;
|
||||
private final IndexCache cache;
|
||||
@@ -126,17 +130,24 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
@Override
|
||||
public void removeProject(IJavaProject project) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
this.cache.remove(cacheKey);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
this.cache.remove(symbolsCacheKey);
|
||||
this.cache.remove(beansCacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFile(IJavaProject project, DocumentDescriptor updatedDoc, String content) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
if (updatedDoc != null && shouldProcessDocument(project, updatedDoc.getDocURI())
|
||||
&& isCacheOutdated(cacheKey, updatedDoc.getDocURI(), updatedDoc.getLastModified())) {
|
||||
this.symbolHandler.removeSymbols(project, updatedDoc.getDocURI());
|
||||
scanFile(project, updatedDoc, content);
|
||||
IndexCacheKey symbolCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
if (updatedDoc != null && shouldProcessDocument(project, updatedDoc.getDocURI())) {
|
||||
if (isCacheOutdated(symbolCacheKey, updatedDoc.getDocURI(), updatedDoc.getLastModified())
|
||||
|| isCacheOutdated(beansCacheKey, updatedDoc.getDocURI(), updatedDoc.getLastModified())) {
|
||||
this.symbolHandler.removeSymbols(project, updatedDoc.getDocURI());
|
||||
scanFile(project, updatedDoc, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,18 +166,23 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
@Override
|
||||
public void removeFiles(IJavaProject project, String[] docURIs) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
for (String docURI : docURIs) {
|
||||
String file = new File(new URI(docURI)).getAbsolutePath();
|
||||
this.cache.removeFile(cacheKey, file);
|
||||
this.cache.removeFile(symbolsCacheKey, file, CachedSymbol.class);
|
||||
this.cache.removeFile(beansCacheKey, file, CachedSymbol.class);
|
||||
}
|
||||
}
|
||||
|
||||
private DocumentDescriptor[] filterDocuments(IJavaProject project, DocumentDescriptor[] updatedDocs) {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
return Arrays.stream(updatedDocs).filter(doc -> shouldProcessDocument(project, doc.getDocURI()))
|
||||
.filter(doc -> isCacheOutdated(cacheKey, doc.getDocURI(), doc.getLastModified())).toArray(DocumentDescriptor[]::new);
|
||||
.filter(doc -> isCacheOutdated(symbolsCacheKey, doc.getDocURI(), doc.getLastModified())
|
||||
|| isCacheOutdated(beansCacheKey, doc.getDocURI(), doc.getLastModified())).toArray(DocumentDescriptor[]::new);
|
||||
}
|
||||
|
||||
private boolean shouldProcessDocument(IJavaProject project, String docURI) {
|
||||
@@ -218,19 +234,25 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
if (cu != null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
String file = UriUtil.toFileString(docURI);
|
||||
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, file,
|
||||
lastModified, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
|
||||
lastModified, docRef, content, generatedSymbols, generatedBeans, SCAN_PASS.ONE, new ArrayList<>());
|
||||
|
||||
scanAST(context);
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
this.cache.update(cacheKey, file, lastModified, generatedSymbols, context.getDependencies());
|
||||
IndexCacheKey symbolCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
this.cache.update(symbolCacheKey, file, lastModified, generatedSymbols, context.getDependencies(), CachedSymbol.class);
|
||||
this.cache.update(beansCacheKey, file, lastModified, generatedBeans, context.getDependencies(), CachedBean.class);
|
||||
// dependencyTracker.dump();
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedSymbols.stream().filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans);
|
||||
|
||||
Set<String> scannedFiles = new HashSet<>();
|
||||
@@ -253,10 +275,12 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
if (cu != null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
String file = UriUtil.toFileString(docURI);
|
||||
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, file,
|
||||
0, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
|
||||
0, docRef, content, generatedSymbols, generatedBeans, SCAN_PASS.ONE, new ArrayList<>());
|
||||
|
||||
scanAST(context);
|
||||
|
||||
@@ -289,6 +313,8 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
}
|
||||
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
Multimap<String, String> dependencies = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
|
||||
FileASTRequestor requestor = new FileASTRequestor() {
|
||||
@@ -303,7 +329,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
|
||||
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, sourceFilePath,
|
||||
lastModified, docRef, null, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
|
||||
lastModified, docRef, null, generatedSymbols, generatedBeans, SCAN_PASS.ONE, new ArrayList<>());
|
||||
|
||||
scanAST(context);
|
||||
|
||||
@@ -317,11 +343,14 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
parser.createASTs(javaFiles, null, new String[0], requestor, null);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedSymbols.stream().filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, symbols, beans);
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
this.cache.update(cacheKey, javaFiles, lastModified, generatedSymbols, dependencies);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
this.cache.update(symbolsCacheKey, javaFiles, lastModified, generatedSymbols, dependencies, CachedSymbol.class);
|
||||
this.cache.update(beansCacheKey, javaFiles, lastModified, generatedBeans, dependencies, CachedBean.class);
|
||||
|
||||
return scannedTypes;
|
||||
}
|
||||
@@ -358,45 +387,55 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
}
|
||||
|
||||
private void scanFiles(IJavaProject project, String[] javaFiles) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> cached = this.cache.retrieve(cacheKey, javaFiles);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> cachedSymbols = this.cache.retrieve(symbolsCacheKey, javaFiles, CachedSymbol.class);
|
||||
Pair<CachedBean[], Multimap<String, String>> cachedBeans = this.cache.retrieve(beansCacheKey, javaFiles, CachedBean.class);
|
||||
|
||||
CachedSymbol[] symbols;
|
||||
if (cached == null) {
|
||||
CachedBean[] beans;
|
||||
|
||||
if (cachedSymbols == null || cachedBeans == null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
log.info("scan java files, AST parse, pass 1 for files: {}", javaFiles.length);
|
||||
|
||||
String[] pass2Files = scanFiles(project, javaFiles, generatedSymbols, SCAN_PASS.ONE);
|
||||
String[] pass2Files = scanFiles(project, javaFiles, generatedSymbols, generatedBeans, SCAN_PASS.ONE);
|
||||
if (pass2Files.length > 0) {
|
||||
|
||||
log.info("scan java files, AST parse, pass 2 for files: {}", javaFiles.length);
|
||||
|
||||
scanFiles(project, pass2Files, generatedSymbols, SCAN_PASS.TWO);
|
||||
scanFiles(project, pass2Files, generatedSymbols, generatedBeans, SCAN_PASS.TWO);
|
||||
}
|
||||
|
||||
log.info("scan java files done, number of symbols created: " + generatedSymbols.size());
|
||||
|
||||
this.cache.store(cacheKey, javaFiles, generatedSymbols, dependencyTracker.getAllDependencies());
|
||||
this.cache.store(symbolsCacheKey, javaFiles, generatedSymbols, dependencyTracker.getAllDependencies(), CachedSymbol.class);
|
||||
this.cache.store(beansCacheKey, javaFiles, generatedBeans, dependencyTracker.getAllDependencies(), CachedBean.class);
|
||||
// dependencyTracker.dump();
|
||||
|
||||
symbols = (CachedSymbol[]) generatedSymbols.toArray(new CachedSymbol[generatedSymbols.size()]);
|
||||
beans = (CachedBean[]) generatedBeans.toArray(new CachedBean[generatedBeans.size()]);
|
||||
}
|
||||
else {
|
||||
symbols = cached.getLeft();
|
||||
symbols = cachedSymbols.getLeft();
|
||||
beans = cachedBeans.getLeft();
|
||||
|
||||
log.info("scan java files used cached data: {} - no. of cached symbols retrieved: {}", project.getElementName(), symbols.length);
|
||||
this.dependencyTracker.restore(cached.getRight());
|
||||
log.info("scan java files restored cached dependency data: {} - no. of cached dependencies: {}", cached.getRight().size());
|
||||
this.dependencyTracker.restore(cachedSymbols.getRight());
|
||||
log.info("scan java files restored cached dependency data: {} - no. of cached dependencies: {}", cachedSymbols.getRight().size());
|
||||
}
|
||||
|
||||
if (symbols != null) {
|
||||
if (symbols != null && beans != null) {
|
||||
EnhancedSymbolInformation[] enhancedSymbols = Arrays.stream(symbols).map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = Arrays.stream(symbols).filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, beans);
|
||||
Bean[] allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, allBeans);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] scanFiles(IJavaProject project, String[] javaFiles, List<CachedSymbol> generatedSymbols, SCAN_PASS pass)
|
||||
private String[] scanFiles(IJavaProject project, String[] javaFiles, List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans, SCAN_PASS pass)
|
||||
throws Exception {
|
||||
ASTParser parser = createParser(project, SCAN_PASS.ONE.equals(pass));
|
||||
List<String> nextPassFiles = new ArrayList<>();
|
||||
@@ -410,7 +449,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
|
||||
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, sourceFilePath,
|
||||
lastModified, docRef, null, generatedSymbols, pass, nextPassFiles);
|
||||
lastModified, docRef, null, generatedSymbols, generatedBeans, pass, nextPassFiles);
|
||||
|
||||
scanAST(context);
|
||||
}
|
||||
@@ -523,7 +562,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
WorkspaceSymbol symbol = provideDefaultSymbol(node, context);
|
||||
if (symbol != null) {
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null);
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,7 +647,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
private IndexCacheKey getCacheKey(IJavaProject project) {
|
||||
private IndexCacheKey getCacheKey(IJavaProject project, String elementType) {
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<File> classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
|
||||
|
||||
@@ -617,7 +656,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
.map(file -> file.getAbsolutePath() + "#" + file.lastModified())
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
return new IndexCacheKey(project.getElementName() + "-java-", DigestUtils.md5Hex(GENERATION + "-" + classpathIdentifier).toUpperCase());
|
||||
return new IndexCacheKey(project.getElementName() + "-java-" + elementType + "-", DigestUtils.md5Hex(GENERATION + "-" + classpathIdentifier).toUpperCase());
|
||||
}
|
||||
|
||||
public void setScanTestJavaSources(boolean scanTestJavaSources) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -17,8 +17,10 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJava.SCAN_PASS;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
@@ -34,6 +36,7 @@ public class SpringIndexerJavaContext {
|
||||
private final AtomicReference<TextDocument> docRef;
|
||||
private final String content;
|
||||
private final List<CachedSymbol> generatedSymbols;
|
||||
private final List<CachedBean> beans;
|
||||
private final SCAN_PASS pass;
|
||||
private final List<String> nextPassFiles;
|
||||
|
||||
@@ -48,7 +51,8 @@ public class SpringIndexerJavaContext {
|
||||
long lastModified,
|
||||
AtomicReference<TextDocument> docRef,
|
||||
String content,
|
||||
List<CachedSymbol> generatedSymbols,
|
||||
List<CachedSymbol> generatedSymbols,
|
||||
List<CachedBean> beans,
|
||||
SCAN_PASS pass,
|
||||
List<String> nextPassFiles
|
||||
) {
|
||||
@@ -61,6 +65,7 @@ public class SpringIndexerJavaContext {
|
||||
this.docRef = docRef;
|
||||
this.content = content;
|
||||
this.generatedSymbols = generatedSymbols;
|
||||
this.beans = beans;
|
||||
this.pass = pass;
|
||||
this.nextPassFiles = nextPassFiles;
|
||||
}
|
||||
@@ -96,6 +101,10 @@ public class SpringIndexerJavaContext {
|
||||
public List<CachedSymbol> getGeneratedSymbols() {
|
||||
return generatedSymbols;
|
||||
}
|
||||
|
||||
public List<CachedBean> getBeans() {
|
||||
return beans;
|
||||
}
|
||||
|
||||
public SCAN_PASS getPass() {
|
||||
return pass;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2022 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -33,6 +33,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCache;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheKey;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
@@ -48,6 +49,9 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class SpringIndexerXML implements SpringIndexer {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SpringIndexerJava.class);
|
||||
|
||||
private static final String SYMBOL_KEY = "symbols";
|
||||
private static final String BEANS_KEY = "beans";
|
||||
|
||||
private final SymbolHandler symbolHandler;
|
||||
private final Map<String, SpringIndexerXMLNamespaceHandler> namespaceHandler;
|
||||
@@ -106,28 +110,34 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
|
||||
log.info("scan xml files for symbols for project: " + project.getElementName() + " - no. of files: " + files.length);
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
CachedSymbol[] symbols = this.cache.retrieveSymbols(cacheKey, files);
|
||||
if (symbols == null) {
|
||||
CachedSymbol[] symbols = this.cache.retrieveSymbols(symbolsCacheKey, files, CachedSymbol.class);
|
||||
CachedBean[] beans = this.cache.retrieveSymbols(beansCacheKey, files, CachedBean.class);
|
||||
|
||||
if (symbols == null || beans == null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
for (String file : files) {
|
||||
scanFile(project, file, generatedSymbols);
|
||||
scanFile(project, file, generatedSymbols, generatedBeans);
|
||||
}
|
||||
|
||||
this.cache.store(cacheKey, files, generatedSymbols, null);
|
||||
this.cache.store(symbolsCacheKey, files, generatedSymbols, null, CachedSymbol.class);
|
||||
this.cache.store(beansCacheKey, files, generatedBeans, null, CachedBean.class);
|
||||
|
||||
symbols = (CachedSymbol[]) generatedSymbols.toArray(new CachedSymbol[generatedSymbols.size()]);
|
||||
beans = (CachedBean[]) generatedBeans.toArray(new CachedBean[generatedBeans.size()]);
|
||||
}
|
||||
else {
|
||||
log.info("scan xml files used cached data: " + project.getElementName() + " - no. of cached symbols retrieved: " + symbols.length);
|
||||
}
|
||||
|
||||
if (symbols != null) {
|
||||
if (symbols != null && beans != null) {
|
||||
EnhancedSymbolInformation[] enhancedSymbols = Arrays.stream(symbols).map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = Arrays.stream(symbols).filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, beans);
|
||||
Bean[] allBeans = Arrays.stream(beans).filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, enhancedSymbols, allBeans);
|
||||
}
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
@@ -137,8 +147,11 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
|
||||
@Override
|
||||
public void removeProject(IJavaProject project) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
this.cache.remove(cacheKey);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
this.cache.remove(symbolsCacheKey);
|
||||
this.cache.remove(beansCacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,16 +160,21 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
this.symbolHandler.removeSymbols(project, updatedDoc.getDocURI());
|
||||
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
|
||||
String docURI = updatedDoc.getDocURI();
|
||||
|
||||
scanFile(project, content, docURI, updatedDoc.getLastModified(), generatedSymbols);
|
||||
scanFile(project, content, docURI, updatedDoc.getLastModified(), generatedSymbols, generatedBeans);
|
||||
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
String file = new File(new URI(docURI)).getAbsolutePath();
|
||||
this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null);
|
||||
this.cache.update(symbolsCacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null, CachedSymbol.class);
|
||||
this.cache.update(beansCacheKey, file, updatedDoc.getLastModified(), generatedBeans, null, CachedBean.class);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedSymbols.stream().filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans);
|
||||
}
|
||||
|
||||
@@ -172,29 +190,36 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
String content = new String(Files.readAllBytes(path));
|
||||
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
|
||||
scanFile(project, content, docURI, updatedDoc.getLastModified(), generatedSymbols);
|
||||
List<CachedBean> generatedBeans = new ArrayList<CachedBean>();
|
||||
scanFile(project, content, docURI, updatedDoc.getLastModified(), generatedSymbols, generatedBeans);
|
||||
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
IndexCacheKey symbolCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
String file = new File(new URI(docURI)).getAbsolutePath();
|
||||
this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null);
|
||||
this.cache.update(symbolCacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null, CachedSymbol.class);
|
||||
this.cache.update(beansCacheKey, file, updatedDoc.getLastModified(), generatedBeans, null, CachedBean.class);
|
||||
|
||||
EnhancedSymbolInformation[] symbols = generatedSymbols.stream().map(cachedSymbol -> cachedSymbol.getEnhancedSymbol()).toArray(EnhancedSymbolInformation[]::new);
|
||||
Bean[] beans = generatedSymbols.stream().filter(cachedSymbol -> cachedSymbol.getBean() != null).map(cachedSymbol -> cachedSymbol.getBean()).toArray(Bean[]::new);
|
||||
Bean[] beans = generatedBeans.stream().filter(cachedBean -> cachedBean.getBean() != null).map(cachedBean -> cachedBean.getBean()).toArray(Bean[]::new);
|
||||
symbolHandler.addSymbols(project, docURI, symbols, beans);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFiles(IJavaProject project, String[] docURIs) throws Exception {
|
||||
IndexCacheKey cacheKey = getCacheKey(project);
|
||||
IndexCacheKey symbolsCacheKey = getCacheKey(project, SYMBOL_KEY);
|
||||
IndexCacheKey beansCacheKey = getCacheKey(project, BEANS_KEY);
|
||||
|
||||
for (String docURI : docURIs) {
|
||||
String file = new File(new URI(docURI)).getAbsolutePath();
|
||||
this.cache.removeFile(cacheKey, file);
|
||||
|
||||
this.cache.removeFile(symbolsCacheKey, file, CachedSymbol.class);
|
||||
this.cache.removeFile(beansCacheKey, file, CachedBean.class);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanFile(IJavaProject project, String fileName, List<CachedSymbol> generatedSymbols) {
|
||||
private void scanFile(IJavaProject project, String fileName, List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans) {
|
||||
log.debug("starting to parse XML file for Spring symbol indexing: {}", fileName);
|
||||
|
||||
try {
|
||||
@@ -204,29 +229,32 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
String docURI = UriUtil.toUri(file).toASCIIString();
|
||||
String fileContent = FileUtils.readFileToString(file);
|
||||
|
||||
scanFile(project, fileContent, docURI, lastModified, generatedSymbols);
|
||||
scanFile(project, fileContent, docURI, lastModified, generatedSymbols, generatedBeans);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("error parsing XML file: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanFile(IJavaProject project, String fileContent, String docURI, long lastModified, List<CachedSymbol> generatedSymbols) throws Exception {
|
||||
private void scanFile(IJavaProject project, String fileContent, String docURI, long lastModified, List<CachedSymbol> generatedSymbols,
|
||||
List<CachedBean> generatedBeans) throws Exception {
|
||||
DOMParser parser = DOMParser.getInstance();
|
||||
DOMDocument document = parser.parse(fileContent, "", null);
|
||||
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
scanNode(document, project, docURI, lastModified, docRef, fileContent, generatedSymbols);
|
||||
scanNode(document, project, docURI, lastModified, docRef, fileContent, generatedSymbols, generatedBeans);
|
||||
}
|
||||
|
||||
private void scanNode(DOMNode node, IJavaProject project, String docURI, long lastModified, AtomicReference<TextDocument> docRef, String content, List<CachedSymbol> generatedSymbols) throws Exception {
|
||||
private void scanNode(DOMNode node, IJavaProject project, String docURI, long lastModified, AtomicReference<TextDocument> docRef, String content,
|
||||
List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans) throws Exception {
|
||||
|
||||
String namespaceURI = node.getNamespaceURI();
|
||||
|
||||
if (namespaceURI != null && this.namespaceHandler.containsKey(namespaceURI)) {
|
||||
SpringIndexerXMLNamespaceHandler namespaceHandler = this.namespaceHandler.get(namespaceURI);
|
||||
|
||||
TextDocument document = DocumentUtils.getTempTextDocument(docURI, docRef, content);
|
||||
namespaceHandler.processNode(node, project, docURI, lastModified, document, generatedSymbols);
|
||||
namespaceHandler.processNode(node, project, docURI, lastModified, document, generatedSymbols, generatedBeans);
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +268,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
|
||||
List<DOMNode> children = node.getChildren();
|
||||
for (DOMNode child : children) {
|
||||
scanNode(child, project, docURI, lastModified, docRef, content, generatedSymbols);
|
||||
scanNode(child, project, docURI, lastModified, docRef, content, generatedSymbols, generatedBeans);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +297,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
return xmlFiles;
|
||||
}
|
||||
|
||||
private IndexCacheKey getCacheKey(IJavaProject project) {
|
||||
private IndexCacheKey getCacheKey(IJavaProject project, String elementType) {
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<File> classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
|
||||
|
||||
@@ -278,7 +306,7 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
.map(file -> file.getAbsolutePath() + "#" + file.lastModified())
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
return new IndexCacheKey(project.getElementName() + "-xml-", DigestUtils.md5Hex(classpathIdentifier).toUpperCase());
|
||||
return new IndexCacheKey(project.getElementName() + "-xml-" + elementType + "-", DigestUtils.md5Hex(classpathIdentifier).toUpperCase());
|
||||
}
|
||||
|
||||
private void clearIndex() {
|
||||
@@ -318,7 +346,9 @@ public class SpringIndexerXML implements SpringIndexer {
|
||||
throws Exception {
|
||||
if (content != null) {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
scanFile(project, content, docURI, 0, generatedSymbols);
|
||||
List<CachedBean> generatedBeans = new ArrayList<>();
|
||||
|
||||
scanFile(project, content, docURI, 0, generatedSymbols, generatedBeans);
|
||||
return generatedSymbols.stream().map(s -> s.getEnhancedSymbol()).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java.utils;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lemminx.dom.DOMNode;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -21,6 +22,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public interface SpringIndexerXMLNamespaceHandler {
|
||||
|
||||
void processNode(DOMNode node, IJavaProject project, String docURI, long lastModifiued, TextDocument document, List<CachedSymbol> generatedSymbols) throws Exception;
|
||||
void processNode(DOMNode node, IJavaProject project, String docURI, long lastModifiued, TextDocument document,
|
||||
List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -22,6 +22,7 @@ import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.beans.CachedBean;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
@@ -34,14 +35,16 @@ import org.springframework.lang.NonNull;
|
||||
public class SpringIndexerXMLNamespaceHandlerBeans implements SpringIndexerXMLNamespaceHandler {
|
||||
|
||||
@Override
|
||||
public void processNode(DOMNode node, IJavaProject project, String docURI, long lastModified, TextDocument document, List<CachedSymbol> generatedSymbols) throws Exception {
|
||||
public void processNode(DOMNode node, IJavaProject project, String docURI, long lastModified, TextDocument document,
|
||||
List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans) throws Exception {
|
||||
String localName = node.getLocalName();
|
||||
if (localName != null && "bean".equals(localName)) {
|
||||
createBeanSymbol(node, project, docURI, lastModified, document, generatedSymbols);
|
||||
createBeanSymbol(node, project, docURI, lastModified, document, generatedSymbols, generatedBeans);
|
||||
}
|
||||
}
|
||||
|
||||
private void createBeanSymbol(DOMNode node, IJavaProject project, String docURI, long lastModified, TextDocument document, List<CachedSymbol> generatedSymbols) throws Exception {
|
||||
private void createBeanSymbol(DOMNode node, IJavaProject project, String docURI, long lastModified, TextDocument document,
|
||||
List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans) throws Exception {
|
||||
String beanID = null;
|
||||
int symbolStart = 0;
|
||||
int symbolEnd = 0;
|
||||
@@ -94,8 +97,10 @@ public class SpringIndexerXMLNamespaceHandlerBeans implements SpringIndexerXMLNa
|
||||
|
||||
EnhancedSymbolInformation fullSymbol = new EnhancedSymbolInformation(symbol, addon);
|
||||
|
||||
CachedSymbol cachedSymbol = new CachedSymbol(docURI, lastModified, fullSymbol, null);
|
||||
CachedSymbol cachedSymbol = new CachedSymbol(docURI, lastModified, fullSymbol);
|
||||
generatedSymbols.add(cachedSymbol);
|
||||
|
||||
// TODO: bean index
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ide.vscode.boot.index.cache.AbstractIndexCacheable;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheKey;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheOnDisc;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
@@ -67,7 +68,7 @@ public class IndexCacheOnDiscTest {
|
||||
|
||||
@Test
|
||||
void testEmptyCache() throws Exception {
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("something", "0"), new String[0]);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("something", "0"), new String[0], CachedSymbol.class);
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@@ -87,15 +88,15 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null);
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null));
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, ImmutableMultimap.of(
|
||||
file1.toString(), "file1dep1",
|
||||
file2.toString(), "file2dep1",
|
||||
file2.toString(), "file2dep2"
|
||||
));
|
||||
), CachedSymbol.class);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
|
||||
CachedSymbol[] cachedSymbols = result.getLeft();
|
||||
assertNotNull(cachedSymbols);
|
||||
@@ -113,8 +114,6 @@ public class IndexCacheOnDiscTest {
|
||||
|
||||
assertEquals(timeFile1.toMillis(), cache.getModificationTimestamp(new IndexCacheKey("somekey", "1"), file1.toString()));
|
||||
assertEquals(0, cache.getModificationTimestamp(new IndexCacheKey("somekey", "1"), "random-non-existing-file"));
|
||||
|
||||
assertNull(cachedSymbols[0].getBean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,11 +132,11 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null);
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null));
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("otherkey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("otherkey", "1"), files, CachedSymbol.class);
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@@ -157,16 +156,16 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null);
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null));
|
||||
generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, ImmutableMultimap.of(
|
||||
file1.toString(), "file1dep",
|
||||
file2.toString(), "file2dep"
|
||||
));
|
||||
), CachedSymbol.class);
|
||||
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 1000));
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@@ -181,10 +180,10 @@ public class IndexCacheOnDiscTest {
|
||||
Files.createFile(file3);
|
||||
|
||||
String[] files = {file1.toString(), file2.toString()};
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, new ArrayList<>(), null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, new ArrayList<>(), null, CachedSymbol.class);
|
||||
|
||||
String[] moreFiles = {file1.toString(), file2.toString(), file3.toString()};
|
||||
assertNull(cache.retrieve(new IndexCacheKey("somekey", "1"), moreFiles));
|
||||
assertNull(cache.retrieve(new IndexCacheKey("somekey", "1"), moreFiles, CachedSymbol.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,20 +197,20 @@ public class IndexCacheOnDiscTest {
|
||||
Files.createFile(file3);
|
||||
|
||||
String[] files = {file1.toString(), file2.toString(), file3.toString()};
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, new ArrayList<>(), null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, new ArrayList<>(), null, CachedSymbol.class);
|
||||
|
||||
String[] fewerFiles = {file1.toString(), file2.toString()};
|
||||
assertNull(cache.retrieve(new IndexCacheKey("somekey", "1"), fewerFiles));
|
||||
assertNull(cache.retrieve(new IndexCacheKey("somekey", "1"), fewerFiles, CachedSymbol.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteOldCacheFileIfNewOneIsStored() throws Exception {
|
||||
IndexCacheKey key1 = new IndexCacheKey("somekey", "1");
|
||||
cache.store(key1, new String[0], new ArrayList<>(), null);
|
||||
cache.store(key1, new String[0], new ArrayList<>(), null, CachedSymbol.class);
|
||||
assertTrue(Files.exists(tempDir.resolve(Paths.get(key1.toString() + ".json"))));
|
||||
|
||||
IndexCacheKey key2 = new IndexCacheKey("somekey", "2");
|
||||
cache.store(key2, new String[0], new ArrayList<>(), null);
|
||||
cache.store(key2, new String[0], new ArrayList<>(), null, CachedSymbol.class);
|
||||
assertTrue(Files.exists(tempDir.resolve(Paths.get(key2.toString() + ".json"))));
|
||||
assertFalse(Files.exists(tempDir.resolve(Paths.get(key1.toString() + ".json"))));
|
||||
}
|
||||
@@ -231,11 +230,11 @@ public class IndexCacheOnDiscTest {
|
||||
WebfluxElementsInformation addon = new WebfluxElementsInformation(new Range(new Position(4, 4), new Position(5, 5)), new Range(new Position(6, 6), new Position(7, 7)));
|
||||
EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[]{addon});
|
||||
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files);
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(cachedSymbols);
|
||||
assertEquals(1, cachedSymbols.length);
|
||||
|
||||
@@ -268,9 +267,9 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols1 = new ArrayList<>();
|
||||
WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null);
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null));
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null, CachedSymbol.class);
|
||||
|
||||
List<CachedSymbol> generatedSymbols2 = new ArrayList<>();
|
||||
symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location(doc1URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
@@ -279,13 +278,13 @@ public class IndexCacheOnDiscTest {
|
||||
WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Interface, Either.forLeft(new Location(doc1URI, new Range(new Position(5, 5), new Position(5, 10)))));
|
||||
EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null);
|
||||
|
||||
generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol1, null));
|
||||
generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol2, null));
|
||||
generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol1));
|
||||
generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol2));
|
||||
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000));
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, null);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, null, CachedSymbol.class);
|
||||
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files);
|
||||
AbstractIndexCacheable[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(cachedSymbols);
|
||||
assertEquals(2, cachedSymbols.length);
|
||||
|
||||
@@ -317,18 +316,18 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols = new ArrayList<>();
|
||||
WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location(doc1URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null);
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1));
|
||||
|
||||
WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null);
|
||||
generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2));
|
||||
|
||||
WorkspaceSymbol symbol3 = new WorkspaceSymbol("symbol3", SymbolKind.Field, Either.forLeft(new Location(doc3URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol3 = new EnhancedSymbolInformation(symbol3, null);
|
||||
generatedSymbols.add(new CachedSymbol(doc3URI, timeFile3.toMillis(), enhancedSymbol3, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc3URI, timeFile3.toMillis(), enhancedSymbol3));
|
||||
|
||||
// store original version of the symbols to the cache
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
|
||||
// create updated and new symbols
|
||||
@@ -340,23 +339,23 @@ public class IndexCacheOnDiscTest {
|
||||
WorkspaceSymbol newSymbol1 = new WorkspaceSymbol("symbol1-new", SymbolKind.Interface, Either.forLeft(new Location(doc1URI, new Range(new Position(5, 5), new Position(5, 10)))));
|
||||
EnhancedSymbolInformation newEnhancedSymbol1 = new EnhancedSymbolInformation(newSymbol1, null);
|
||||
|
||||
updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, updatedEnhancedSymbol1, null));
|
||||
updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, newEnhancedSymbol1, null));
|
||||
updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, updatedEnhancedSymbol1));
|
||||
updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, newEnhancedSymbol1));
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000));
|
||||
|
||||
WorkspaceSymbol updatedSymbol2 = new WorkspaceSymbol("symbol2-updated", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation updatedEnhancedSymbol2 = new EnhancedSymbolInformation(updatedSymbol2, null);
|
||||
updatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis() + 3000, updatedEnhancedSymbol2, null));
|
||||
updatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis() + 3000, updatedEnhancedSymbol2));
|
||||
assertTrue(file2.toFile().setLastModified(timeFile2.toMillis() + 3000));
|
||||
|
||||
String[] updatedFiles = new String[]{file1.toAbsolutePath().toString(), file2.toAbsolutePath().toString()};
|
||||
long[] updatedModificationTimestamps = new long[]{timeFile1.toMillis() + 2000, timeFile2.toMillis() + 3000};
|
||||
|
||||
// update multiple files in the cache
|
||||
cache.update(new IndexCacheKey("somekey", "1"), updatedFiles, updatedModificationTimestamps, updatedSymbols, null);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), updatedFiles, updatedModificationTimestamps, updatedSymbols, null, CachedSymbol.class);
|
||||
|
||||
// double check whether all changes got stored and retrieved correctly
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files);
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(cachedSymbols);
|
||||
assertEquals(4, cachedSymbols.length);
|
||||
|
||||
@@ -395,13 +394,13 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols = ImmutableList.of();
|
||||
|
||||
Multimap<String, String> dependencies = ImmutableMultimap.of(file1.toString(), "dep1");
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, dependencies);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, dependencies, CachedSymbol.class);
|
||||
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000));
|
||||
Set<String> dependencies2 = ImmutableSet.of("dep1", "dep2");
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols, dependencies2);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols, dependencies2, CachedSymbol.class);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(result);
|
||||
assertEquals(ImmutableSet.of("dep1", "dep2"), result.getRight().get(file1.toString()));
|
||||
}
|
||||
@@ -420,16 +419,16 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols1 = new ArrayList<>();
|
||||
WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null);
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null));
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null, CachedSymbol.class);
|
||||
|
||||
List<CachedSymbol> generatedSymbols2 = new ArrayList<>();
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000));
|
||||
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, null);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, null, CachedSymbol.class);
|
||||
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files);
|
||||
AbstractIndexCacheable[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(cachedSymbols);
|
||||
assertEquals(0, cachedSymbols.length);
|
||||
}
|
||||
@@ -450,15 +449,15 @@ public class IndexCacheOnDiscTest {
|
||||
file1.toString(), "dep2"
|
||||
);
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, dependencies1);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, dependencies1, CachedSymbol.class);
|
||||
|
||||
List<CachedSymbol> generatedSymbols2 = new ArrayList<>();
|
||||
assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000));
|
||||
|
||||
Set<String> dependencies2 = ImmutableSet.of("dep2");
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, dependencies2);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, dependencies2, CachedSymbol.class);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
assertNotNull(result);
|
||||
assertEquals(ImmutableSet.of("dep2"), result.getRight().get(file1.toString()));
|
||||
}
|
||||
@@ -481,19 +480,19 @@ public class IndexCacheOnDiscTest {
|
||||
List<CachedSymbol> generatedSymbols1 = new ArrayList<>();
|
||||
WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location(doc1URI, new Range(new Position(3, 10), new Position(3, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null);
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null));
|
||||
generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1));
|
||||
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, null, CachedSymbol.class);
|
||||
|
||||
List<CachedSymbol> generatedSymbols2 = new ArrayList<>();
|
||||
WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Interface, Either.forLeft(new Location(doc2URI, new Range(new Position(5, 5), new Position(5, 10)))));
|
||||
EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null);
|
||||
|
||||
generatedSymbols2.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null));
|
||||
generatedSymbols2.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2));
|
||||
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file2.toString(), timeFile2.toMillis(), generatedSymbols2, null);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file2.toString(), timeFile2.toMillis(), generatedSymbols2, null, CachedSymbol.class);
|
||||
|
||||
CachedSymbol[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), new String[]{file1.toString(), file2.toString()});
|
||||
AbstractIndexCacheable[] cachedSymbols = cache.retrieveSymbols(new IndexCacheKey("somekey", "1"), new String[]{file1.toString(), file2.toString()}, CachedSymbol.class);
|
||||
assertNotNull(cachedSymbols);
|
||||
assertEquals(2, cachedSymbols.length);
|
||||
}
|
||||
@@ -513,12 +512,12 @@ public class IndexCacheOnDiscTest {
|
||||
Multimap<String, String> dependencies1 = ImmutableMultimap.of(
|
||||
file1.toString(), "dep1"
|
||||
);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, dependencies1);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols1, dependencies1, CachedSymbol.class);
|
||||
|
||||
Set<String> dependencies2 = ImmutableSet.of("dep2");
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file2.toString(), timeFile2.toMillis(), generatedSymbols1, dependencies2);
|
||||
cache.update(new IndexCacheKey("somekey", "1"), file2.toString(), timeFile2.toMillis(), generatedSymbols1, dependencies2, CachedSymbol.class);
|
||||
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), new String[]{file1.toString(), file2.toString()});
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), new String[]{file1.toString(), file2.toString()}, CachedSymbol.class);
|
||||
assertNotNull(result);
|
||||
assertEquals(ImmutableSet.of("dep2"), result.getRight().get(file2.toString()));
|
||||
assertEquals(ImmutableSet.of("dep1"), result.getRight().get(file1.toString()));
|
||||
@@ -527,7 +526,7 @@ public class IndexCacheOnDiscTest {
|
||||
@Test
|
||||
void testProjectDeleted() throws Exception {
|
||||
IndexCacheKey key1 = new IndexCacheKey("somekey", "1");
|
||||
cache.store(key1, new String[0], new ArrayList<>(), null);
|
||||
cache.store(key1, new String[0], new ArrayList<>(), null, CachedSymbol.class);
|
||||
assertTrue(Files.exists(tempDir.resolve(Paths.get(key1.toString() + ".json"))));
|
||||
|
||||
cache.remove(key1);
|
||||
@@ -557,18 +556,18 @@ public class IndexCacheOnDiscTest {
|
||||
WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(5, 10), new Position(5, 20)))));
|
||||
EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null);
|
||||
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null));
|
||||
generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1));
|
||||
generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2));
|
||||
|
||||
Multimap<String, String> dependencies = ImmutableMultimap.of(
|
||||
file1.toString(), "dep1",
|
||||
file2.toString(), "dep2"
|
||||
);
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, dependencies);
|
||||
cache.removeFile(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString());
|
||||
cache.store(new IndexCacheKey("somekey", "1"), files, generatedSymbols, dependencies, CachedSymbol.class);
|
||||
cache.removeFile(new IndexCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), CachedSymbol.class);
|
||||
|
||||
files = new String[]{file2.toAbsolutePath().toString()};
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files);
|
||||
Pair<CachedSymbol[], Multimap<String, String>> result = cache.retrieve(new IndexCacheKey("somekey", "1"), files, CachedSymbol.class);
|
||||
CachedSymbol[] cachedSymbols = result.getLeft();
|
||||
assertNotNull(result);
|
||||
assertEquals(1, cachedSymbols.length);
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCache;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheKey;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.index.cache.IndexCacheable;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class IndexCacheTimestampsOnly implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(IndexCacheKey cacheKey, String[] files, List<CachedSymbol> generatedSymbols, Multimap<String,String> dependencies) {
|
||||
public <T extends IndexCacheable> void store(IndexCacheKey cacheKey, String[] files, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type) {
|
||||
SortedMap<String, Long> timestampedFiles = new TreeMap<>();
|
||||
|
||||
timestampedFiles = Arrays.stream(files)
|
||||
@@ -58,18 +58,18 @@ public class IndexCacheTimestampsOnly implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<CachedSymbol[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files) {
|
||||
public <T extends IndexCacheable> Pair<T[], Multimap<String, String>> retrieve(IndexCacheKey cacheKey, String[] files, Class<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String file, long lastModified, List<CachedSymbol> generatedSymbols, Set<String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String file, long lastModified, List<T> generatedSymbols, Set<String> dependencies, Class<T> type) {
|
||||
Map<String, Long> timestampMap = timestampCache.get(cacheKey);
|
||||
timestampMap.put(file, lastModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<CachedSymbol> generatedSymbols, Multimap<String, String> dependencies) {
|
||||
public <T extends IndexCacheable> void update(IndexCacheKey cacheKey, String[] files, long[] lastModified, List<T> generatedSymbols, Multimap<String, String> dependencies, Class<T> type) {
|
||||
Map<String, Long> timestampMap = timestampCache.get(cacheKey);
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
@@ -82,7 +82,7 @@ public class IndexCacheTimestampsOnly implements IndexCache {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFile(IndexCacheKey symbolCacheKey, String file) {
|
||||
public <T extends IndexCacheable> void removeFile(IndexCacheKey symbolCacheKey, String file, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user