
prompto.transpiler.HtmlGenerator Maven / Gradle / Ivy
package prompto.transpiler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.security.InvalidParameterException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import prompto.code.ICodeStore;
import prompto.code.ModuleType;
import prompto.code.WebLibrary;
import prompto.declaration.CategoryDeclaration;
import prompto.declaration.IWidgetDeclaration;
import prompto.error.SyntaxError;
import prompto.grammar.Identifier;
import prompto.intrinsic.PromptoVersion;
import prompto.runtime.ApplicationContext;
import prompto.runtime.Context;
import prompto.store.DataStore;
import prompto.utils.HtmlUtils;
import prompto.utils.Logger;
import prompto.utils.YamlUtils;
public class HtmlGenerator {
static final Logger logger = new Logger();
String userAgent;
Map pageConfig;
String htmlEngine = null;
Set headerEntries = new HashSet<>();
public HtmlGenerator(String userAgent, Map pageConfig) {
this.userAgent = userAgent;
this.pageConfig = pageConfig;
}
public void generate(Context context, File htmlFile) throws IOException {
try(OutputStream output = new FileOutputStream(htmlFile) ) {
try(Writer writer = new OutputStreamWriter(output)) {
try(PrintWriter printer = new PrintWriter(writer)) {
generate(context, printer);
}
}
}
}
private void generate(Context context, PrintWriter printer) throws IOException {
generateProlog(printer);
Consumer bodyWriter = generateHeader(context, printer);
bodyWriter.accept(printer);
generateEpilog(printer);
}
private void generatePageRenderScript(PrintWriter printer, String widgetName) {
printer.println("");
}
private void generateProlog(PrintWriter printer) {
printer.println("");
printer.println("");
}
private Consumer generateHeader(Context context, PrintWriter printer) throws IOException {
printer.println("");
generateMetas(printer);
generateManifest(printer);
generateTitle(printer);
generateIcon(printer);
generateName(printer);
generatePromptoScripts(printer);
try {
generateLibraries(printer);
Consumer bodyWriter = generatePageWidgetScript(context, printer);
printer.println("");
return bodyWriter;
} catch(Exception e) {
return p->generateException(p, e);
}
}
private void generateManifest(PrintWriter printer) {
Map config = getHeaderConfig();
Object value = config.get("manifest");
if(value==null)
return;
else if(value instanceof String) {
String manifest = "";
writeHeaderEntry(printer, manifest);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
}
@SuppressWarnings("unchecked")
private void generateMetas(PrintWriter printer) {
writeHeaderEntry(printer, "");
Map config = getHeaderConfig();
Object value = config.get("metas");
if(value==null)
return;
else if(value instanceof Collection) {
((Collection)value).forEach(item->{
if(item instanceof String)
writeHeaderEntry(printer, item);
else
logger.warn(()->"Expected a String, got " + value.getClass().getName());
});
} else
logger.warn(()->"Expected a Collection, got " + value.getClass().getName());
}
private void writeHeaderEntry(PrintWriter printer, String entry) {
if(headerEntries.add(entry))
printer.println(entry);
else
logger.warn(()->"Duplicate header entry: " + entry);
}
private Consumer generatePageWidgetScript(Context context, PrintWriter printer) {
try {
String widgetName = getWidgetName();
generatePageWidgetScript(context, printer, widgetName);
return this::generateBody;
} catch(SyntaxError e) {
logger.error(()->"While generating page", e);
return p->generateSyntaxError(p, e);
} catch(Exception e) {
return p->generateException(p, e);
}
}
private void generateException(PrintWriter printer, Exception e) {
printer.println("");
e.printStackTrace(printer);
printer.println("");
}
private void generateSyntaxError(PrintWriter printer, SyntaxError e) {
printer.println("");
printer.println("Syntax error '" + HtmlUtils.encodeHtmlEntities(e.getMessage()) + "'");
printer.println("");
}
private String getWidgetName() {
Map body = getBodyConfig();
if(body==null)
throw new SyntaxError("Missing 'body' section in page descriptor");
Object value = body.get("widget");
if(value instanceof String)
return (String)value;
if(value==null)
throw new SyntaxError("Missing 'widget' entry in 'body' section of page descriptor");
else
throw new SyntaxError("Expected a String for 'widget', got " + value.getClass().getName());
}
private void generatePageWidgetScript(Context context, PrintWriter printer, String widgetName) {
IWidgetDeclaration widget = fetchWidgetDeclaration(context, widgetName);
if(widget==null)
throw new SyntaxError("No such widget '" + widgetName + "'");
generatePageWidgetScript(printer, widget);
generatePageRenderScript(printer, widgetName);
}
private IWidgetDeclaration fetchWidgetDeclaration(Context context, String widgetName) {
CategoryDeclaration decl = context.getRegisteredDeclaration(CategoryDeclaration.class, new Identifier(widgetName));
if(decl!=null && decl.isAWidget(context))
return ((CategoryDeclaration)decl).asWidget();
else
return null;
}
private void generatePageWidgetScript(PrintWriter printer, IWidgetDeclaration declaration) {
IJSEngine engine = IJSEngine.forUserAgent(userAgent);
Context context = ApplicationContext.get().newLocalContext();
Transpiler transpiler = new Transpiler(engine, context);
declaration.declare(transpiler);
if(transpiler.requires("DataStore")) {
transpiler.require("Remote");
transpiler.require("RemoteRunner");
transpiler.require("RemoteStore");
if(DataStore.getInstance().getNativeDbIdClass()==UUID.class)
transpiler.require("UUID");
}
printer.println("");
}
}
private void generatePromptoScripts(PrintWriter printer) {
writeHeaderEntry(printer, "");
writeHeaderEntry(printer, "");
writeHeaderEntry(printer, "");
}
private void generateLibraries(PrintWriter printer) throws Exception {
Map config = getHeaderConfig();
if(config==null)
return;
generateWebLibraries(printer, config);
generateWidgetLibraries(printer, config);
generateHtmlEngine(printer, config);
generateUiFramework(printer, config);
generateStyleSheets(printer, config);
generateJavaScripts(printer, config);
}
@SuppressWarnings("unchecked")
private void generateWebLibraries(PrintWriter printer, Map config) throws Exception {
Object value = config.get("webLibraries");
if(value==null)
return;
else if(value instanceof Collection) {
for(Object item : (Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy