001package com.randomnoun.common.jessop; 002 003/* (c) 2016 randomnoun. All Rights Reserved. This work is licensed under a 004 * BSD Simplified License. ( http://www.randomnoun.com/bsd-simplified.html ) 005 */ 006 007import java.io.PrintWriter; 008 009import javax.script.ScriptException; 010 011/** Each target language we intend to support within jessop must have an implementation of this interface. 012 * Developers wishing to implement this interface should use the {@link AbstractJessopScriptBuilder} abstract class. 013 * 014 * <p>Implementations of this class should return the language it supports (and the default script engine name) via the 015 * {@link #getLanguage()} and {@link #getDefaultScriptEngineName()} methods. 016 * 017 * <p>These values will be used to select the correct JessopScriptBuilder identified in the 018 * <code><%@ jessop language="xxx"%></code> 019 * declaration in the jessop source file. 020 * 021 * <p>When this class is instantiated, the caller will invoke {@link #setPrintWriter(PrintWriter)} and 022 * {@link #setTokeniserAndDeclarations(Tokeniser, JessopDeclarations)}. 023 * 024 * <p>As the Tokeniser parses the jessop source file, it will invoke emit() methods on this class. 025 * As these methods are called, this class should generate code in the target language via the printWriter. 026 * 027 * <p>Care should be taken to ensure that code in the target language script is on the same line number 028 * as the corresponding code on the input script, to make error messages more developer-friendly. 029 * 030 * @author knoxg 031 */ 032public interface JessopScriptBuilder { 033 // lines are source line numbers; try to keep these intact in the generated script 034 035 /** Returns the name of the language that this scriptBuilder can parse; e.g. "javascript" or "python2". 036 * 037 * <p>This is used to register this JessopScriptBuilder in the registry and is used to lookup the JessopScriptBuilder 038 * from the language defined in the jessop script declaration. 039 * 040 * @return the name of the language that this scriptBuilder can parse; e.g. "javascript" or "python2". 041 */ 042 String getLanguage(); 043 044 /** Returns the name of the script engine that is used to evaluate this script; e.g. "rhino" or "jython" 045 * 046 * @return the name of the script engine that is used to evaluate this script; e.g. "rhino" or "jython" 047 */ 048 String getDefaultScriptEngineName(); 049 050 /** Returns the name of the default exceptionConverter class that should be used for the default script engine, 051 * or null if no converter is required. 052 * 053 * <p>Changing the engine in the jessop declaration will reset the the converter to null. 054 * 055 * @return the name of the default exceptionConverter class that should be used for the default script engine 056 */ 057 String getDefaultExceptionConverterClassName(); 058 059 /** Returns the name of the default bindingsConverter class that should be used for the default script engine, 060 * or null if no converter is required. 061 * 062 * <p>Changing the engine in the jessop declaration will reset the the converter to null. 063 * 064 * @return the name of the default bindingsConverter class that should be used for the default script engine 065 */ 066 String getDefaultBindingsConverterClassName(); 067 068 069 /** Sets the printWriter that this class will write to during emit() methods 070 * 071 * @param pw the printWriter that this class will write to during emit() methods 072 */ 073 void setPrintWriter(PrintWriter pw); 074 075 /** Sets the tokeniser and declaration that are in effect at the start of parsing. This allows this 076 * ScriptBuilder to switch ScriptBuilders. 077 * 078 * @param t tokeniser that is processing the jessop source 079 * @param declarations jessop declarations that are in effect 080 */ 081 void setTokeniserAndDeclarations(Tokeniser t, JessopDeclarations declarations); 082 083 /** Called by the tokeniser and requests that this JessopScriptBuilder generate code to generate some text output. 084 * 085 * <p>This method should escape the output and generate code that outputs this text in the implementation language. 086 * 087 * @param line jessop source line number that begins this text output 088 * @param s the text to output; may include newlines. 089 */ 090 void emitText(int line, String s); 091 092 /** Called by the tokeniser and requests that this JessopScriptBuilder generate code to generate some evaluated output. 093 * i.e. process a <code><%= ... %></code> expression. 094 * 095 * <p>This method should generate the code to evaluate and output the contents of the <code><%= ... %></code> expression. 096 * 097 * <p>This method should attempt to preserve line numbers between the jessop source file and the generated code file. 098 * 099 * @param line jessop source line number that begins this text output. 100 * @param s the contents of the <code><%= ... %></code> expression. 101 */ 102 void emitExpression(int line, String s); // <%= ... %> 103 104 105 /** Called by the tokeniser and requests that this JessopScriptBuilder copy the included code into the generated script. 106 * i.e. process a <code><% ... %></code> scriptlet. (The 'scriptlet' term is the term used in the JSP specification) 107 * 108 * <p>This method should generate the same code that is contained within the <code><% ... %></code> scriptlet. 109 * 110 * <p>This method should attempt to preserve line numbers between the jessop source file and the generated code file. 111 * 112 * <p>This scriptlet may not be syntactically correct by itself and may require further scriptlets to function, e.g. 113 * <pre> 114 * <% if (a > b) { %> 115 * something 116 * <% } %> 117 * </pre> 118 * 119 * @param line jessop source line number that begins this scriptlet. 120 * @param s the contents of the <code><%= ... %></code> expression. 121 */ 122 void emitScriptlet(int line, String s); 123 124 /** Called by the tokeniser and requests that this JessopScriptBuilder process a <code><%@ ... %></code> directive. 125 * 126 * <p>The exact semantics of these declarations can be defined per-language, but 'jessop' declarations 127 * should be processed by the AbstractJessopScriptBuilder, i.e. declarations that are in the form 128 * <code><%@ jessop language="xxx" %></code> 129 * 130 * <p>Ideally, there's only one declaration, at the top of the source script. 131 * 132 * @param line jessop source line number that begins this directive 133 * @param s the contents of the <code><%@ ... %></code> directive 134 * @throws ScriptException 135 */ 136 void emitDeclaration(int line, String s) throws ScriptException; 137 138 /** Returns the value of any jessop declarations that are in effect. 139 * 140 * <p>Used to maintain declarations when switching JessopScriptBuilders, and to retrieve declarations after the script is built. 141 */ 142 JessopDeclarations getDeclarations(); 143 144}