com.microsoft.kiota.store.InMemoryBackingStore Maven / Gradle / Ivy
The newest version!
package com.microsoft.kiota.store;
import com.microsoft.kiota.TriConsumer;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/** In-memory implementation of the backing store. Allows for dirty tracking of changes. */
public class InMemoryBackingStore implements BackingStore {
/** Creates a new instance of the backing store. */
public InMemoryBackingStore() {
// default constructor
}
private static class Pair {
private final A value0;
private final B value1;
public Pair(A value0, B value1) {
this.value0 = value0;
this.value1 = value1;
}
public A getValue0() {
return value0;
}
public Pair setValue0(A value0) {
return new Pair<>(value0, value1);
}
public B getValue1() {
return value1;
}
public Pair setValue1(B value1) {
return new Pair<>(value0, value1);
}
}
private boolean isInitializationCompleted = true;
private boolean returnOnlyChangedValues;
private final Map> store = new ConcurrentHashMap<>();
private final Map> subscriptionStore =
new ConcurrentHashMap<>();
public void setIsInitializationCompleted(final boolean value) {
this.isInitializationCompleted = value;
ensureCollectionPropertiesAreConsistent();
for (final Map.Entry> entry : this.store.entrySet()) {
final Pair wrapper = entry.getValue();
final Pair updatedValue = new Pair<>(!value, wrapper.getValue1());
entry.setValue(updatedValue);
if (wrapper.getValue1() instanceof BackedModel) {
BackedModel backedModel = (BackedModel) wrapper.getValue1();
backedModel
.getBackingStore()
.setIsInitializationCompleted(value); // propagate initialization
}
if (isCollectionValue(wrapper)) {
final Pair, Integer> collectionTuple = (Pair, Integer>) wrapper.getValue1();
Object[] items = getObjectArrayFromCollectionWrapper(collectionTuple);
final boolean isCollection = collectionTuple.getValue0() instanceof Collection;
// No need to iterate over collection if first item is not BackedModel
if ((isCollection && items.length != 0 && items[0] instanceof BackedModel)
|| !isCollection) {
for (final Object item : items) {
if (item instanceof BackedModel) {
BackedModel backedModel = (BackedModel) item;
backedModel
.getBackingStore()
.setIsInitializationCompleted(
value); // propagate initialization
}
}
}
}
}
}
public boolean getIsInitializationCompleted() {
return this.isInitializationCompleted;
}
public void setReturnOnlyChangedValues(final boolean value) {
this.returnOnlyChangedValues = value;
// propagate to nested backed models
for (final Map.Entry> entry : this.store.entrySet()) {
final Pair wrapper = entry.getValue();
if (wrapper.getValue1() instanceof BackedModel) {
final BackedModel item = (BackedModel) wrapper.getValue1();
item.getBackingStore().setReturnOnlyChangedValues(value);
}
if (isCollectionValue(wrapper)) {
final Pair, Integer> collectionTuple = (Pair, Integer>) wrapper.getValue1();
Object[] items = getObjectArrayFromCollectionWrapper(collectionTuple);
final boolean isCollection = collectionTuple.getValue0() instanceof Collection;
// No need to iterate over collection if first item is not BackedModel
if ((isCollection && items.length != 0 && items[0] instanceof BackedModel)
|| !isCollection) {
for (final Object item : items) {
if (item instanceof BackedModel) {
BackedModel backedModel = (BackedModel) item;
backedModel.getBackingStore().setReturnOnlyChangedValues(value);
}
}
}
}
}
}
public boolean getReturnOnlyChangedValues() {
return this.returnOnlyChangedValues;
}
public void clear() {
this.store.clear();
}
@Nonnull public Map enumerate() {
final Map result = new HashMap<>();
for (final Map.Entry> entry : this.store.entrySet()) {
final Pair wrapper = entry.getValue();
final Object value = this.get(entry.getKey());
if (value != null) {
result.put(entry.getKey(), value);
} else if (Boolean.TRUE.equals(wrapper.getValue0())) {
result.put(entry.getKey(), null);
}
}
return result;
}
@Nonnull public Iterable enumerateKeysForValuesChangedToNull() {
final List result = new ArrayList<>();
for (final Map.Entry> entry : this.store.entrySet()) {
final Pair wrapper = entry.getValue();
final Object value = wrapper.getValue1();
if (value == null && wrapper.getValue0()) {
result.add(entry.getKey());
}
}
return result;
}
private Object getValueFromWrapper(final Pair wrapper) {
if (wrapper == null) {
return null;
}
if (isCollectionValue(wrapper)) {
Pair, ?> collectionTuple = (Pair, ?>) wrapper.getValue1();
return collectionTuple.getValue0();
}
return wrapper.getValue1();
}
@SuppressWarnings("unchecked")
@Nullable public T get(@Nonnull final String key) {
Objects.requireNonNull(key);
final Pair wrapper = this.store.get(key);
if (wrapper == null) {
return null;
}
final Object value = this.getValueFromWrapper(wrapper);
boolean hasChanged = wrapper.getValue0();
if (getReturnOnlyChangedValues() && !hasChanged) {
if (isCollectionValue(wrapper)) {
ensureCollectionPropertiesAreConsistent();
hasChanged = this.store.get(key).getValue0();
}
if (!hasChanged) {
return null;
}
}
try {
return (T) value;
} catch (ClassCastException ex) {
return null;
}
}
public void set(@Nonnull final String key, @Nullable final T value) {
Objects.requireNonNull(key);
Pair valueToAdd = new Pair<>(this.isInitializationCompleted, value);
if (value instanceof Collection) {
valueToAdd = valueToAdd.setValue1(new Pair<>(value, ((Collection>) value).size()));
final Collection