001package com.randomnoun.common.jessop.lang;
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 org.apache.log4j.Logger;
008
009import com.randomnoun.common.jessop.AbstractJessopScriptBuilder;
010import com.randomnoun.common.jessop.JessopScriptBuilder;
011
012// exactly the same as the JavascriptJessopScriptBuilder
013// string coercion is a bit different
014public class JavaJessopScriptBuilder extends AbstractJessopScriptBuilder implements JessopScriptBuilder {
015
016        Logger logger = Logger.getLogger(JavaJessopScriptBuilder.class);
017        int outputLine = 1;        // current line number in the target script;
018        int lastScriptletLine = 1; // the last line number of the last scriptlet (used for suppressEol)
019
020        public JavaJessopScriptBuilder() { 
021        }
022        private void skipToLine(int line) {
023                // skipToLines are only used in the target script, so aren't affected by suppressEol
024                while (outputLine < line) { print("\n"); }
025        }
026        private void print(String s) {
027                // logger.info("** PRINT " + s);
028                pw.print(s);
029                for (int i=0; i<s.length(); i++) {
030                        if (s.charAt(i)=='\n') { outputLine++; } 
031                }
032        }
033        private static String escapeJava(String string) {
034        StringBuilder sb = new StringBuilder(string.length());
035                for (int i = 0; i<string.length(); i++) {
036                        char ch = string.charAt(i);
037                        if (ch=='\n') {
038                           sb.append("\\n");    
039                        } else if (ch=='\\' || ch=='"' || ch=='\'' || ch<32 || ch>126) {
040                                String hex = Integer.toString(ch, 16);
041                                sb.append("\\u" + "0000".substring(0, 4-hex.length()) + hex);
042                        } else {
043                                sb.append(ch);
044                        }
045                }
046        return sb.toString();
047    }
048
049        @Override
050        public void emitText(int line, String s) {
051                skipToLine(line);
052                s = suppressEol(s, declarations.isSuppressEol() && lastScriptletLine == line);
053                print("out.write(\"" + escapeJava(s) + "\");");
054                lastScriptletLine = 0; // don't suppress eols on this line
055        }
056        @Override
057        public void emitExpression(int line, String s) {
058                skipToLine(line);
059                print("out.write(\"\" + (" + s + "));"); // coerce to String
060                lastScriptletLine = 0; // don't suppress eols on this line
061        }
062        
063        @Override
064        public void emitScriptlet(int line, String s) {
065                skipToLine(line);
066                print(s);
067                lastScriptletLine = line;
068                for (int i=0; i<s.length(); i++) { if (s.charAt(i)=='\n') { lastScriptletLine++; } }
069        }
070        @Override
071        public String getLanguage() {
072                return "java";
073        }
074        @Override
075        public String getDefaultScriptEngineName() {
076                return "beanshell";
077        }
078        @Override
079        public String getDefaultExceptionConverterClassName() {
080                return "com.randomnoun.common.jessop.engine.BeanshellExceptionConverter";
081        }
082
083}