Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
prompto.code.MutableCodeStore Maven / Gradle / Ivy
package prompto.code;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import prompto.declaration.AttributeDeclaration;
import prompto.declaration.CategoryDeclaration;
import prompto.declaration.DeclarationList;
import prompto.declaration.IDeclaration;
import prompto.declaration.IDeclaration.DeclarationType;
import prompto.declaration.IEnumeratedDeclaration;
import prompto.declaration.IMethodDeclaration;
import prompto.declaration.NativeCategoryDeclaration;
import prompto.error.PromptoError;
import prompto.expression.Symbol;
import prompto.grammar.Annotation;
import prompto.grammar.Identifier;
import prompto.grammar.OrderByClause;
import prompto.grammar.OrderByClauseList;
import prompto.intrinsic.PromptoDbId;
import prompto.intrinsic.PromptoVersion;
import prompto.parser.Dialect;
import prompto.runtime.Context;
import prompto.runtime.Context.MethodDeclarationMap;
import prompto.store.AttributeInfo;
import prompto.store.Family;
import prompto.store.IQueryBuilder;
import prompto.store.IQueryBuilder.MatchOp;
import prompto.store.IStorable;
import prompto.store.IStorable.IDbIdFactory;
import prompto.store.IStore;
import prompto.store.IStored;
import prompto.store.IStoredIterable;
import prompto.type.CategoryType;
import prompto.utils.CodeWriter;
import prompto.utils.IdentifierList;
import prompto.utils.Logger;
import prompto.utils.StringUtils;
public class MutableCodeStore extends BaseCodeStore {
static final Logger logger = new Logger();
IStore store; // data store where to store/fetch the code
String application;
PromptoVersion version;
// fetching and storing declarations requires a context holding code store attributes
// some of these are code store specific and should not be looked for in the app context
Context context;
// storing resource code is optional
boolean storeExternals = false;
public MutableCodeStore(IStore store, ICodeStore runtime, String application, PromptoVersion version, URL[] addOns, URL ...resourceNames) throws PromptoError {
super(null);
this.store = store;
this.application = application;
this.version = version;
this.context = CodeStoreBootstrapper.bootstrap(store, runtime);
this.next = AppStoreBootstrapper.bootstrap(store, runtime, application, version, addOns, resourceNames);
}
public IStore getStore() {
return store;
}
public void setStore(IStore store) {
this.store = store;
}
public void collectStorables(List list, IDeclaration declaration, Dialect dialect, Object moduleId) {
if(declaration instanceof MethodDeclarationMap) {
for(IDeclaration method : ((MethodDeclarationMap)declaration).values())
collectStorables(list, method, dialect, moduleId);
} else {
String typeName = StringUtils.capitalizeFirst(declaration.getDeclarationType().name()) + "Declaration";
List categories = Arrays.asList("Resource", "NamedResource", "Declaration", typeName);
IStorable storable = populateDeclarationStorable(categories, declaration, dialect, moduleId);
list.add(storable);
}
}
@Override
public ModuleType getModuleType() {
return ModuleType.WEBSITE;
}
@Override
public Dialect getModuleDialect() {
return null;
}
@Override
public String getModuleName() {
return application;
}
@Override
public PromptoVersion getModuleVersion() {
return version;
}
@Override
public void storeResource(Resource resource, Object moduleId) {
IStorable storable = resource.toStorable(store);
if(moduleId!=null)
storable.setData("module", moduleId);
store.store(null, Collections.singletonList(storable));
}
@Override
public void storeModule(Module module) throws PromptoError {
Context context = Context.newGlobalsContext();
List storables = new ArrayList<>();
module.collectStorables(context, store, storables);
store.store(null, storables);
}
@Override
public void storeDependency(Dependency dependency) {
Context context = Context.newGlobalsContext();
List storables = new ArrayList<>();
dependency.collectStorables(context, store, storables);
store.store(null, storables);
}
@Override
public void dropModule(Module module) {
IQueryBuilder builder = store.newQueryBuilder();
builder.verify(AttributeInfo.MODULE, MatchOp.HAS, module.getDbId());
Iterable stuff = store.fetchMany(builder.build());
Stream stuffDbIds = StreamSupport.stream(stuff.spliterator(), false)
.map(IStored::getDbId);
List dbIds = Stream.concat(Stream.of(module.getDbId()), stuffDbIds)
.collect(Collectors.toList());
store.delete(dbIds);
}
private Object storeDeclarationModule(IDeclaration decl) throws PromptoError {
ICodeStore origin = decl.getOrigin();
List categories = Arrays.asList("Module", origin.getModuleType().getCategory().getTypeName());
IStorable storable = store.newStorable(categories, null);
storable.setData("name", origin.getModuleName());
storable.setData("version", origin.getModuleVersion());
store.store(storable);
return storable.getOrCreateDbId();
}
@Override
public Iterable fetchAllModules() throws PromptoError {
try {
IQueryBuilder builder = store.newQueryBuilder();
builder.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "Module");
Iterator iterator = store.fetchMany(builder.build()).iterator();
return () -> new Iterator() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public Module next() {
try {
return moduleFromStored(iterator.next());
} catch(Exception e) {
throw new InternalError(e);
}
}
};
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
@Override
public T fetchVersionedModule(ModuleType type, String name, PromptoVersion version) throws PromptoError {
try {
IStored stored = fetchOneNamedInStore(type.getCategory(), version, name, false);
if(stored==null)
return null;
Module module = type.getModuleClass().getDeclaredConstructor().newInstance();
module.fromStored(store, stored);
return (T)module;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Module fetchModule(String name, PromptoVersion version) throws PromptoError {
try {
IStored stored = fetchOneNamedInStore(new CategoryType(new Identifier("Module")), version, name, false);
return moduleFromStored(stored);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private Module moduleFromStored(IStored stored) throws Exception {
if(stored==null)
return null;
String[] categories = stored.getCategories();
String category = categories[categories.length-1];
ModuleType type = ModuleType.valueOf(category.toUpperCase());
Module module = type.getModuleClass().getDeclaredConstructor().newInstance();
module.fromStored(store, stored);
return module;
}
@Override
public Object fetchVersionedModuleDbId(String name, PromptoVersion version) throws PromptoError {
try {
// could be optimized by only fetching dbId but not worth it...
IStored stored = fetchOneNamedInStore(new CategoryType(new Identifier("Module")), version, name, false);
return stored==null ? null : stored.getDbId();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Resource fetchResource(String name) {
try {
IStored stored = fetchOneInStore(new CategoryType(new Identifier("Resource")), null, "name", name, true);
if(stored==null)
return super.fetchResource(name);
else
return ResourceReader.readResource(stored);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doFetchLatestResourcesWithMimeTypes(List resources, Set mimeTypes) {
IStoredIterable found = fetchManyInStore(new CategoryType(new Identifier("Resource")), null, "mimeType", mimeTypes, true);
found.forEach(stored -> resources.add(ResourceReader.readResource(stored)));
}
static ThreadLocal>> registering = new ThreadLocal>>() {
@Override protected Map> initialValue() {
return new HashMap<>();
}
};
@SuppressWarnings("unchecked")
private IDeclaration getRegisteringSymbol(String name) {
return registering.get().values().stream()
.map(i->StreamSupport.stream(i.spliterator(), false))
.flatMap(Function.identity())
.filter(d->d instanceof IEnumeratedDeclaration)
.map(d->(IEnumeratedDeclaration)d)
.filter(e->e.hasSymbol(name))
.findFirst()
.orElse(null);
}
private Iterable getRegisteringDeclarations(String name) {
return registering.get().get(name);
}
private void setRegisteringDeclarations(String name, Iterable decl) {
registering.get().put(name, decl);
}
private void clearRegisteringDeclarations(String name) {
registering.get().remove(name);
}
@Override
public Collection fetchDeclarationNames() {
// TODO Auto-generated method stub
return super.fetchDeclarationNames();
}
@Override
public Iterable fetchDeclarations(String name) throws PromptoError {
Iterable decls = fetchDeclarationsInStore(name);
if(decls!=null)
return decls;
if(storeExternals)
return fetchAndStoreExternalDeclarations(name);
else
return super.fetchDeclarations(name);
}
@Override
public Iterable fetchDeclarationsWithAnnotations(Set annotations) {
Iterator fetched = fetchDeclarationsWithAnnotationsInStore(annotations).iterator();
Iterable parsed = () -> new Iterator() {
@Override public boolean hasNext() { return fetched.hasNext(); }
@Override public IDeclaration next() { return parseDeclaration(fetched.next()); }
};
if(next==null)
return parsed;
else {
Iterable decls = next.fetchDeclarationsWithAnnotations(annotations);
return Stream.concat(StreamSupport.stream(decls.spliterator(), false), StreamSupport.stream(parsed.spliterator(), false)).collect(Collectors.toList());
}
}
private synchronized Iterable fetchAndStoreExternalDeclarations(String name) {
// when called from the AppServer, multiple threads may be attempting to do this
// TODO: need to deal with multiple cloud nodes doing this
synchronized(this) {
Iterable decls = fetchDeclarationsInStore(name);
if(decls!=null)
return decls;
decls = getRegisteringDeclarations(name);
if(decls!=null)
return decls;
decls = super.fetchDeclarations(name);
if(store!=null && decls!=null && decls.iterator().hasNext()) {
// avoid infinite reentrance loop
setRegisteringDeclarations(name, decls);
decls = storeDeclarations(decls);
clearRegisteringDeclarations(name);
store.flush();
}
return decls;
}
}
@Override
public IDeclaration fetchVersionedSymbol(String name, PromptoVersion version) throws PromptoError {
Iterable decls = fetchSymbolsInStore(name, version, true);
if(decls!=null && decls.iterator().hasNext())
return decls.iterator().next();
if(storeExternals)
return fetchAndStoreExternalSpecificSymbol(name, version);
else
return super.fetchVersionedSymbol(name, version);
}
private synchronized IDeclaration fetchAndStoreExternalSpecificSymbol(String name, PromptoVersion version) {
// when called from the AppServer, multiple threads may be attempting to do this
// TODO: need to deal with multiple cloud nodes doing this
synchronized(this) {
Iterable decls = fetchSymbolsInStore(name, version, true);
if(decls!=null && decls.iterator().hasNext())
return decls.iterator().next();
IDeclaration decl = getRegisteringSymbol(name);
if(decl==null) {
decl = super.fetchVersionedSymbol(name, version);
if(store!=null && decl!=null) {
setRegisteringDeclarations(decl.getName(), Collections.singletonList(decl));
decls = storeDeclarations(Collections.singletonList(decl));
clearRegisteringDeclarations(decl.getName());
store.flush();
decl = decls.iterator().next();
}
}
return decl;
}
}
private Iterable fetchSymbolsInStore(String name, PromptoVersion version, boolean filterOnModules) {
IStoredIterable iterable = fetchStoredDeclarationsBySymbol(name, version, filterOnModules);
if(iterable.iterator().hasNext()) {
Iterator iterator = iterable.iterator();
return () -> new Iterator() {
@Override public boolean hasNext() { return iterator.hasNext(); }
@Override public IDeclaration next() { return parseDeclaration(iterator.next()); }
};
} else
return null;
}
private IStoredIterable fetchStoredDeclarationsBySymbol(String name, PromptoVersion version, boolean filterOnModules) {
IQueryBuilder builder = store.newQueryBuilder()
.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "EnumeratedDeclaration")
.verify(AttributeInfo.SYMBOLS, MatchOp.HAS, name)
.and();
builder = filterOnModules(builder, filterOnModules);
if(PromptoVersion.LATEST.equals(version)) {
IdentifierList names = IdentifierList.parse("prototype,version");
OrderByClauseList orderBy = new OrderByClauseList( new OrderByClause(names, true) );
orderBy.interpretQuery(context, builder);
IStoredIterable stored = store.fetchMany(builder.build());
return fetchDistinct(stored);
} else
return store.fetchMany(builder.build());
}
private IQueryBuilder filterOnModules(IQueryBuilder builder, boolean filterOnModules) {
if(!filterOnModules || ICodeStore.getModuleDbIds().isEmpty())
return builder;
AttributeInfo info = new AttributeInfo("module", Family.CATEGORY, false, null);
builder.verify(info, MatchOp.IN, ICodeStore.getModuleDbIds());
return builder.and();
}
@Override
public Collection fetchDerivedCategoryDeclarations(Identifier id) {
Stream stream1 = super.fetchDerivedCategoryDeclarations(id).stream();
Stream stream2 = doFetchDerivedCategoryDeclarations(id).stream();
return Stream.concat(stream1, stream2).collect(Collectors.toList());
}
Collection doFetchDerivedCategoryDeclarations(Identifier id) {
IQueryBuilder builder = store.newQueryBuilder()
.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "CategoryDeclaration")
.verify(AttributeInfo.DERIVED_FROM, MatchOp.HAS, id.toString())
.and();
builder = filterOnModules(builder, true);
IdentifierList names = IdentifierList.parse("version");
OrderByClauseList orderBy = new OrderByClauseList( new OrderByClause(names, true) );
orderBy.interpretQuery(context, builder);
IStoredIterable stored = store.fetchMany(builder.build());
IStoredIterable distinct = fetchDistinct(stored);
return StreamSupport.stream(distinct.spliterator(), false)
.map(s->parseDeclaration(s))
.filter(d->d instanceof CategoryDeclaration)
.map(d->(CategoryDeclaration)d)
.collect(Collectors.toList());
}
private Iterable storeDeclarations(Iterable decls) throws PromptoError {
Iterator iter = decls.iterator();
if(!iter.hasNext())
return null;
// need module id
IDeclaration decl = iter.next();
ICodeStore origin = decl.getOrigin();
if(origin==null)
throw new InternalError("Cannot store declaration with no origin!");
Object moduleId = fetchDeclarationModuleDbId(decl);
if(moduleId==null)
moduleId = storeDeclarationModule(decl);
storeDeclarations(decls, origin.getModuleDialect(), moduleId);
return decls;
}
@Override
public void storeDeclarations(Iterable declarations, Dialect dialect, Object moduleId) throws PromptoError {
List list = new ArrayList<>();
declarations.forEach((decl)->
collectStorables(list, decl, dialect, moduleId));
store.store(null, list);
}
private Object fetchDeclarationModuleDbId(IDeclaration decl) throws PromptoError {
ICodeStore origin = decl.getOrigin();
IStored stored = fetchOneNamedInStore(origin.getModuleType().getCategory(), origin.getModuleVersion(), origin.getModuleName(), false);
if(stored==null)
return null;
else
return stored.getDbId();
}
private IStorable populateDeclarationStorable(List categories, IDeclaration decl, Dialect dialect, Object moduleId) {
IStorable storable = store.newStorable(categories, null);
try {
storable.setData("name", decl.getId().toString());
if(decl instanceof IMethodDeclaration) {
String proto = ((IMethodDeclaration)decl).getProto();
storable.setData("prototype", proto);
}
storable.setData("dialect", dialect.name());
CodeWriter writer = new CodeWriter(dialect, context);
decl.toDialect(writer);
String content = writer.toString();
storable.setData("body", content);
storable.setData("module", moduleId);
if(decl instanceof IEnumeratedDeclaration) {
@SuppressWarnings("unchecked")
List symbols = ((IEnumeratedDeclaration)decl).getSymbolsList().stream()
.map(Symbol::getName)
.collect(Collectors.toList());
storable.setData("symbols", symbols);
}
if(decl.isStorable(null))
storable.setData("storable", true);
Collection annotations = decl.getLocalAnnotations();
if(annotations!=null && !annotations.isEmpty()) {
List data = annotations.stream().map(Annotation::toString).collect(Collectors.toList());
storable.setData("annotations", data);
}
return storable;
} catch(PromptoError e) {
throw new RuntimeException(e);
}
}
private Iterable fetchDeclarationsInStore(String name) {
if(store==null)
return null;
else try {
CategoryType category = new CategoryType(new Identifier("Declaration"));
IStoredIterable iterable = fetchManyInStore(category, null, "name", name, true);
if(iterable.iterator().hasNext()) {
Iterator iterator = iterable.iterator();
return () -> new Iterator() {
@Override public boolean hasNext() { return iterator.hasNext(); }
@Override public IDeclaration next() { return parseDeclaration(iterator.next()); }
};
} else
return null;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private IStoredIterable fetchDeclarationsWithAnnotationsInStore(Set annotations) {
if(store==null)
return null;
else try {
IQueryBuilder builder = store.newQueryBuilder();
builder.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "Declaration");
builder.verify(AttributeInfo.ANNOTATIONS, MatchOp.HAS_ANY, annotations);
builder.and();
builder = filterOnModules(builder, true);
IdentifierList names = new IdentifierList("prototype", "version");
OrderByClauseList orderBy = new OrderByClauseList( new OrderByClause(names, true) );
orderBy.interpretQuery(context, builder);
IStoredIterable stored = store.fetchMany(builder.build());
return fetchDistinct(stored);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private static Set uniqueDecls = new HashSet<>(
Arrays.asList(DeclarationType.ATTRIBUTE.name(), DeclarationType.CATEGORY.name(), DeclarationType.TEST.name()));
@Override
public NativeCategoryDeclaration fetchLatestNativeCategoryDeclarationWithJavaBinding(String typeName) {
if(store==null)
return null;
else try {
IQueryBuilder builder = store.newQueryBuilder();
builder.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "NativeCategoryDeclaration");
builder = filterOnModules(builder, true);
IdentifierList names = new IdentifierList("version");
OrderByClauseList orderBy = new OrderByClauseList( new OrderByClause(names, true) );
orderBy.interpretQuery(context, builder);
IStoredIterable stored = store.fetchMany(builder.build());
NativeCategoryDeclaration decl = filterNativeCategoryDeclarationWithJavaBinding(stored, typeName);
if(decl!=null)
return decl;
else
return super.fetchLatestNativeCategoryDeclarationWithJavaBinding(typeName);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private NativeCategoryDeclaration filterNativeCategoryDeclarationWithJavaBinding(IStoredIterable iterable, String typeName) {
Iterator iterator = iterable.iterator();
while(iterator.hasNext()) {
NativeCategoryDeclaration decl = parseDeclaration(iterator.next());
if(typeName.equals(decl.getBoundClassName()))
return decl;
}
return null;
}
private IStoredIterable fetchManyInStore(CategoryType type, PromptoVersion version, String attribute, Object value, boolean filterOnModules) throws PromptoError {
IQueryBuilder builder = store.newQueryBuilder();
if(uniqueDecls.contains(type.toString().toUpperCase())) {
builder.first(1L).last(1L);
}
builder = verifyCategory(builder, type);
builder = verifyVersion(builder, version);
builder = verifyAttribute(builder, attribute, value);
builder = filterOnModules(builder, filterOnModules);
if(PromptoVersion.LATEST.equals(version)) {
builder = orderByVersion(builder);
IStoredIterable stored = store.fetchMany(builder.build());
return fetchDistinct(stored);
} else
return store.fetchMany(builder.build());
}
private IQueryBuilder verifyCategory(IQueryBuilder builder, CategoryType type) {
return builder.verify(AttributeInfo.CATEGORY, MatchOp.HAS, type.getTypeName());
}
private IQueryBuilder verifyVersion(IQueryBuilder builder, PromptoVersion version) {
if(version==null || PromptoVersion.LATEST.equals(version))
return builder;
else
return builder.verify(AttributeInfo.VERSION, MatchOp.EQUALS, version).and();
}
private IQueryBuilder orderByVersion(IQueryBuilder builder) {
OrderByClauseList orderBy = new OrderByClauseList();
orderBy.add(new OrderByClause(new IdentifierList("prototype"), false));
orderBy.add(new OrderByClause(new IdentifierList("version"), true));
return orderBy.interpretQuery(context, builder);
}
private IQueryBuilder verifyAttribute(IQueryBuilder builder, String attribute, Object value) {
AttributeInfo info = fetchAttributeInfo(context, attribute);
MatchOp op = value instanceof Collection ? MatchOp.IN : MatchOp.EQUALS;
return builder.verify(info, op, value).and();
}
private IStored fetchOneNamedInStore(CategoryType type, PromptoVersion version, String name, boolean filterOnModules) throws PromptoError {
return fetchOneInStore(type, version, "name", name, filterOnModules);
}
private IStored fetchOneInStore(CategoryType type, PromptoVersion version, String attribute, String value, boolean filterOnModules) throws PromptoError {
IQueryBuilder builder = store.newQueryBuilder();
builder = verifyCategory(builder, type);
builder = verifyVersion(builder, version);
builder = verifyAttribute(builder, attribute, value);
builder = filterOnModules(builder, filterOnModules);
if(PromptoVersion.LATEST.equals(version)) {
builder = orderByVersion(builder);
builder.first(1L).last(1L);
IStoredIterable iterable = store.fetchMany(builder.build());
Iterator stored = iterable.iterator();
return stored.hasNext() ? stored.next() : null;
} else
return store.fetchOne(builder.build());
}
@Override
public void collectStorableAttributes(Map map) throws PromptoError {
super.collectStorableAttributes(map);
if(store!=null) {
IQueryBuilder builder = store.newQueryBuilder();
builder.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "AttributeDeclaration");
builder.verify(AttributeInfo.STORABLE, MatchOp.EQUALS, true);
builder.and();
builder = filterOnModules(builder, true);
IStoredIterable iterable = store.fetchMany(builder.build());
Iterator stored = iterable.iterator();
while(stored.hasNext()) {
AttributeDeclaration attr = parseDeclaration(stored.next());
map.put(attr.getName(), attr);
}
}
}
private IStoredIterable fetchDistinct(IStoredIterable iterable) {
/* we don't support distinct/group by yet, so need to do it "by hand" on client side */
List distinct = new ArrayList<>();
Object lastName = null;
Object lastProto = null;
for(IStored stored : iterable) {
Object thisName = stored.getData("name");
Object thisProto = stored.getData("prototype");
if(!Objects.equals(thisName, lastName) || !Objects.equals(thisProto, lastProto)) {
distinct.add(stored);
lastName = thisName;
lastProto = thisProto;
}
}
return new IStoredIterable() {
@Override public Iterator iterator() { return distinct.iterator(); }
@Override public long count() { return distinct.size(); }
@Override public long totalCount() { return distinct.size(); }
};
}
@SuppressWarnings("unchecked")
private T parseDeclaration(IStored stored) {
if(stored==null)
return null;
try {
logger.debug(()->"Found " + stored.getData("name") + " with dbId " + stored.getDbId());
Dialect dialect = Dialect.valueOf((String)stored.getData("dialect"));
String body = (String)stored.getData("body");
InputStream input = new ByteArrayInputStream(body.getBytes());
DeclarationList decls = ICodeStore.parse(dialect, "__store__", input);
return decls.isEmpty() ? null : (T)decls.get(0);
} catch (Exception e) {
throw new RuntimeException(e); // TODO
}
}
@Override
public void upgradeIfRequired() {
upgradeDerivedFrom();
upgradeVersionQualifiers();
dropResourceVersions();
super.upgradeIfRequired();
}
private void dropResourceVersions() {
Map config = store.fetchConfiguration("CodeStoreConfiguration");
if(config==null)
config = new HashMap<>();
if(config.containsKey("resourceVersions"))
return;
logger.info(()->"Upgrading code store for resourceVersions...");
IQueryBuilder builder = store.newQueryBuilder()
.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "Resource")
.verify(AttributeInfo.VERSION, MatchOp.EQUALS, null)
.not()
.and();
IStoredIterable stored = store.fetchMany(builder.build());
StreamSupport.stream(stored.spliterator(), false)
.forEach(this::dropResourceVersion);
config.put("resourceVersions", true);
store.storeConfiguration("CodeStoreConfiguration", config);
logger.info(()->"Code store upgraded for resourceVersions");
}
private void dropResourceVersion(IStored stored) {
Object value = stored.getRawData("version");
if(value!=null) {
IStorable storable = store.newStorable(stored.getCategories(), IDbIdFactory.of(()->stored.getDbId(), null, ()->true));
storable.removeData("version");
store.store(storable);
}
}
private void upgradeVersionQualifiers() {
Map config = store.fetchConfiguration("CodeStoreConfiguration");
if(config==null)
config = new HashMap<>();
if(config.containsKey("versionQualifiers"))
return;
logger.info(()->"Upgrading code store for versionQualifiers...");
IQueryBuilder builder = store.newQueryBuilder()
.verify(AttributeInfo.VERSION, MatchOp.EQUALS, null)
.not();
IStoredIterable stored = store.fetchMany(builder.build());
StreamSupport.stream(stored.spliterator(), false)
.forEach(this::upgradeVersionQualifiers);
config.put("versionQualifiers", true);
store.storeConfiguration("CodeStoreConfiguration", config);
logger.info(()->"Code store upgraded for versionQualifiers");
}
private void upgradeVersionQualifiers(IStored stored) {
Object value = stored.getRawData("version");
if(value instanceof Integer) {
PromptoVersion version = PromptoVersion.parseInt((Integer)value);
IStorable storable = store.newStorable(stored.getCategories(), IDbIdFactory.of(()->stored.getDbId(), null, ()->true));
storable.setData("version", version.asInt());
store.store(storable);
}
}
private void upgradeDerivedFrom() {
Map config = store.fetchConfiguration("CodeStoreConfiguration");
if(config==null)
config = new HashMap<>();
if(config.containsKey("derivedFrom"))
return;
logger.info(()->"Upgrading code store for derivedFrom attribute...");
IQueryBuilder builder = store.newQueryBuilder()
.verify(AttributeInfo.CATEGORY, MatchOp.HAS, "CategoryDeclaration");
IStoredIterable stored = store.fetchMany(builder.build());
StreamSupport.stream(stored.spliterator(), false)
.forEach(this::upgradeDerivedFrom);
config.put("derivedFrom", true);
store.storeConfiguration("CodeStoreConfiguration", config);
logger.info(()->"Code store upgraded or derivedFrom attribute");
}
private void upgradeDerivedFrom(IStored stored) {
IDeclaration decl = parseDeclaration(stored);
if(decl instanceof CategoryDeclaration) {
IdentifierList derivedFrom = ((CategoryDeclaration)decl).getDerivedFrom();
if(derivedFrom!=null && !derivedFrom.isEmpty()) {
List names = derivedFrom.stream().map(Object::toString).collect(Collectors.toList());
IStorable storable = store.newStorable(stored.getCategories(), new IDbIdFactory() {
@Override public void accept(PromptoDbId t) { }
@Override public PromptoDbId get() { return stored.getDbId(); }
@Override public boolean isUpdate() { return true; }
});
storable.setData("derivedFrom", names);
stored.getNames().forEach(name->storable.setData(name, stored.getData(name)));
store.store(storable);
}
}
}
}