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.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);
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);
}
}
@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)value) {
generateWebLibrary(printer, item);
}
} else
logger.warn(()->"Expected a Collection, got " + value.getClass().getName());
}
private void generateWebLibrary(PrintWriter printer, Object entry) throws Exception {
if(entry instanceof String)
generateWebLibrary(printer, (String)entry, PromptoVersion.LATEST);
else if(entry instanceof Map) {
Object name = ((Map,?>)entry).get("name");
if(name instanceof String) {
Object value = ((Map,?>)entry).get("version");
if(value instanceof String) try {
PromptoVersion version = PromptoVersion.parse((String)value);
generateWebLibrary(printer, (String)name, version);
} catch(InvalidParameterException e) {
throw new SyntaxError("Invalid 'version' in webLibraries entry: " + entry.toString());
} else
throw new SyntaxError("Missing 'version' in webLibraries entry: " + entry.toString());
} else
throw new SyntaxError("Missing 'name' in webLibraries entry: " + entry.toString());
} else
throw new SyntaxError("Could not understand webLibraries entry: " + entry.toString());
}
private void generateWebLibrary(PrintWriter printer, String name, PromptoVersion version) throws Exception {
WebLibrary webLibrary = ICodeStore.getInstance().fetchVersionedModule(ModuleType.WEBLIBRARY, name, version);
if(webLibrary == null)
throw new SyntaxError("Could not find webLibrary: " + name + ", version: " + version.toString());
Map config = new HashMap<>();
config.put("htmlEngine", webLibrary.getHtmlEngine());
config.put("javaScripts", webLibrary.getJavaScripts());
config.put("styleSheets", webLibrary.getStyleSheets());
generateHtmlEngine(printer, config);
generateStyleSheets(printer, config);
generateJavaScripts(printer, config);
}
@SuppressWarnings("unchecked")
private void generateStyleSheets(PrintWriter printer, Map config) {
Object value = config.get("styleSheets");
if(value==null)
return;
else if(value instanceof Collection) {
((Collection)value).forEach(item->{
if(item instanceof String) {
if(!(item.startsWith("http")|| item.startsWith("/")))
item = "/" + item;
String styleSheet = " ";
writeHeaderEntry(printer, styleSheet);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
});
} else
logger.warn(()->"Expected a Collection, got " + value.getClass().getName());
}
@SuppressWarnings("unchecked")
private void generateJavaScripts(PrintWriter printer, Map config) {
Object value = config.get("javaScripts");
if(value==null)
return;
else if(value instanceof Collection) {
((Collection)value).forEach(item->{
if(item instanceof String) {
if(!(item.startsWith("http")|| item.startsWith("/")))
item = "/" + item;
String javaScript = "";
writeHeaderEntry(printer, javaScript);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
});
} else
logger.warn(()->"Expected a Collection, got " + value.getClass().getName());
}
private void generateUiFramework(PrintWriter printer, Map config) throws IOException {
Object value = config.get("uiFramework");
if(value==null)
return;
else if(value instanceof String) {
config = YamlUtils.readResource("uiFrameworks/" + value + ".yaml");
generateStyleSheets(printer, config);
generateJavaScripts(printer, config);
} else
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
private void generateHtmlEngine(PrintWriter printer, Map config) throws Exception {
Object value = config.get("htmlEngine");
if(value==null)
return;
else if(value instanceof String) {
if(value.equals(htmlEngine))
return; // already generated
else if(htmlEngine!=null)
throw new SyntaxError("HTML engine: " + value + " conflicts with: " + htmlEngine);
else {
htmlEngine = (String)value;
config = YamlUtils.readResource("htmlEngines/" + value + ".yaml");
generateStyleSheets(printer, config);
generateJavaScripts(printer, config);
}
} else
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
private void generateWidgetLibraries(PrintWriter printer, Map config) throws Exception {
Object values = config.get("widgetLibraries");
if(values==null)
return;
else if(values instanceof Collection) {
for(Object value : (Collection>)values)
generateWidgetLibrary(value, printer, config);
} else
logger.warn(()->"Expected a List, got " + values.getClass().getName());
}
private void generateWidgetLibrary(Object value, PrintWriter printer, Map config) throws Exception {
if(value instanceof String) {
config = YamlUtils.readResource("widgetLibraries/" + value + ".yaml");
generateHtmlEngine(printer, config);
generateUiFramework(printer, config);
generateStyleSheets(printer, config);
generateJavaScripts(printer, config);
}
else
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
private void generateIcon(PrintWriter printer) {
Map header = getHeaderConfig();
if(header==null)
return;
Object value = header.get("icon");
if(value==null)
return;
if(value instanceof String) {
String icon = " ";
writeHeaderEntry(printer, icon);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
}
private void generateTitle(PrintWriter printer) {
Map header = getHeaderConfig();
if(header==null)
return;
Object value = header.get("title");
if(value==null)
return;
else if(value instanceof String) {
String title = "" + value + " ";
writeHeaderEntry(printer, title);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
}
private void generateName(PrintWriter printer) {
Map header = getHeaderConfig();
if(header==null)
return;
Object value = header.get("name");
if(value==null)
return;
else if(value instanceof String) {
String name = "";
writeHeaderEntry(printer, name);
} else {
logger.warn(()->"Expected a String, got " + value.getClass().getName());
}
}
private Map getHeaderConfig() {
return getConfig(pageConfig, "header");
}
private Map getBodyConfig() {
return getConfig(pageConfig, "body");
}
@SuppressWarnings("unchecked")
private Map getConfig(Map source, String key) {
Object value = source.get(key);
if(value==null)
return null;
else if(value instanceof Map)
return (Map)value;
else {
logger.warn(()->"Expected a Map, got " + value.getClass().getName());
return null;
}
}
private void generateBody(PrintWriter printer) {
printer.println("");
printer.println("
");
printer.println("
");
printer.println("
");
printer.println("");
}
private void generateEpilog(PrintWriter printer) {
printer.println("");
}
}