
prompto.imports.SampleImporter Maven / Gradle / Ivy
package prompto.imports;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import prompto.code.Dependency;
import prompto.code.ICodeStore;
import prompto.code.ImmutableCodeStore;
import prompto.code.Module;
import prompto.code.ModuleType;
import prompto.code.TextResource;
import prompto.code.WebLibrary;
import prompto.imports.populator.ModulePopulator;
import prompto.intrinsic.PromptoVersion;
import prompto.utils.Logger;
import prompto.utils.StreamUtils;
import prompto.utils.URLUtils;
import prompto.value.ImageValue;
public class SampleImporter {
static Logger logger = new Logger();
Module module;
PromptoVersion migrateFrom;
URL imageResource;
URL codeResource;
URL stubResource;
List javaScripts;
List styleSheets;
List resources;
public SampleImporter(Module module, URL codeResource) {
this.module = module;
this.codeResource = codeResource;
}
public SampleImporter(String resourcePath) {
this(Thread.currentThread().getContextClassLoader().getResource(resourcePath));
}
public SampleImporter(URL url) {
try {
JsonNode descriptor = readDescriptor(url);
Module module = newModule(descriptor);
populateModule(module, descriptor);
populateResources(url, descriptor);
populateMigrateFrom(descriptor);
// done
this.module = module;
} catch(Exception e) {
e.printStackTrace(System.err);
}
}
private void populateMigrateFrom(JsonNode descriptor) {
if(descriptor.get("migrateFrom")!=null)
this.migrateFrom = PromptoVersion.parse(descriptor.get("migrateFrom").asText());
}
private void populateResources(URL moduleUrl, JsonNode descriptor) {
imageResource = makeResourceUrlFromField(moduleUrl, descriptor, "imageResource");
codeResource = makeResourceUrlFromField(moduleUrl, descriptor, "codeResource");
stubResource = makeResourceUrlFromField(moduleUrl, descriptor, "stubResource");
javaScripts = makeResourceUrlsWithMimeType(descriptor, "javaScripts", node -> this.makeResourceUrlWithMimeTypeFromTextualNode(moduleUrl, node, "text/javascript"));
if(javaScripts==null) {
URL nativeResource = makeResourceUrlFromField(moduleUrl, descriptor, "nativeResource");
if(nativeResource != null)
javaScripts = Collections.singletonList(new URLWithMimeType(nativeResource, "text/javascript"));
}
styleSheets = makeResourceUrlsWithMimeType(descriptor, "styleSheets", node -> this.makeResourceUrlWithMimeTypeFromTextualNode(moduleUrl, node, "text/css"));
resources = makeResourceUrlsWithMimeType(descriptor, "resources", node -> this.makeResourceUrlWithMimeTypeFromObjectNode(moduleUrl, node));
}
private URL makeResourceUrlFromField(URL moduleUrl, JsonNode descriptor, String name) {
JsonNode node = descriptor.get(name);
if(node==null || !node.isTextual())
return null;
else
return makeResourceUrlFromString(moduleUrl, node.asText());
}
private URL makeResourceUrlFromString(URL moduleUrl, String value) {
try {
if(value.startsWith("http"))
return new URL(value);
else
return new URL(moduleUrl, value);
} catch(MalformedURLException e) {
throw new RuntimeException(e);
}
}
private List makeResourceUrlsWithMimeType(JsonNode descriptor, String name, Function supplier) {
JsonNode node = descriptor.get(name);
if(node==null || !node.isArray())
return null;
return StreamSupport.stream(((ArrayNode)node).spliterator(), false)
.map(supplier)
.collect(Collectors.toList());
}
private URLWithMimeType makeResourceUrlWithMimeTypeFromTextualNode(URL moduleUrl, JsonNode node, String mimeType) {
if(node==null || !node.isTextual())
return null;
else {
URL url = makeResourceUrlFromString(moduleUrl, node.asText());
return new URLWithMimeType(url, mimeType);
}
}
private URLWithMimeType makeResourceUrlWithMimeTypeFromObjectNode(URL moduleUrl, JsonNode node) {
if(node!=null && node.isObject()) {
JsonNode mimeType = node.get("mimeType");
if(mimeType!=null && mimeType.isTextual()) {
URL url = makeResourceUrlFromField(moduleUrl, node, "url");
return new URLWithMimeType(url, mimeType.asText());
}
}
return null;
}
private void populateModule(Module module, JsonNode descriptor) throws Exception {
ModulePopulator populator = ModulePopulator.forType(module);
populator.populate(module, descriptor);
}
private Module newModule(JsonNode descriptor) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
String typeName = descriptor.get("type").asText();
ModuleType type = ModuleType.valueOf(typeName);
return type.getModuleClass().getDeclaredConstructor().newInstance();
}
private JsonNode readDescriptor(URL path) throws JsonProcessingException, IOException {
URL json = new URL(path, "module.json");
try(InputStream input = json.openStream()) {
return new ObjectMapper().readTree(input);
}
}
public boolean importModule(ICodeStore codeStore) throws Exception {
Module existing = codeStore.fetchVersionedModule(module.getType(), module.getName(), module.getVersion());
if(existing!=null)
return false;
createModule(codeStore);
List toMigrate = fetchModulesToMigrate(codeStore);
return migrateModules(codeStore, toMigrate);
}
private List fetchModulesToMigrate(ICodeStore codeStore) {
if(migrateFrom==null)
return null;
else
return StreamSupport.stream(codeStore.fetchAllModules().spliterator(), false)
.filter(m->m.getName().equals(module.getName()))
.filter(m->m.getVersion().asInt() >= migrateFrom.asInt())
.filter(m->m.getVersion().asInt() < module.getVersion().asInt())
.collect(Collectors.toList());
}
private boolean migrateModules(ICodeStore codeStore, List toMigrate) throws Exception {
if(toMigrate!=null) for(Module existing : toMigrate) {
updateDependencies(codeStore, existing.getVersion());
codeStore.dropModule(existing);
}
return true;
}
private void updateDependencies(ICodeStore codeStore, PromptoVersion minVersion) {
StreamSupport.stream(codeStore.fetchAllModules().spliterator(), false)
.filter(m->m.hasDependency(module.getName()))
.forEach(m->{
Dependency d = m.getDependency(module.getName());
if(d.getVersion().asInt() >= minVersion.asInt() && d.getVersion().asInt()"Importing module: " + module.getName() + " - " + module.getVersion());
if(imageResource!=null)
module.setImage(ImageValue.fromURL(imageResource).getStorableData());
codeStore.storeModule(module);
if(codeResource!=null)
storeAssociatedCode(codeStore);
if(module instanceof WebLibrary) {
if(stubResource!=null && isLocalResource(stubResource))
storeTextResource(codeStore, stubResource, "text/javascript");
if(javaScripts!=null)
javaScripts.forEach(res -> storeTextResource(codeStore, res));
if(styleSheets!=null)
styleSheets.forEach(res -> storeTextResource(codeStore, res));
if(resources!=null)
resources.forEach(res -> storeTextResource(codeStore, res));
}
}
private void storeAssociatedCode(ICodeStore codeStore) throws Exception {
ImmutableCodeStore rcs = new ImmutableCodeStore(null, module.getType(), codeResource, module.getVersion());
codeStore.storeDeclarations(rcs.getDeclarations(), rcs.getModuleDialect(), module.getDbId());
}
private void storeTextResource(ICodeStore codeStore, URLWithMimeType res) {
try {
if(isLocalResource(res.getUrl()))
storeTextResource(codeStore, res.getUrl(), res.getMimeType());
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private boolean isLocalResource(URL resource) throws URISyntaxException {
if("file".equals(resource.getProtocol()))
return Paths.get(resource.toURI()).toFile().exists();
else
return "jar".equals(resource.getProtocol());
}
private void storeTextResource(ICodeStore codeStore, URL resourceUrl, String mimeType) throws IOException {
String fileName = URLUtils.extractFileName(resourceUrl);
String fullName = module.getName().toLowerCase().replaceAll(" ", "-") + "/" + fileName;
TextResource resource = new TextResource();
resource.setMimeType(mimeType);
resource.setName(fullName);
resource.setLastModified(OffsetDateTime.now());
resource.setBody(StreamUtils.readString(resourceUrl));
codeStore.storeResource(resource, module.getDbId());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy